Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Циклический вызов агента повторяется до тех пор, пока не будет выполнено условие завершения. Используйте это для итеративной доработки, выполнения задач из списка дел, ожидания завершения фоновых задач или оценки того, соответствует ли ответ явно заданным критериям.
Всегда ограничивайте автономные циклы. Условие завершения может завершиться ошибкой, модель может застопориться, и вычислитель может быть вероятностным.
Это важно
Цикл агента является экспериментальным.
Настройка циклов вручную
Используйте API прямой композиции, если вам нужно циклическое выполнение без других параметров Harness Agent по умолчанию.
Импортируйте типы циклов и оберните любой AIAgent в LoopAgent. Максимальное значение по умолчанию — 10 вызовов агента:
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
AIAgent baseAgent = chatClient.AsAIAgent();
AIAgent agent = new LoopAgent(
baseAgent,
new CompletionMarkerLoopEvaluator("DONE"),
new LoopAgentOptions { MaxIterations = 5 });
Импортируйте AgentLoopMiddleware и добавьте его в обычный Agent. Максимальное значение по умолчанию — 10 запусков агента:
from agent_framework import Agent, AgentLoopMiddleware
def needs_more_work(*, last_result, **kwargs):
return "DONE" not in last_result.text
agent = Agent(
client=client,
middleware=[
AgentLoopMiddleware(
needs_more_work,
max_iterations=5,
)
],
)
Предикат может быть синхронным или асинхронным. Вернуться True, чтобы продолжить, False — чтобы остановить, или (continue, feedback) — чтобы передать обратную связь для следующей итерации.
Go предоставляет ограниченный повторный вызов через agent/harness/loop. Зарегистрируйтесь loop.New(loop.Config{...}) в agent.Config.Middlewares. ПО промежуточного слоя запускает агент, оценивает его ответ и при необходимости передает обратную связь в следующую итерацию.
В следующем примере Foundry используется маркер завершения. Для этого требуются FOUNDRY_PROJECT_ENDPOINT, FOUNDRY_MODEL, и учетные данные Azure.
// Copyright (c) Microsoft. All rights reserved.
package main
import (
"context"
"github.com/microsoft/agent-framework-go/agent"
"github.com/microsoft/agent-framework-go/agent/harness/loop"
"github.com/microsoft/agent-framework-go/examples/internal/demo"
"github.com/microsoft/agent-framework-go/provider/foundryprovider"
)
var logger = demo.NewLogger(
"Loop Harness",
"This sample shows how the loop harness keeps re-invoking an agent until it "+
"signals completion with a marker, so the agent can work across several turns "+
"on its own before returning.",
"Model", demo.FoundryModel,
)
// completionMarker is the token the agent is asked to emit once the task is
// fully done; the loop stops as soon as it appears in a response.
const completionMarker = "TASK COMPLETE"
func main() {
token := demo.FoundryTokenCredential()
// Wrap the agent with the loop harness: after each iteration the
// completion-marker evaluator decides whether to run the agent again.
a := foundryprovider.NewAgent(
demo.FoundryProjectEndpoint,
token,
foundryprovider.ModelDeployment(demo.FoundryModel),
foundryprovider.AgentConfig{
Instructions: "You are a diligent assistant. Work on the request step by step across " +
"multiple turns. End your final message with the marker '" + completionMarker +
"' once, and only once, the request is fully complete.",
Config: agent.Config{
Name: "Worker",
Middlewares: []agent.Middleware{
// The loop re-invokes the agent (and everything below it,
// including the logger) until an evaluator stops the loop.
loop.New(loop.Config{
Evaluators: []loop.Evaluator{
loop.NewCompletionMarkerEvaluator(loop.CompletionMarkerConfig{Marker: completionMarker}),
},
}),
logger, // for logging each agent iteration
},
},
},
)
ctx := context.Background()
resp, err := a.RunText(ctx, "Draft a short checklist for planning a small birthday party, "+
"then review it once for anything missing, and finish.").Collect()
demo.Response(resp, err)
}
MaxIterations является необязательным *int и по умолчанию имеет значение 10. Задайте явное ограничение для задачи. При использовании нескольких оценщиков первый оценщик, запрашивающий другую итерацию, предоставляет свой отзыв; цикл останавливается только в том случае, если все оценщики остановятся или будет достигнут предел числа итераций.
Пример без учетных данных см. в примере цикла со скриптом. Он демонстрирует завершение маркера, пользовательский оценщик и ограничение безопасности итерации.
Выбор условия завершения
LoopAgent принимает один вычислитель или упорядоченную коллекцию:
| Эвалуатор | Продолжается, пока |
|---|---|
CompletionMarkerLoopEvaluator |
Последний ответ не содержит заданного маркера. |
TodoCompletionLoopEvaluator |
Решённый TodoProvider по-прежнему содержит незавершённые элементы, возможно в выбранных режимах агента. |
BackgroundTaskCompletionLoopEvaluator |
У решенного BackgroundAgentsProvider по-прежнему есть выполняющиеся задачи. |
AIJudgeLoopEvaluator |
Отдельный клиент судьи говорит, что исходный запрос не полностью ответен. |
DelegateLoopEvaluator |
Ваша функция обратного вызова возвращает LoopEvaluation.Continue(...). |
Если настроено несколько оценщиков, они запускаются по порядку. Первый вычислитель, запрашивающий другую итерацию, предоставляет свои отзывы; Цикл останавливается, только если все вычислители отказались от продолжения.
Использование судьи ИИ
Судья получает исходный запрос и последний ответ агента. Если он находит разрыв, его анализ становится обратной связью для следующей итерации:
var evaluator = new AIJudgeLoopEvaluator(
judgeClient,
new AIJudgeLoopEvaluatorOptions
{
Criteria =
[
"Answer every part of the request.",
"Support conclusions with evidence.",
],
});
AIAgent loopAgent = new LoopAgent(
agent,
evaluator,
new LoopAgentOptions { MaxIterations = 4 });
Используйте только ту конечную точку оценщика, которой вы доверяете исходный запрос и сгенерированный ответ.
Контекст управления и выходные данные
По умолчанию LoopAgent использует один и тот же сеанс и отправляет последний отзыв победившего оценщика в качестве следующего ввода.
FreshContextPerIteration = true вместо этого на каждом проходе заново формирует состояние на основе исходного запроса и агрегированного журнала обратной связи, а затем сбрасывает или восстанавливает сеанс.
По умолчанию запросы без потоковой передачи возвращают единый транскрипт. Задайте NonStreamingReturnsLastResponseOnly = true для возврата только окончательного ответа. Потоковая выдача всегда возвращает результат каждой итерации и все видимые сообщения обратной связи, отправляемые от имени.
Предикат получает аргументы ключевых слов, включая iteration, , last_resultmessages, original_messages, , sessionagentprogressи .feedback Вспомогательные функции todos_remaining() и background_tasks_running() предоставляют встроенные условия todo и для фоновых задач. Сопоставьте их с todos_remaining_message или background_tasks_running_message, чтобы создать целевой следующий входной запрос.
Использование судьи ИИ
AgentLoopMiddleware.with_judge выстраивает цикл, управляемый модулем оценки. Циклы Judge по умолчанию составляют пять итераций:
from agent_framework import Agent, AgentLoopMiddleware
loop = AgentLoopMiddleware.with_judge(
judge_client,
criteria=[
"Answer every part of the request.",
"Support conclusions with evidence.",
],
max_iterations=4,
)
agent = Agent(
client=client,
middleware=[loop],
)
Рассуждения судьи возвращаются агенту, когда требуется больше работы. Используйте только ту конечную точку оценщика, которой вы доверяете исходный запрос и сгенерированный ответ.
Управление контекстом, ходом выполнения и выходными данными
Для расширенных циклов создайте AgentLoopMiddleware напрямую:
-
record_feedbackсоздает краткую запись хода выполнения после каждой итерации работы. -
progressпредоставляет накопленные записи для обратных вызовов. -
inject_progress=Trueдобавляет сведения о ходе выполнения во входные данные следующей итерации. -
fresh_context=Trueперезапускается на основе исходной задачи и журнала прогресса и восстанавливает подключённый сеанс до состояния снимка перед циклом. -
return_final_only=Trueвозвращает только последний ответ для запусков без потоковой передачи.
Передавайте max_iterations=None только в том случае, если гарантировано, что предикат завершения завершит работу.
Используйте loop.NewCompletionMarkerEvaluator, чтобы остановиться, когда последний ответ содержит настроенный маркер. Для завершения, специфичного для приложения, реализуйте loop.Evaluator или используйте loop.EvaluatorFunc, возвращая loop.Stop(), loop.Continue(feedback) или loop.ContinueWithMessages(messages).
FreshContextPerIteration перезапускается на основе исходных входных данных и накопленных отзывов.
NonStreamingReturnsLastResponseOnly ограничивает непотоковый результат окончательной итерацией.
Go не включает встроенный оценщик ИИ-судья, показанный в примерах C#. Укажите собственного оценщика, если завершение требует другой модели или внешней проверки.
Используйте циклы с Harness Agent
Используйте настройку Harness Agent, если вам также нужны его предварительно настроенные история, планирование, память, согласование и конвейер наблюдаемости.
Задайте HarnessAgentOptions.LoopEvaluators. Тестовый каркас использует LoopAgent в качестве внешнего декоратора агента:
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
var options = new HarnessAgentOptions
{
LoopEvaluators =
[
new CompletionMarkerLoopEvaluator("DONE"),
],
LoopAgentOptions = new LoopAgentOptions
{
MaxIterations = 5,
},
};
HarnessAgent agent = chatClient.AsHarnessAgent(options);
// Equivalent construction: new HarnessAgent(chatClient, options)
AgentSession session = await agent.CreateSessionAsync();
Пустая или nullLoopEvaluators коллекция делает обвязку одноразовой.
Утверждение и поведение сеанса
LoopAgent прекращает работу до проверки условия завершения, если итерация возвращает ожидающий запрос на одобрение инструмента. Он возвращает запрос вызывающей стороне вместо того, чтобы скрывать его за другой самостоятельной итерацией. После того как инициатор предоставляет ответ с подтверждением через обычный процесс подтверждения инструмента, агент может продолжить.
LoopAgent сам по себе не добавляет обработку подтверждений. Агент Harness применяет цикл вне ToolApprovalAgent, позволяя запросам на утверждение, ожидающим обработки, выйти из цикла.
Повторно используйте то же самое AgentSession в вызовах, чтобы продолжить беседу. Цикловые итерации по умолчанию используют этот сеанс. С помощью FreshContextPerIteration = true, LoopAgent сбрасывает или восстанавливает состояние сеанса, переданное вызывающей стороной, если это поддерживается. Хранилище бесед, принадлежащих службе, может хранить журнал, если сериализованный сеанс содержит только идентификатор удаленного диалога.
Укажите значение от loop_should_continue до create_harness_agent; loop_max_iterations по умолчанию — 10:
from agent_framework import create_harness_agent
def needs_more_work(*, last_result, **kwargs):
return "DONE" not in last_result.text
agent = create_harness_agent(
client=client,
loop_should_continue=needs_more_work,
loop_max_iterations=5,
)
session = agent.create_session()
loop_next_message настраивает следующие входные данные. При отсутствии loop_should_continue фабрика не добавляет цикл и игнорирует остальные аргументы цикла.
Утверждение и поведение сеанса
AgentLoopMiddleware останавливается перед оценкой предиката продолжения, когда итерация возвращает ожидающий запрос на утверждение средства. Он возвращает запрос вызывающей стороне вместо того, чтобы скрывать его за другой самостоятельной итерацией. После того как инициатор предоставляет ответ с подтверждением через обычный процесс подтверждения инструмента, агент может продолжить.
AgentLoopMiddleware сам по себе не добавляет ToolApprovalMiddleware Агент Harness размещает цикл за пределами своего промежуточного слоя согласования, что позволяет ожидающим запросам на согласование выйти из цикла. Создайте и передавайте AgentSession при каждом запуске агента Harness, если включено автоматическое одобрение инструментов.
Повторно используйте то же самое AgentSession в вызовах, чтобы продолжить беседу. Цикловые итерации по умолчанию используют этот сеанс. С помощью fresh_context=True промежуточное ПО между итерациями восстанавливает подключённый сеанс до состояния, сохранённого в снимке до начала цикла. Хранилище бесед, принадлежащих службе, может хранить журнал, если сериализованный сеанс содержит только идентификатор удаленного диалога.
Помощник Go harness.AgentConfig не добавляет цикл по умолчанию. Включите agent.Config.Middlewares в loop.New(...) вызывающей стороны, чтобы обернуть настроенный агент ограниченным повторным вызовом.
Цикл завершается, когда в результате итерации появляются запросы на одобрение инструмента, ожидающие одобрения. Он не утверждает инструменты автоматически. Обработайте запросы на узле и верните соответствующие ответы с подтверждением через тот же сеанс, прежде чем продолжить.