A2A Protocol

A2A .NET SDK Comprehensive Documentation

MILO
Share
A2A .NET SDK Comprehensive Documentation

1. 项目概述

A2A(Agent2Agent).NET SDK 是一个实现 Google A2A 协议 v0.2.1 的 .NET 库,用于在 .NET 应用程序中启用代理之间的通信。该 SDK 设计用于与 ASP.NET Core 应用程序配合使用,提供了一种简单的方式为您的代理添加 A2A 支持。

主要特性

  • 协议兼容性: 实现了 A2A 协议 v0.2.1 的大部分功能
  • 多框架支持: 支持 .NET 9.0、.NET 8.0 和 .NET Standard 2.0
  • ASP.NET Core 集成: 提供简单的集成方式
  • 任务管理: 标准化的任务管理和执行支持
  • 流式传输: 支持实时流式响应
  • OpenTelemetry: 内置遥测和可观测性支持

项目状态

该库已实现协议的大部分功能,但仍有一些场景可能不完整。最大的缺失功能是使用推送通知的客户端回调。

2. A2A .NET 核心架构

2.1 项目结构

src/
├── A2A/                    # 核心 A2A 协议实现
│   ├── Client/            # 客户端组件
│   ├── JsonRpc/           # JSON-RPC 实现
│   ├── Models/            # 数据模型
│   ├── Server/            # 服务器端组件
│   └── openapi.yaml       # API 规范
└── A2A.AspNetCore/        # ASP.NET Core 集成

2.2 核心组件

  1. A2A 核心库: 包含协议的核心实现
  2. A2A.AspNetCore: 提供 ASP.NET Core 集成
  3. 示例项目: 演示不同使用场景的示例代码

3. A2A .NET Client 端实现

3.1 A2AClient 类

A2AClient 类是与代理进行通信的主要客户端接口,实现了 IA2AClient 接口。

主要功能:

public class A2AClient : IA2AClient
{
    // 发送消息
    public Task<A2AResponse> SendMessageAsync(MessageSendParams taskSendParams)
    
    // 获取任务
    public Task<AgentTask> GetTaskAsync(string taskId)
    
    // 取消任务
    public Task<AgentTask> CancelTaskAsync(TaskIdParams taskIdParams)
    
    // 流式发送消息
    public async IAsyncEnumerable<SseItem<A2AEvent>> SendMessageStreamAsync(MessageSendParams taskSendParams)
    
    // 重新订阅任务
    public async IAsyncEnumerable<SseItem<A2AEvent>> ResubscribeToTaskAsync(string taskId)
}

关键特性:

  1. JSON-RPC 通信: 所有通信都通过 JSON-RPC 协议进行
  2. 流式响应: 支持 Server-Sent Events (SSE) 进行实时流式传输
  3. 序列化优化: 使用 System.Text.Json 源生成器进行高性能序列化
  4. 错误处理: 完整的错误处理和状态管理

3.2 JsonRpcContent 类

专门用于 JSON-RPC 请求的 HTTP 内容类:

public class JsonRpcContent : HttpContent
{
    public JsonRpcContent(JsonRpcRequest request)
    {
        _request = request;
        Headers.ContentType = new MediaTypeHeaderValue("application/json");
    }
}

3.3 A2ACardResolver 类

用于解析和获取代理卡片信息:

public class A2ACardResolver
{
    public async Task<AgentCard> GetAgentCardAsync(Uri agentUri)
    public async Task<AgentCard> GetAgentCardAsync(string agentUrl)
}

4. A2A .NET Server 端实现

4.1 TaskManager 类

TaskManager 是服务器端的核心组件,负责管理任务的生命周期。

主要职责:

  1. 任务生命周期管理: 创建、更新、取消任务
  2. 消息处理: 处理传入的消息和任务更新
  3. 事件分发: 管理任务状态变化事件
  4. 存储抽象: 通过 ITaskStore 接口进行任务持久化

核心方法:

public class TaskManager : ITaskManager
{
    // 事件处理器
    public Func<MessageSendParams, Task<Message>>? OnMessageReceived { get; set; }
    public Func<AgentTask, Task> OnTaskCreated { get; set; }
    public Func<AgentTask, Task> OnTaskCancelled { get; set; }
    public Func<AgentTask, Task> OnTaskUpdated { get; set; }
    public Func<string, AgentCard> OnAgentCardQuery { get; set; }
    
    // 核心操作
    public async Task<AgentTask> CreateTaskAsync(string? contextId = null)
    public async Task<AgentTask?> CancelTaskAsync(TaskIdParams? taskIdParams)
    public async Task<A2AResponse?> SendMessageAsync(MessageSendParams messageSendParams)
    public async Task<IAsyncEnumerable<A2AEvent>> SendMessageStreamAsync(MessageSendParams messageSendParams)
    public async Task UpdateStatusAsync(string taskId, TaskState status, Message? message = null, bool final = false)
    public async Task ReturnArtifactAsync(string taskId, Artifact artifact)
}

4.2 ITaskStore 接口

任务存储的抽象接口:

public interface ITaskStore
{
    Task<AgentTask?> GetTaskAsync(string taskId);
    Task SetTaskAsync(AgentTask task);
    Task UpdateStatusAsync(string taskId, TaskState status);
}

4.3 ASP.NET Core 集成

通过 A2A.AspNetCore 库提供的扩展方法:

// 添加 JSON-RPC A2A 支持
app.MapA2A(taskManager, "/echo");

// 添加 HTTP A2A 支持
app.MapHttpA2A(taskManager, "/echo");

5. A2A .NET 数据模型

5.1 核心模型类

AgentCard - 代理卡片

public class AgentCard
{
    public string Name { get; set; }                    // 代理名称
    public string Description { get; set; }            // 代理描述
    public string Url { get; set; }                     // 代理 URL
    public AgentProvider? Provider { get; set; }        // 提供商信息
    public string Version { get; set; }                 // 版本信息
    public AgentCapabilities Capabilities { get; set; } // 代理能力
    public List<AgentSkill> Skills { get; set; }        // 代理技能
    public List<string> DefaultInputModes { get; set; } // 默认输入模式
    public List<string> DefaultOutputModes { get; set; }// 默认输出模式
}

AgentTask - 代理任务

public class AgentTask : A2AResponse
{
    public string Id { get; set; }                      // 任务 ID
    public string? ContextId { get; set; }              // 上下文 ID
    public AgentTaskStatus Status { get; set; }         // 任务状态
    public List<Artifact>? Artifacts { get; set; }      // 任务产出物
    public List<Message>? History { get; set; }         // 消息历史
    public Dictionary<string, JsonElement>? Metadata { get; set; } // 元数据
}

Message - 消息

public class Message : A2AResponse
{
    public MessageRole Role { get; set; }               // 消息角色 (User/Agent)
    public List<Part> Parts { get; set; }               // 消息部分
    public string? MessageId { get; set; }              // 消息 ID
    public string? TaskId { get; set; }                 // 关联任务 ID
    public string? ContextId { get; set; }              // 上下文 ID
    public Dictionary<string, JsonElement>? Metadata { get; set; } // 元数据
}

5.2 任务状态

public enum TaskState
{
    Submitted,      // 已提交
    Working,        // 工作中
    InputRequired,  // 需要输入
    Completed,      // 已完成
    Canceled,       // 已取消
    Failed,         // 失败
    Rejected        // 被拒绝
}

5.3 消息部分类型

支持多种消息部分类型:

  • TextPart: 文本内容
  • FilePart: 文件内容
  • DataPart: 数据内容

6. A2A .NET AgentServer 示例详细分析

6.1 项目概览

AgentServer 示例展示了如何创建和部署多个不同类型的代理,包括:

  1. EchoAgent: 简单的回声代理
  2. EchoAgentWithTasks: 支持任务的回声代理
  3. HostedClientAgent: 托管客户端代理
  4. ResearcherAgent: 研究员代理(状态机实现)

6.2 EchoAgent 实现

public class EchoAgent
{
    private ITaskManager? _taskManager;

    public void Attach(TaskManager taskManager)
    {
        _taskManager = taskManager;
        taskManager.OnMessageReceived = ProcessMessage;
        taskManager.OnAgentCardQuery = GetAgentCard;
    }

    public Task<Message> ProcessMessage(MessageSendParams messageSendParams)
    {
        var messageText = messageSendParams.Message.Parts.OfType<TextPart>().First().Text;
        var message = new Message()
        {
            Role = MessageRole.Agent,
            MessageId = Guid.NewGuid().ToString(),
            ContextId = messageSendParams.Message.ContextId,
            Parts = [new TextPart() { Text = $"Echo: {messageText}" }]
        };
        return Task.FromResult(message);
    }
}

6.3 ResearcherAgent 实现

ResearcherAgent 展示了更复杂的状态机实现:

public class ResearcherAgent
{
    private enum AgentState
    {
        Planning,                    // 规划阶段
        WaitingForFeedbackOnPlan,   // 等待计划反馈
        Researching                 // 研究阶段
    }

    public async Task Invoke(string taskId, string message)
    {
        switch (_agentStates[taskId])
        {
            case AgentState.Planning:
                await DoPlanning(taskId, message);
                break;
            case AgentState.WaitingForFeedbackOnPlan:
                if (message == "go ahead")
                    await DoResearch(taskId, message);
                else
                    await DoPlanning(taskId, message);
                break;
            case AgentState.Researching:
                await DoResearch(taskId, message);
                break;
        }
    }
}

7. 如何运行 AgentServer 示例

7.1 环境要求

  • .NET 9.0 SDK 或更高版本
  • 可选:OpenTelemetry 收集器(用于遥测数据)

7.2 运行步骤

  1. 克隆项目

    git clone https://github.com/a2aproject/a2a-dotnet
    cd a2a-dotnet
    
  2. 进入示例目录

    cd samples/AgentServer
    
  3. 运行项目

    dotnet run
    
  4. 验证服务运行: 服务将在以下端口启动:

7.3 可用端点

  • /echo - 简单回声代理
  • /echotasks - 支持任务的回声代理
  • /hostedclient - 托管客户端代理
  • /researcher - 研究员代理

7.4 测试 API 调用

获取代理卡片

curl -X GET http://localhost:5048/echo/.well-known/agent.json

发送消息到回声代理

curl -X POST http://localhost:5048/echo \
  -H "Content-Type: application/json" \
  -d '{
    "id": "1",
    "jsonrpc": "2.0",
    "method": "message/send",
    "params": {
      "message": {
        "messageId": "12345",
        "role": "user",
        "parts": [
          {
            "kind": "text",
            "text": "Hello, world!"
          }
        ]
      }
    }
  }'

创建研究员代理任务

curl -X POST http://localhost:5048/researcher \
  -H "Content-Type: application/json" \
  -d '{
    "id": "1",
    "jsonrpc": "2.0",
    "method": "message/send",
    "params": {
      "message": {
        "messageId": "research-1",
        "role": "user",
        "parts": [
          {
            "kind": "text",
            "text": "Research the current price of butter"
          }
        ]
      }
    }
  }'

8. 时序图

8.1 简单消息处理时序图

sequenceDiagram
    participant Client as 客户端
    participant Server as A2A 服务器
    participant Agent as 代理实现
    participant TaskMgr as TaskManager

    Client->>Server: POST /echo (JSON-RPC message/send)
    Server->>TaskMgr: SendMessageAsync()
    TaskMgr->>Agent: OnMessageReceived()
    Agent->>Agent: ProcessMessage()
    Agent-->>TaskMgr: 返回 Message
    TaskMgr-->>Server: 返回 A2AResponse
    Server-->>Client: JSON-RPC Response

8.2 任务处理时序图

sequenceDiagram
    participant Client as 客户端
    participant Server as A2A 服务器
    participant TaskMgr as TaskManager
    participant Agent as 代理实现
    participant Store as TaskStore

    Client->>Server: POST /researcher (message/send)
    Server->>TaskMgr: SendMessageAsync()
    TaskMgr->>TaskMgr: CreateTaskAsync()
    TaskMgr->>Store: SetTaskAsync()
    TaskMgr->>Agent: OnTaskCreated()
    Agent->>Agent: 状态变更 (Planning)
    Agent->>TaskMgr: UpdateStatusAsync(Working)
    TaskMgr->>Store: UpdateStatusAsync()
    Agent->>TaskMgr: ReturnArtifactAsync()
    Agent->>TaskMgr: UpdateStatusAsync(InputRequired)
    TaskMgr-->>Server: 返回 AgentTask
    Server-->>Client: JSON-RPC Response

    Note over Client,Store: 客户端发送后续消息

    Client->>Server: POST /researcher (message/send, taskId)
    Server->>TaskMgr: SendMessageAsync()
    TaskMgr->>Store: GetTaskAsync()
    TaskMgr->>Agent: OnTaskUpdated()
    Agent->>Agent: 状态处理逻辑
    Agent->>TaskMgr: UpdateStatusAsync(Completed)
    TaskMgr-->>Server: 返回 AgentTask
    Server-->>Client: JSON-RPC Response

8.3 流式处理时序图

sequenceDiagram
    participant Client as 客户端
    participant Server as A2A 服务器
    participant TaskMgr as TaskManager
    participant Agent as 代理实现

    Client->>Server: POST /echo (JSON-RPC message/stream)
    Server->>TaskMgr: SendMessageStreamAsync()
    TaskMgr->>Agent: OnMessageReceived()
    
    loop 流式响应
        Agent->>TaskMgr: 生成事件
        TaskMgr->>Server: A2AEvent
        Server->>Client: Server-Sent Event
    end
    
    Agent->>TaskMgr: 完成处理
    TaskMgr->>Server: 结束流
    Server->>Client: 关闭连接

9. A2A .NET关键设计模式

9.1 事件驱动架构

TaskManager 使用事件驱动模式:

  • OnMessageReceived: 处理传入消息
  • OnTaskCreated: 任务创建事件
  • OnTaskUpdated: 任务更新事件
  • OnTaskCancelled: 任务取消事件

9.2 策略模式

不同的代理实现可以有不同的处理策略:

  • 无状态处理(EchoAgent)
  • 有状态处理(ResearcherAgent)
  • 任务导向处理(EchoAgentWithTasks)

9.3 存储抽象

通过 ITaskStore 接口抽象任务存储:

  • InMemoryTaskStore: 内存存储实现
  • 可扩展到数据库存储实现

10. A2A .NET 性能和可观测性

10.1 性能优化

  1. 源生成序列化: 使用 System.Text.Json 源生成器
  2. AOT 兼容: 支持 Native AOT 编译
  3. 异步处理: 全面使用异步/等待模式
  4. 流式处理: 支持大数据量的流式传输

10.2 可观测性

集成 OpenTelemetry 支持:

  • 分布式追踪: ActivitySource 集成
  • 指标收集: 任务状态和性能指标
  • 日志记录: 结构化日志支持
// OpenTelemetry 配置示例
builder.Services.AddOpenTelemetry()
    .WithTracing(tracing => tracing
        .AddSource(TaskManager.ActivitySource.Name)
        .AddSource(A2AJsonRpcProcessor.ActivitySource.Name)
        .AddConsoleExporter()
        .AddOtlpExporter());

11. A2A .NET 总结

A2A .NET SDK 提供了一个完整的、生产就绪的解决方案,用于在 .NET 应用程序中实现代理间通信。

11.1 主要优势

  1. 标准化协议: 基于 Google A2A 协议标准
  2. 易于集成: 简单的 ASP.NET Core 集成
  3. 灵活架构: 支持多种代理实现模式
  4. 高性能: 优化的序列化和异步处理
  5. 可观测性: 内置遥测和监控支持
  6. 可扩展性: 抽象接口支持自定义实现

11.2 适用场景

  1. AI 代理系统: 构建智能代理交互系统
  2. 微服务架构: 服务间的智能通信
  3. 工作流引擎: 复杂业务流程的代理化处理
  4. 聊天机器人: 多代理协作的对话系统

11.3 未来发展

  1. 推送通知: 完整的客户端回调支持
  2. 更多存储后端: 数据库和分布式存储支持
  3. 安全增强: 更完善的认证和授权机制
  4. 协议更新: 跟进 A2A 协议的最新版本

11.4 开发建议

  1. 从简单开始: 使用 EchoAgent 了解基本概念
  2. 理解状态管理: 研究 ResearcherAgent 的状态机实现
  3. 重视错误处理: 实现完善的错误处理和恢复机制
  4. 监控和调试: 利用 OpenTelemetry 进行系统监控
  5. 测试驱动: 编写全面的单元测试和集成测试

这个 SDK 为 .NET 开发者提供了一个强大而灵活的平台,用于构建下一代的智能代理系统。通过其清晰的架构和丰富的示例,开发者可以快速上手并构建复杂的代理间通信应用。