A2A エージェント

A2AAgentを使用すると、アプリケーションはエージェント間 (A2A) プロトコルを介して公開されているリモート エージェントに接続できます。 A2A 準拠エンドポイントが標準の AIAgentとしてラップされるため、 RunAsyncRunStreamingAsync などの使い慣れた方法を使用して、構築されたフレームワークやテクノロジに関係なくリモート エージェントと対話できます。

はじめに

必要な NuGet パッケージをプロジェクトに追加します。

dotnet add package Microsoft.Agents.AI.A2A --prerelease

エージェントの検出

リモート A2A エージェントと通信する前に、それを検出し、 AIAgent インスタンスを作成する必要があります。 A2A プロトコルは、エージェント フレームワークでサポートされる 3 つの 検出戦略を定義します。

Well-Known URI

A2A エージェントは、標準化されたパス (https://{domain}/.well-known/agent-card.json) でエージェント カードを検出できるようにします。 A2ACardResolverを使用してカードをフェッチし、1 回の呼び出しでエージェントを作成します。

using A2A;
using Microsoft.Agents.AI;

// Initialize a resolver pointing at the remote agent's host.
A2ACardResolver resolver = new(new Uri("https://a2a-agent.example.com"));

// Resolve the agent card and create an AIAgent in one step.
AIAgent agent = await resolver.GetAIAgentAsync();

// Use the agent.
Console.WriteLine(await agent.RunAsync("Hello!"));

ヒント

GetAIAgentAsyncでは、プロトコル選択の省略可能な A2AClientOptions パラメーターも受け取ります。

Catalog-Based 検出

エンタープライズ環境またはパブリック マーケットプレースでは、多くの場合、エージェント カードは中央レジストリによって管理されます。 このようなレジストリから取得した AgentCard が既にある場合は、それを直接 AIAgentに変換します。

using A2A;
using Microsoft.Agents.AI;

// Assume agentCard was retrieved from a registry or catalog.
AgentCard agentCard = await GetAgentCardFromRegistryAsync("travel-planner");

AIAgent agent = agentCard.AsAIAgent();

Console.WriteLine(await agent.RunAsync("Plan a trip to Paris."));

ダイレクト構成

エージェント エンドポイントが事前にわかっている密結合システムまたは開発シナリオの場合は、 A2AClient を直接作成し、 AIAgentに変換します。

using A2A;
using Microsoft.Agents.AI;

// Create a client pointing at the known agent endpoint.
A2AClient a2aClient = new(new Uri("https://a2a-agent.example.com"));

AIAgent agent = a2aClient.AsAIAgent(name: "my-agent", description: "A helpful assistant.");

Console.WriteLine(await agent.RunAsync("What can you help me with?"));

プロトコルの選択

A2A エージェントは、HTTP+JSON や JSON-RPC などの複数のプロトコル バインディングを公開できます。 既定では、HTTP+ JSON は JSON-RPC よりも優先されます。 A2AClientOptions.PreferredBindingsを使用して、使用するプロトコル バインディングを明示的に制御します。

Note

リモート A2A エージェントは、選択したプロトコル バインディングをサポートするエンドポイントで使用できる必要があります。

using A2A;
using Microsoft.Agents.AI;

A2ACardResolver agentCardResolver = new(new Uri("https://a2a-agent.example.com"));

AgentCard agentCard = await agentCardResolver.GetAgentCardAsync();

// Prefer HTTP+JSON protocol binding. For JSON-RPC, set PreferredBindings = [ProtocolBindingNames.JsonRpc]
A2AClientOptions options = new()
{
    PreferredBindings = [ProtocolBindingNames.HttpJson]
};

AIAgent agent = agentCard.AsAIAgent(options: options);

Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));

ストリーミング

A2A では、Server-Sent イベントを介したストリーミング応答がサポートされます。 リモート エージェントが要求を処理する際に、 RunStreamingAsync を使用してリアルタイムで更新プログラムを受信します。

using A2A;
using Microsoft.Agents.AI;

A2ACardResolver resolver = new(new Uri("https://a2a-agent.example.com"));
AIAgent agent = await resolver.GetAIAgentAsync();

await foreach (var update in agent.RunStreamingAsync("Write a short story about a robot."))
{
    if (!string.IsNullOrEmpty(update.Text))
    {
        Console.Write(update.Text);
    }
}

バックグラウンド応答

A2A エージェントは、実行時間の長い操作を処理するための バックグラウンド応答 をサポートします。 リモート A2A エージェントが即時メッセージではなくタスクを返すと、Agent Framework は、結果のポーリングや中断されたストリームへの再接続に使用できる継続トークンを提供します。

タスク完了のポーリング

ストリーミング以外のシナリオでは、 AllowBackgroundResponses を使用して継続トークンを受け取り、タスクが完了するまでポーリングします。

using A2A;
using Microsoft.Agents.AI;

A2ACardResolver resolver = new(new Uri("https://a2a-agent.example.com"));
AIAgent agent = await resolver.GetAIAgentAsync();

AgentSession session = await agent.CreateSessionAsync();

// AllowBackgroundResponses must be true so the server returns immediately with a continuation token
// instead of blocking until the task is complete.
AgentRunOptions options = new() { AllowBackgroundResponses = true };

// Start the initial run with a long-running task.
AgentResponse response = await agent.RunAsync(
    "Conduct a comprehensive analysis of quantum computing applications in cryptography.",
    session,
    options: options);

// Poll until the response is complete.
while (response.ContinuationToken is { } token)
{
    // Wait before polling again.
    await Task.Delay(TimeSpan.FromSeconds(2));

    // Continue with the token.
    response = await agent.RunAsync(session, options: new AgentRunOptions { ContinuationToken = token });
}

Console.WriteLine(response);

ストリームの再接続

ストリーミング シナリオでは、各更新プログラムに継続トークンが含まれる場合があります。 ストリームが中断された場合は、トークンを使用して再接続し、最初から応答ストリームを取得します。

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

A2ACardResolver resolver = new(new Uri("https://a2a-agent.example.com"));
AIAgent agent = await resolver.GetAIAgentAsync();

AgentSession session = await agent.CreateSessionAsync();

ResponseContinuationToken? continuationToken = null;

await foreach (var update in agent.RunStreamingAsync(
    "Conduct a comprehensive analysis of quantum computing applications in cryptography.",
    session))
{
    // Save the continuation token to reconnect later if the stream is interrupted.
    // Continuation tokens are only returned for long-running tasks. If the A2A agent
    // returns a message instead of a task, the continuation token will not be initialized.
    if (update.ContinuationToken is { } token)
    {
        continuationToken = token;
    }
}

// If the stream was interrupted and a continuation token was captured,
// reconnect to the response stream using the saved continuation token.
if (continuationToken is not null)
{
    await foreach (var update in agent.RunStreamingAsync(
        session,
        options: new() { ContinuationToken = continuationToken }))
    {
        if (!string.IsNullOrEmpty(update.Text))
        {
            Console.WriteLine(update.Text);
        }
    }
}

Note

A2A エージェントは、ストリーム内の特定のポイントからのストリーム再開ではなく、ストリーム再接続 (最初から同じ応答ストリームを取得) をサポートします。

Note

Python A2A エージェントのドキュメントは近日公開予定です。

次のステップ