エージェント ループは、完了条件が満たされるまでエージェントを再呼び出します。 反復的な改善、ToDo の完了、バックグラウンドタスクの完了待ち、または回答が明確な基準を満たしているかどうかの評価に利用できます。
自律ループは常に制限する。 完了条件が失敗し、モデルがストールし、エバリュエーターが確率論的になる可能性があります。
Important
エージェントのループ処理は実験的機能です。
ループを手動で設定する
他の Harness エージェントの既定値なしでループする場合は、ダイレクトコンポジション API を使用します。
ループの種類をインポートし、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 は、1 つのエバリュエーターまたは順序付けられたコレクションを受け取ります。
| エバリュエーター | 次の間、継続します |
|---|---|
CompletionMarkerLoopEvaluator |
最新の応答には、構成されたマーカーが含まれません。 |
TodoCompletionLoopEvaluator |
解決された TodoProvider には、オプションで選択したエージェント モードで不完全な項目が残っています。 |
BackgroundTaskCompletionLoopEvaluator |
解決された BackgroundAgentsProvider には、まだ実行中のタスクがあります。 |
AIJudgeLoopEvaluator |
別の判定クライアントから、元的要求が完全に処理されていないという報告があります。 |
DelegateLoopEvaluator |
コールバックは LoopEvaluation.Continue(...)を返します。 |
複数のエバリュエーターを構成すると、順番に実行されます。 別のイテレーションを要求する最初のエバリュエーターは、フィードバックを提供します。ループは、すべてのエバリュエーターが続行を拒否した場合にのみ停止します。
AI ジャッジを使用する
ジャッジは、元の要求と最新のエージェントの応答を受け取ります。 ギャップが見つかると、その分析は次のイテレーションのフィードバックになります。
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 は 1 つのセッションを再利用し、次の入力として、成功したエバリュエーターの最新のフィードバックを送信します。
FreshContextPerIteration = true 代わりに、元の要求から各パスと集計されたフィードバック ログを再構築し、セッションをリセットまたは復元します。
ストリーミング以外の実行では、既定で集計されたトランスクリプトが返されます。 最終的な応答のみを返すように NonStreamingReturnsLastResponseOnly = true を設定します。 ストリーミングでは、すべてのイテレーションと、表示可能な on-behalf-of フィードバック メッセージが常に送信されます。
述語は、 iteration、 last_result、 messages、 original_messages、 session、 agent、 progress、 feedbackなどのキーワード引数を受け取ります。 ヘルパー todos_remaining() と background_tasks_running() は、組み込みの todo とバックグラウンド タスクの条件を提供します。 それらを todos_remaining_message または background_tasks_running_message とペアリングして、ターゲットの次の入力を生成します。
AI ジャッジを使用する
AgentLoopMiddleware.with_judge は、ジャッジドリブン ループを構築します。 ジャッジ ループの既定値は 5 回です。
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# の例に示されている組み込みの AI ジャッジ エバリュエーターは含まれていません。 完了に別のモデルまたは外部チェックが必要な場合は、独自のエバリュエーターを用意してください。
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 エージェントは、承認ミドルウェアの外側にループを配置し、保留中の承認要求がループをエスケープできるようにします。 ツールの自動承認が有効になっている間、Harness エージェントを実行するたびに AgentSession を作成して渡します。
呼び出し間で同じ AgentSession を再利用して会話を続行します。 ループ イテレーションでは、既定でそのセッションが共有されます。
fresh_context=Trueを使用すると、ミドルウェアはアタッチされたセッションをイテレーション間のプリループ スナップショットに復元します。 サービス所有の会話ストレージは、シリアル化されたセッションにリモート会話識別子のみが含まれている場合に履歴を保持できます。
Go harness.AgentConfig ヘルパーは、既定ではループを追加しません。 呼び出し元のloop.New(...)にagent.Config.Middlewaresを含め、構成されたエージェントを境界付きの再呼び出しでラップします。
このループは、イテレーションによって保留中のツール承認要求が生成されたときに終了します。 ツールは自動的には承認されません。 ホスト内の要求を処理し、同じセッション経由で一致する承認応答を返してから続行します。