エージェント ハーネス

エージェント ハーネスは、言語モデルを実際に実行できるエージェントに変換するスキャフォールディングです。 モデル自体はテキストのみを生成できます。 ツールを呼び出し、複数ステップのタスクを実行し、実行したことを思い出し、ジョブが完了するまで作業を続けるためには、モデルにラップされたランタイムが必要です。そのランタイムはハーネスです。

ハーネスは、エージェントを駆動します。これは、モデルを呼び出し、モデルが要求するツールを実行するループを実行し、会話履歴とコンテキストを管理して、モデルがその制限内に留まるようにし、アクションが実行される前に承認ポリシーと安全ポリシーを適用し、タスクの完了に向けてエージェントを進行させます。 コーディングアシスタントや自律エージェントは、いずれも何らかのハーネスの上に成り立っています。つまり、ハーネスとはモデルを取り巻くエンジンのことです。

Agent Framework には既製のハーネスが用意されているため、このスキャフォールディングを自分で構築する必要はありません。 これは、特定の設計思想に基づいた、必要な機能をひととおり備えたエージェントです。チャット クライアントを、関数呼び出し、コンテキスト管理、厳選されたツールとプロバイダー群を含む完全なエージェント パイプラインでラップし、調査、コーディング、データ分析、一般的なタスク自動化など、長時間にわたる自律的な作業向けに調整されています。

引き続き独自のチャット クライアントを提供し、変更する部分のみを構成します。 それ以外には、無効にしたりカスタマイズしたりできる適切な既定値があります。

内部的には、Agent Framework のハーネスは、Agent Framework の複数の機能を追加した、チャット クライアントをベースにしたエージェント(Python では Agent、C# では ChatClientAgent)です。 これらの機能はすべて、Agent Framework のスタンドアロン機能としても使用できます。

Agent Framework ハーネスを構成するもの

Agent Framework ハーネスは、次の機能を 1 つのエージェントにバンドルします。 それぞれが既定で有効になっており (省略可能な場合を除く)、個別に無効にしたりカスタマイズしたりすることができます。

能力 Description
関数の呼び出し 構成可能な反復制限を持つ自動ツール呼び出しループ。
サービスごとの呼び出し履歴の永続化 チャット履歴は、個々のモデル呼び出しのたびに保持され、クラッシュの復旧と検査の途中実行が可能になります。
圧縮 コンテキスト ウィンドウの圧縮により、長いツール呼び出しループがコンテキスト ウィンドウからオーバーフローするのを防ぐ。 トークン予算 (またはカスタム戦略) が指定されている場合にアクティブです。
ToDo プロバイダー エージェントがマルチステップ プランの追跡に使用する永続的な todo リスト。
エージェント モード プロバイダー エージェントの動作を構造化する計画/実行/カスタム モードの追跡。
ファイル メモリ プロバイダー 複数のターンにわたって保持されるノートとアーティファクトのファイル ベースのセッション メモリ。
ファイル アクセス プロバイダー 作業ディレクトリをスコープとした読み取り/書き込みファイル ツール。
ツールの承認 「今後確認しない」承認ルールに加え、安全な無人実行のためのヒューリスティックによる自動承認。
OpenTelemetry 生成AIのセマンティック規約に準拠した組み込み型の可観測性。
Web 検索 既定で追加されたホスト型 Web 検索ツール。
スキル プロバイダー(省略可能) エージェント スキルを検出し、ファイル システムから段階的に読み込みます。
バックグラウンド エージェント(省略可能) 並列作業をバックグラウンド サブエージェントに委任します。
シェル環境(省略可能) シェル コマンドの実行と OS/シェル/作業ディレクトリプローブ。
ループ(任意) 完了条件が満たされるまでエージェントを再呼び出します。

ハーネス エージェントの作成

ハーネスは、HarnessAgent名前空間 (Microsoft.Agents.AI パッケージ) のMicrosoft.Agents.AI.Harness クラスとして公開されます。 最も簡単な方法は、IChatClient拡張メソッドを使用する任意のAsHarnessAgentから作成することです。

using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;

// chatClient is any IChatClient implementation (Foundry, Azure OpenAI, OpenAI, Anthropic, ...).
AIAgent agent = chatClient.AsHarnessAgent();

AgentResponse response = await agent.RunAsync("Plan a weekend trip to Seattle.");
Console.WriteLine(response.Text);

エージェントを直接構築することもできます。

AIAgent agent = new HarnessAgent(chatClient);

指示とツールを提供するための HarnessAgentOptions を提供します。 ハーネスレベルの指示 (HarnessAgentOptions.HarnessInstructions) は一般的な運用ガイドラインを示し、一方でタスク固有の指示は ChatOptions.Instructions に記載します。 HarnessAgentには既定のハーネス レベル命令 (HarnessAgent.DefaultInstructions) が付属していますが、HarnessAgentOptions.HarnessInstructionsを使用して独自の命令をオーバーライドできます。

AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
    Name = "research-agent",
    ChatOptions = new ChatOptions
    {
        Instructions = "You are a research assistant focused on academic sources.",
        Tools = [AIFunctionFactory.Create(GetStockPrice)],
    },
});

圧縮の有効化

圧縮により、長いツール呼び出しループでコンテキスト ウィンドウがオーバーフローするのを防ぐことができます。 推論サービスで保存されたチャット履歴を使用しない場合、既定の InMemoryChatHistoryProvider も同じ圧縮プロバイダーで提供されるため、セッションに格納されたチャット履歴も圧縮されます。 コンテキスト ウィンドウの最大サイズと最大出力サイズの両方を指定して、トークンの予算に対応した既定の戦略を有効にします。

AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
    MaxContextWindowTokens = 128_000,
    MaxOutputTokens = 16_384,
});

独自の戦略を使用するには、 HarnessAgentOptions.CompactionStrategy; を設定して圧縮をオフにし、 DisableCompaction = true設定します。

機能のカスタマイズと無効化

すべての既定の機能には、 HarnessAgentOptionsに対応する無効化フラグがあるため、必要なパイプラインを保持し、残りを削除できます。

AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
    HarnessInstructions = "Custom operating guidelines here.",
    DisableTodoProvider = true,      // No todo list
    DisableAgentModeProvider = true, // No plan/execute modes
    DisableWebSearch = true,         // No hosted web search tool
    DisableFileMemory = true,        // No file-based session memory
});

その他のフラグには、 DisableFileAccessDisableAgentSkillsProviderDisableToolAutoApproval、および DisableOpenTelemetryがあります。 また、 AIContextProviders を使用して独自のコンテキスト プロバイダーを追加し、 AgentSkillsSourceを介してカスタムの場所にスキル プロバイダーをポイントすることもできます。

完了するまでループする

既定では、ハーネスは呼び出しごとに 1 回実行されます。 1 つ以上の LoopEvaluator インスタンスを指定して、エバリュエーターが完了すると判断するまでエージェントを自動的に再呼び出します (たとえば、完了マーカーが表示されたとき、述語が満たされたとき、AI の判事が承認したときなど)。

AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
    LoopEvaluators = [new CompletionMarkerLoopEvaluator("DONE")],
});

ループは最も外側のエージェント デコレーターとして適用されるため、各イテレーションは、ツールによって承認され、トレースされた完全なエージェント実行になります。

シェルとバックグラウンド エージェント

エージェントでシェル コマンドを実行できるようにするには、 ShellExecutorを渡します。 これにより、承認ゲートシェル実行ツールと、OS、シェル、作業ディレクトリの情報をコンテキストに挿入するプロバイダーが追加されます。

using Microsoft.Agents.AI.Tools.Shell;

// A shell confined to a working directory. Commands require approval by default;
// the deny-list is a UX pre-filter, not a security boundary.
await using var shell = new LocalShellExecutor(new LocalShellExecutorOptions
{
    WorkingDirectory = workingDir,
    ConfineWorkingDirectory = true,
    Policy = new ShellPolicy(denyList: [@"\brm\s+-rf\b", @"\bsudo\b"]),
});

AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
    ShellExecutor = shell,
});

並列デリゲーションを有効にするには、バックグラウンドエージェントのセットを渡します。 エージェントは、同時実行のためにサブタスクを渡すことができます。

AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
    BackgroundAgents = [webSearchAgent, codeAgent],
});

ハーネス エージェントの作成

ハーネスは create_harness_agent ファクトリ関数として公開されており、チャット クライアントから構成済みの Agent を組み立てます。 最も単純な形式では、クライアントのみが必要です。

from agent_framework import create_harness_agent
from agent_framework.openai import OpenAIChatClient

agent = create_harness_agent(
    OpenAIChatClient(model="gpt-4o"),
)

session = agent.create_session()
response = await agent.run("Plan a weekend trip to Seattle.", session=session)
print(response.text)

ハーネスレベルの指示では一般的な運用ガイドラインを説明し、タスク固有の指示は agent_instructions に記載します。 ハーネスには、既定のハーネス レベル命令 (DEFAULT_HARNESS_INSTRUCTIONS) が付属しており、 harness_instructionsを介してオーバーライドできます。 追加のツールを渡すこともできます。

agent = create_harness_agent(
    client=client,
    name="research-agent",
    agent_instructions="You are a research assistant focused on academic sources.",
    tools=get_stock_price,
)

圧縮の有効化

圧縮により、長いツール呼び出しループでコンテキスト ウィンドウがオーバーフローするのを防ぐことができます。 モデルのコンテキスト ウィンドウの最大サイズと最大出力サイズの両方を指定して、トークンの予算に対応した既定の戦略を有効にします。

agent = create_harness_agent(
    client=client,
    max_context_window_tokens=128_000,
    max_output_tokens=16_384,
)

トークン パラメーターもカスタム戦略も指定されていない場合、圧縮は自動的に無効になります。 独自の戦略を使用するには、 before_compaction_strategyafter_compaction_strategyを渡し、圧縮を明示的にオフにするには、 disable_compaction=True設定します。

機能のカスタマイズと無効化

すべての既定の機能には対応する disable_* キーワード引数があるため、必要な部分を保持して残りの部分を削除できます。

agent = create_harness_agent(
    client=client,
    harness_instructions="Custom operating guidelines here.",
    disable_todo=True,         # No todo list
    disable_mode=True,         # No plan/execute modes
    disable_web_search=True,   # No hosted web search tool
    disable_file_memory=True,  # No file-based session memory
)

その他のフラグには、 disable_file_accessdisable_tool_auto_approval、および disable_compactionがあります。 skills_pathsを使用してカスタムの場所でスキル検出をポイントし、context_providersを使用して独自のプロバイダーを追加できます。

完了するまでループする

既定では、ハーネスは呼び出しごとに 1 回実行されます。 loop_should_continue の述語を渡すことで、述語が完了と判断するまでエージェントを自動的に再度呼び出します。 loop_next_messageを使用して、各フォローアップ イテレーションのプロンプトを制御し、パスの数を制限するloop_max_iterationsを使用します。

from agent_framework import create_harness_agent, todos_remaining

agent = create_harness_agent(
    client=client,
    loop_should_continue=todos_remaining(),
    loop_max_iterations=10,
)

述語は、キーワード引数 (iterationlast_resultsessionagentなど) を使用して呼び出されます。 todos_remaining 、todo リストに開いている項目がある間はエージェントを再実行します。 独自のキーワード引数を記述するには、 lambda *, last_result, **kwargs: "DONE" not in last_result.textなど、これらのキーワード引数を受け入れます。

シェルとバックグラウンド エージェント

エージェントがシェル コマンドを実行できるようにするには、shell_executor (たとえば、LocalShellToolからagent-framework-tools) を渡します。 これにより、承認ゲートシェル実行ツールと、OS とシェル環境をプローブするプロバイダーが追加されます。 呼び出し元が Executor のライフサイクルを管理します:

from agent_framework_tools.shell import LocalShellTool, ShellPolicy

# A shell confined to a working directory. Commands require approval by default;
# the deny-list is a UX pre-filter, not a security boundary.
async with LocalShellTool(
    workdir="./working",
    confine_workdir=True,
    policy=ShellPolicy(denylist=[r"\brm\s+-rf\b", r"\bsudo\b"]),
) as shell:
    agent = create_harness_agent(
        client=client,
        shell_executor=shell,
    )

並列委譲を有効にするには、バックグラウンドエージェントのシーケンスを渡します。 エージェントは、同時実行のためにサブタスクを渡すことができます。

agent = create_harness_agent(
    client=client,
    background_agents=[web_search_agent, code_agent],
)

Note

エージェント ハーネスの Go サポートは近日公開予定です。 最新の状態については、 Agent Framework Go リポジトリ を参照してください。

ワークフローの計画と実行

エージェント モード プロバイダーを使用すると、todo リストと自然にペアリングされる 2 フェーズの作業スタイルが可能になります。

  1. プラン モード - 対話型。 エージェントは、明確な質問をし、ToDo リストと計画を下書きし、重要な作業を行う前に承認を得ます。
  2. 実行モード — 自律的。 エージェントは、ToDo項目を自律的に処理しながら、進捗を報告します。

モード プロバイダーには既定のモードとしてプラン モードと実行モードが付属していますが、必要に応じて、各モードの他のモードとカスタム命令に置き換えることができます。

ターミナル UX の例

ハーネスは有能なエージェントを提供しますが、人々がそれとどのようにやり取りするかまでは規定しません。 ハーネスのエンドツーエンドの動作を示すために、サンプルのターミナル UX を用意しています。これは、エージェントの出力をストリーミングし、ToDo リストと現在のモードを表示し、ツールの承認を求めるプロンプトを提示し、/todos/mode/exit などのスラッシュコマンドをサポートする対話型コンソール(TUI)です。

Important

これらのコンソール プロジェクトは サンプルであり、出荷されたフレームワークの一部ではありません。 これらは意図的に自己完結型であるため、as-is 実行してハーネスを探索したり、独自のターミナル エクスペリエンスを構築するための開始点として独自のプロジェクトにコピーしたりできます。

.NETサンプル コンソールは、Harness.Shared.Console プロジェクトです。 そのエントリ ポイントは HarnessConsole.RunAgentAsync であり、エージェント、プレースホルダー プロンプト、任意の HarnessConsoleOptions (オブザーバー、スラッシュコマンド ハンドラー、モード カラー) を受け取ります。

using Harness.Shared.Console;

await HarnessConsole.RunAgentAsync(agent, userPrompt: "Ask me anything to get started.");

独自のオブザーバー、ツール フォーマッタ、コマンド ハンドラーを使用してカスタマイズするか、独自のターミナル エクスペリエンスのベースとしてフォークします。 .NETハーネスのサンプルを参照してください。

Pythonサンプル コンソールは、ハーネスサンプルの横にあるconsoleパッケージです。 そのエントリ ポイントは、run_agent_async ベースのアプリを実行するです。

from console import run_agent_async

await run_agent_async(agent)

オブザーバー、UI コンポーネント、スラッシュ コマンドを中心に編成され、すべて ConsoleObserverToolCallFormatter、および CommandHandler 基底クラスを介して拡張可能です ( textualrichによって異なります)。 as-is実行するか、独自のターミナル エクスペリエンスのベースとしてコピーします。 Pythonハーネスのサンプルを参照してください。

次のステップ

さらに詳しく