エージェント ハーネス

エージェント ハーネス (AI ハーネスとも呼ばれます) は、言語モデルを作業を実行できるエージェントに変換するランタイム スキャフォールディングです。 モデルとツールの呼び出しを促進し、会話の状態とコンテキストを管理し、承認ポリシーを適用し、マルチステップ タスクを通じてエージェントの進行状況を維持できます。

Agent Framework は、研究、コーディング、データ分析、その他の長時間実行される作業向けに、明確な設計思想に基づき、必要な機能がすべて揃ったハーネスを提供します。 チャット クライアントを提供し、アプリケーションで必要な機能のみをカスタマイズします。

Architecture

Harness は、別のエージェント ランタイムを定義するのではなく、既存の Agent Framework の構成要素を構成します。

  1. チャット クライアント - エージェントをモデルに接続します。
  2. チャット パイプライン - 関数の呼び出し、メッセージの挿入、サービスごとの呼び出し履歴の永続化、およびオプションの圧縮が追加されます。
  3. エージェントとコンテキスト プロバイダー — セッション スコープの命令、ツール、メモリ、todo 状態、操作モード、およびオプションの機能を追加します。
  4. ミドルウェアとデコレーター — 承認処理、可観測性、およびオプションの有界ループを追加します。
  5. アプリケーション UX — 応答をストリーム配信し、進行状況を表示し、ツールの承認などの入力を収集します。

結果のオブジェクトは、通常の Agent Framework エージェントのままです。.NET では HarnessAgent から派生した AIAgent、Python では Agent によって返される create_harness_agent、または Go では *agent.Agent で構成された provider-backed の harness.AgentConfig です。 そのセッションでは、他のエージェントと同じ セッション と コンテキスト プロバイダー の抽象化が使用されます。

ハーネス機能マトリックス

Capability ハーネスの動作 標準ガイダンス
関数呼び出し 構成可能な要求ごとのイテレーション制限で有効になります。 Go プロバイダー コンストラクターは、ツール呼び出しループを担います。 関数ツール
サービスごとの呼び出し履歴の永続化 ツール呼び出しの実行で各モデル呼び出しの後に履歴を保持します。 セッション
圧縮 トークンの制限またはカスタム戦略が.NETおよびPythonで指定された場合に有効になります。 Go には、明示的なプロバイダー構成が必要です。 圧縮
Todo の追跡 既定で有効になっています。 計画と ToDo
エージェント モード プラン モードと実行モードは、既定で有効になっています。 計画と ToDo
ファイル メモリとファイル アクセス セッション ファイル メモリは既定で有効になっています。共有ファイル アクセスはオプトインです。 コンテキスト プロバイダー
ツールの承認 永続的な承認と自動承認ルールは、既定で有効になっています。 ツールの承認
OpenTelemetry エージェントの可観測性は既定で有効になっています。 可観測性
Web 検索 選択したチャット クライアントがサポートする場所に、既定で追加されます。 Web 検索
エージェント のスキル .NET と Go では既定で有効になり、Python ではプロバイダーまたはパス経由でオプトインします。 エージェント のスキル
バックグラウンド エージェント .NETおよびPythonの名前付き子エージェントへの省略可能な並列委任。 パッケージ化された Go バックグラウンド エージェント プロバイダーはありません。 バックグラウンド エージェント
シェルの実行 シェル パッケージから構成されます。Pythonファクトリは自動的に配線できます。 シェル ツール
ループ 評価子または述語によって駆動される、オプションの境界付き再呼び出し。 エージェントのループ動作

バックグラウンド エージェントの委任は、プロバイダーが管理 するバックグラウンド応答とは別です。 バックグラウンド エージェントは、委任されたタスクで子エージェントを実行します。バックグラウンド応答は、継続トークンを使用して 1 つのプロバイダー要求をポーリングまたは再開します。

Tip

Python ハーネス アプリケーションの作成に役立つコーディング エージェント ガイダンスを利用するには、agent-framework-builder-python をインストールします。 この外部コーディング エージェント スキルは、マトリックスに記載されているランタイム エージェント スキル機能とは別です。

ハーネス エージェントを作成する

Microsoft.Agents.AI.Harness パッケージは、HarnessAgent名前空間のMicrosoft.Agents.AIを公開します。 IChatClientを使用して任意のAsHarnessAgentから作成するか、HarnessAgentを直接構築します。

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

AIAgent agent = chatClient.AsHarnessAgent();

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

HarnessAgentOptionsを使用して、ハーネス レベルの運用ガイダンス、エージェント固有の手順、および機能オプションを設定します。

AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
    Name = "research-agent",
    HarnessInstructions = "Use tools deliberately and report verified results.",
    ChatOptions = new ChatOptions
    {
        Instructions = "You are a research assistant focused on academic sources.",
    },
    MaxContextWindowTokens = 128_000,
    MaxOutputTokens = 16_384,
});

HarnessAgent.DefaultInstructions は、既定のハーネス ガイダンスを提供します。 HarnessInstructions は、 ChatOptions.Instructionsの前に表示されます。

コンポジションをカスタマイズする

既定の機能には、 DisableTodoProvider、 DisableAgentModeProvider、 DisableFileMemory、 DisableAgentSkillsProvider、 DisableWebSearch、 DisableToolAutoApproval、 DisableOpenTelemetry、 DisableCompactionなどの対象オプションがあります。

AIContextProvidersを使用してカスタム コンテキスト プロバイダーを追加します。 FileAccessStoreでのファイル アクセス、BackgroundAgentsを使用したバックグラウンド委任、および LoopEvaluators でのループを選択します。

ハーネス エージェントを作成する

create_harness_agent ファクトリは、完全に構成されたAgentを返します。

from agent_framework import create_harness_agent
from agent_framework.openai import OpenAIChatClient

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

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

ハーネス レベルとエージェント固有の命令を個別に設定します。

agent = create_harness_agent(
    client=client,
    name="research-agent",
    harness_instructions="Use tools deliberately and report verified results.",
    agent_instructions="You are a research assistant focused on academic sources.",
    max_context_window_tokens=128_000,
    max_output_tokens=16_384,
)

DEFAULT_HARNESS_INSTRUCTIONS は、既定のハーネス ガイダンスを提供します。 harness_instructions は、 agent_instructionsの前に表示されます。

コンポジションをカスタマイズする

disable_todo、disable_mode、disable_file_memory、disable_web_search、disable_tool_auto_approval、disable_compactionなどのオプションで既定値を無効にします。

組み込みのプロバイダーを todo_provider または mode_providerに置き換え、プロバイダーを context_providersに追加します。 スキルは skills_provider または skills_pathsによってオプトインされます。ファイル アクセス、バックグラウンド エージェント、シェル ツール、ループもオプトインされます。

ファイル アクセスでは、指定されたストアが既定で 1 つの共有ワークスペースとして使用されます。 アクティブなセッション ID でファイルを分離するには、セッション スコープのファイル アクセスを有効にします。

from agent_framework import FileSystemAgentFileStore, create_harness_agent

file_store = FileSystemAgentFileStore("agent-files")
agent = create_harness_agent(
    client=client,
    file_access_store=file_store,
    file_access_session_scoped=True,
)

選択したセッション間で意図的に共有する場合は、 FileAccessProvider(store=file_store, scope="tenant-1") を直接構築し、 context_providersを介して追加します。 スコープは、パスではなく、プロバイダー管理フォルダーにマップされる不透明なキーです。 アクティブなセッション ID も明示的なスコープも使用できない場合、共有ストア ルートを使用する代わりに、スコープ付きアクセスが閉じられません。

1 つのエージェントに複数のファイル アクセス プロバイダーがある場合は、 tool_name_prefix を使用します。 プレフィックスは、 workspace_file_access_read などの名前を生成し、ツール名の競合を防ぎます。 プレフィックス付きプロバイダーの場合は、プロバイダー固有の承認規則ファクトリを使用して、各規則がそのプロバイダーの生成名と一致するようにします。

from agent_framework import FileAccessProvider, create_harness_agent

workspace = FileAccessProvider(
    store=file_store,
    tool_name_prefix="workspace",
)

agent = create_harness_agent(
    client=client,
    context_providers=[workspace],
    auto_approval_rules=[workspace.get_read_only_tools_auto_approval_rule()],
)

get_all_tools_auto_approval_rule() は、読み取りツールと書き込みツールの両方に対して同等のルールを作成します。 ストレージ境界とツール入力が信頼できる場合を除き、書き込み承認を有効のままにします。

ファイル アクセスが有効になっている場合は、 file_access_grep を使用して 1 から始まる行番号を検索し、 file_access_read_lines を使用して包括範囲を検査し、 file_access_replace_lines して行全体を編集します。 file_access_read_lines 各行に番号とタブのプレフィックスを付けます。行テキストを expected_lineとして渡すときは、そのプレフィックスを省略します。 想定されたテキストは、古くなった行番号や一致しない行番号によって誤った行が編集されるのを防ぎます。

file_access_grep では、大文字と小文字を区別しない正規表現を使用し、最大 256 文字のパターンを受け入れ、検索全体に 10 秒の予算を適用します。 無効または過剰なパターンと、予算を超える検索はエラーを返します。 再試行する前に、ディレクトリまたはパターンを絞り込みます。

Important

file_access_grep は、行終端記号と一致する行テキストを返します。 カスタム AgentFileStore.search()実装では、read()によって返されるテキストに対してAgentFileStore.split_lines()と同じ行に対応する 1 から始まる行番号を返す必要があります。

Note

create_harness_agent がリリースされました。 バックグラウンド エージェント、ファイル アクセス、ループは試験段階のままであり、シェル ツールはプレリリース agent-framework-tools パッケージから取得されます。

Go agent/harness パッケージは、通常のプロバイダーに基づくエージェントのミドルウェア、コンテキスト プロバイダー、および履歴のデフォルト設定をアセンブルします。 harness.AgentConfig(harness.Config{}, agent.Config{...})を呼び出し、エラーを処理し、返された構成をプロバイダー コンストラクターに渡します。 個別のエージェントの種類やツール実行ループは導入されません。

ハーネス エージェントを作成する

複合サンプルは、Foundry に基づくハーネス エージェントを構成します。

import (
    "context"
    "fmt"
    "os"
    "path/filepath"

    "github.com/microsoft/agent-framework-go/agent"
    "github.com/microsoft/agent-framework-go/agent/harness"
    "github.com/microsoft/agent-framework-go/examples/internal/demo"
    "github.com/microsoft/agent-framework-go/message"
    "github.com/microsoft/agent-framework-go/provider/foundryprovider"
)
    workingDirectory, err := os.Getwd()
    if err != nil {
        return fmt.Errorf("get working directory: %w", err)
    }
    cfg, err := harness.AgentConfig(harness.Config{WorkingDirectory: workingDirectory}, agent.Config{
        Name:        "HarnessAssistant",
        Middlewares: []agent.Middleware{logger},
    })
    if err != nil {
        return err
    }
    a := foundryprovider.NewAgent(
        demo.FoundryProjectEndpoint,
        demo.FoundryTokenCredential(),
        foundryprovider.ModelDeployment(demo.FoundryModel),
        foundryprovider.AgentConfig{
            Config:             cfg,
            DisableStoreOutput: true,
            Instructions:       "Help with software engineering tasks. Use memory and todos to track the current session's work.",
        },
    )

コンポジションをカスタマイズする

ヘルパーでは、次の既定値が有効になります。

コンポーネント Go harness default
Planning セッションに基づく todo ツールとプラン/実行モード (プラン モードから開始)
ファイル メモリー セッションごとに分離された作業フォルダーを持つ、 agent-file-memory下の永続的なファイル
Skills 作業ディレクトリからのファイルベースの検出 (メモリ サブツリーを除く)
Web 検索 呼び出し元が既に指定している場合を除き、ホストされた Web 検索宣言
Approval 承認が必要なツールの事前承認および自動承認ミドルウェア
History サービス呼び出しごとの永続化を使用したメモリ内履歴
メッセージの挿入 エージェントごとの agent.MessageInjector
トレース エージェント、ツール、サポート対象のモデル呼び出しの計装

コンポーネントを無効にしたり、構成をオーバーライドしたりするには、 harness.Config を使用します。 選択したサービスまたはデプロイがそれをサポートしていない場合は、ホストされた Web 検索を無効にします。 ファイルベースのスキル スクリプトには、明示的に構成されたスクリプト ランナーが必要です。

ヘルパーは、呼び出し元ツール、ミドルウェア、コンテキスト プロバイダー、および明示的に構成された履歴プロバイダーを保持します。 Foundry モデルのデプロイでは、ローカル履歴が会話の管理を担う場合に DisableStoreOutput: true を使用します。

コンパクション、ループ、およびシェル ツールは Go ヘルパーによって追加されません。 必要に応じて明示的に設定します。 他の SDK で説明されているパッケージ化されたバックグラウンド エージェント委任プロバイダーは、Go では使用できません。

セットアップについては Go ハーネス エージェントの作成 を参照し、既定値とオーバーライドについては Go ハーネス構成ガイド を参照してください。

ターミナル UX のサンプル

Harness はアプリケーション インターフェイスを規定していません。 リポジトリには、出力のストリーミング、todo と現在のモードの表示、ツール承認プロンプトの表示、 /todos、 /mode、 /exitなどのコマンドを提供するサンプル ターミナル アプリケーションが含まれています。

Important

これらのコンソール プロジェクトはサンプルであり、出荷されたフレームワーク コンポーネントではありません。 実行可能な例として、または独自のターミナル エクスペリエンスの開始点として使用します。

.NETサンプル エントリ ポイントはHarnessConsole.RunAgentAsync。

using Harness.Shared.Console;

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

オブザーバー、ツール フォーマッタ、コマンド ハンドラー、 HarnessConsoleOptionsを使用してサンプルをカスタマイズします。 .NET ハーネスのサンプルを参照してください。

Pythonサンプルでは、Harness サンプルの横にあるテキストベースのconsole パッケージを使用します。

from console import run_agent_async

await run_agent_async(agent)

オブザーバー、フォーマッタ、コマンド、UI コンポーネントを使用してサンプルをカスタマイズします。 Python ハーネスのサンプルを参照してください。

Go リポジトリには、承認処理を含む 複合ハーネス サンプル と、別の 対話型チャット CLI デモが含まれています。 チャット CLI はプレーン エージェントを使用します。C# または Python Harness コンソールと同等ではありません。

次のステップ

さらに詳しく