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 核心组件
- A2A 核心库: 包含协议的核心实现
- A2A.AspNetCore: 提供 ASP.NET Core 集成
- 示例项目: 演示不同使用场景的示例代码
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)
}
关键特性:
- JSON-RPC 通信: 所有通信都通过 JSON-RPC 协议进行
- 流式响应: 支持 Server-Sent Events (SSE) 进行实时流式传输
- 序列化优化: 使用 System.Text.Json 源生成器进行高性能序列化
- 错误处理: 完整的错误处理和状态管理
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
是服务器端的核心组件,负责管理任务的生命周期。
主要职责:
- 任务生命周期管理: 创建、更新、取消任务
- 消息处理: 处理传入的消息和任务更新
- 事件分发: 管理任务状态变化事件
- 存储抽象: 通过
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 示例展示了如何创建和部署多个不同类型的代理,包括:
- EchoAgent: 简单的回声代理
- EchoAgentWithTasks: 支持任务的回声代理
- HostedClientAgent: 托管客户端代理
- 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 运行步骤
-
克隆项目:
git clone https://github.com/a2aproject/a2a-dotnet cd a2a-dotnet
-
进入示例目录:
cd samples/AgentServer
-
运行项目:
dotnet run
-
验证服务运行: 服务将在以下端口启动:
- HTTP: http://localhost:5048
- HTTPS: https://localhost:7014
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 性能优化
- 源生成序列化: 使用 System.Text.Json 源生成器
- AOT 兼容: 支持 Native AOT 编译
- 异步处理: 全面使用异步/等待模式
- 流式处理: 支持大数据量的流式传输
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 主要优势
- 标准化协议: 基于 Google A2A 协议标准
- 易于集成: 简单的 ASP.NET Core 集成
- 灵活架构: 支持多种代理实现模式
- 高性能: 优化的序列化和异步处理
- 可观测性: 内置遥测和监控支持
- 可扩展性: 抽象接口支持自定义实现
11.2 适用场景
- AI 代理系统: 构建智能代理交互系统
- 微服务架构: 服务间的智能通信
- 工作流引擎: 复杂业务流程的代理化处理
- 聊天机器人: 多代理协作的对话系统
11.3 未来发展
- 推送通知: 完整的客户端回调支持
- 更多存储后端: 数据库和分布式存储支持
- 安全增强: 更完善的认证和授权机制
- 协议更新: 跟进 A2A 协议的最新版本
11.4 开发建议
- 从简单开始: 使用 EchoAgent 了解基本概念
- 理解状态管理: 研究 ResearcherAgent 的状态机实现
- 重视错误处理: 实现完善的错误处理和恢复机制
- 监控和调试: 利用 OpenTelemetry 进行系统监控
- 测试驱动: 编写全面的单元测试和集成测试
这个 SDK 为 .NET 开发者提供了一个强大而灵活的平台,用于构建下一代的智能代理系统。通过其清晰的架构和丰富的示例,开发者可以快速上手并构建复杂的代理间通信应用。