A2A协议开发指南
A2A协议开发指南
概述
A2A(Agent-to-Agent)协议是一种基于JSON-RPC的通信协议,专为代理之间的交互而设计。本指南为开发符合A2A协议规范的服务器和客户端组件提供了全面的指导。
目录
- 1. 协议基础
- 2. 服务器实现
- 3. 客户端实现
- 4. 运行Coder示例
协议基础
A2A协议建立在JSON-RPC 2.0之上,并定义了一组用于代理通信的方法。关键组件包括:
消息结构
所有A2A消息都遵循JSON-RPC 2.0格式,具有以下基本结构:
interface JSONRPCMessage {
jsonrpc?: "2.0";
id?: number | string | null;
method?: string;
params?: unknown;
result?: unknown;
error?: JSONRPCError;
}
协议流程
下面的序列图说明了A2A协议的主要交互流程:

核心方法
该协议支持几个核心方法:
- •
tasks/send
:向代理发送任务消息 - •
tasks/get
:检索任务状态 - •
tasks/cancel
:取消正在运行的任务 - •
tasks/pushNotification/set
:为任务配置推送通知 - •
tasks/pushNotification/get
:获取推送通知配置 - •
tasks/resubscribe
:重新订阅任务更新 - •
tasks/sendSubscribe
:发送任务消息并订阅更新
任务状态
任务可以处于以下状态之一:
- •
submitted
:已提交 - •
working
:正在处理 - •
input-required
:需要输入 - •
completed
:已完成 - •
canceled
:已取消 - •
failed
:失败 - •
unknown
:未知
服务器实现
核心组件
服务器实现由几个关键组件组成:
- 1. 服务器(server.ts):处理HTTP请求的主服务器实现
- 2. 处理器(handler.ts):用于处理A2A协议消息的请求处理器
- 3. 存储(store.ts):任务存储和管理
- 4. 工具(utils.ts):实用函数
- 5. 错误处理(error.ts):错误定义和处理
基本用法(概念性)
import {
A2AServer,
InMemoryTaskStore,
TaskContext,
TaskYieldUpdate,
} from "./index"; // Assuming imports from the server package
// 1. Define your agent's logic as a TaskHandler
async function* myAgentLogic(
context: TaskContext
): AsyncGenerator<TaskYieldUpdate> {
console.log(`Handling task: ${context.task.id}`);
yield {
state: "working",
message: { role: "agent", parts: [{ text: "Processing..." }] },
};
// Simulate work...
await new Promise((resolve) => setTimeout(resolve, 1000));
if (context.isCancelled()) {
console.log("Task cancelled!");
yield { state: "canceled" };
return;
}
// Yield an artifact
yield {
name: "result.txt",
mimeType: "text/plain",
parts: [{ text: `Task ${context.task.id} completed.` }],
};
// Yield final status
yield {
state: "completed",
message: { role: "agent", parts: [{ text: "Done!" }] },
};
}
// 2. Create and start the server
const store = new InMemoryTaskStore(); // Or new FileStore()
const server = new A2AServer(myAgentLogic, { taskStore: store });
server.start(); // Starts listening on default port 41241
console.log("A2A Server started.");
服务器将在配置的端口上启动(默认:3000)。
客户端实现
关键特性:
- • JSON-RPC通信: 根据JSON-RPC 2.0规范处理发送请求和接收响应(标准响应和通过服务器发送事件的流式响应)。
- • A2A方法: 实现标准A2A方法,如
sendTask
、sendTaskSubscribe
、getTask
、cancelTask
、setTaskPushNotification
、getTaskPushNotification
和resubscribeTask
。 - • 错误处理: 为网络问题和JSON-RPC错误提供基本错误处理。
- • 流支持: 管理服务器发送事件(SSE)以获取实时任务更新(
sendTaskSubscribe
、resubscribeTask
)。 - • 可扩展性: 允许为不同环境(例如Node.js)提供自定义
fetch
实现。
基本用法
import { A2AClient, Task, TaskQueryParams, TaskSendParams } from "./client"; // Import necessary types
import { v4 as uuidv4 } from "uuid"; // Example for generating task IDs
const client = new A2AClient("http://localhost:41241"); // Replace with your server URL
async function run() {
try {
// Send a simple task (pass only params)
const taskId = uuidv4();
const sendParams: TaskSendParams = {
id: taskId,
message: { role: "user", parts: [{ text: "Hello, agent!" }] },
};
// Method now returns Task | null directly
const taskResult: Task | null = await client.sendTask(sendParams);
console.log("Send Task Result:", taskResult);
// Get task status (pass only params)
const getParams: TaskQueryParams = { id: taskId };
// Method now returns Task | null directly
const getTaskResult: Task | null = await client.getTask(getParams);
console.log("Get Task Result:", getTaskResult);
} catch (error) {
console.error("A2A Client Error:", error);
}
}
run();
流式用法
import {
A2AClient,
TaskStatusUpdateEvent,
TaskArtifactUpdateEvent,
TaskSendParams, // Use params type directly
} from "./client"; // Adjust path if necessary
import { v4 as uuidv4 } from "uuid";
const client = new A2AClient("http://localhost:41241");
async function streamTask() {
const streamingTaskId = uuidv4();
try {
console.log(`\n--- Starting streaming task ${streamingTaskId} ---`);
// Construct just the params
const streamParams: TaskSendParams = {
id: streamingTaskId,
message: { role: "user", parts: [{ text: "Stream me some updates!" }] },
};
// Pass only params to the client method
const stream = client.sendTaskSubscribe(streamParams);
// Stream now yields the event payloads directly
for await (const event of stream) {
// Type guard to differentiate events based on structure
if ("status" in event) {
// It's a TaskStatusUpdateEvent
const statusEvent = event as TaskStatusUpdateEvent; // Cast for clarity
console.log(
`[${streamingTaskId}] Status Update: ${statusEvent.status.state} - ${
statusEvent.status.message?.parts[0]?.text ?? "No message"
}`
);
if (statusEvent.final) {
console.log(`[${streamingTaskId}] Stream marked as final.`);
break; // Exit loop when server signals completion
}
} else if ("artifact" in event) {
// It's a TaskArtifactUpdateEvent
const artifactEvent = event as TaskArtifactUpdateEvent; // Cast for clarity
console.log(
`[${streamingTaskId}] Artifact Update: ${
artifactEvent.artifact.name ??
`Index ${artifactEvent.artifact.index}`
} - Part Count: ${artifactEvent.artifact.parts.length}`
);
// Process artifact content (e.g., artifactEvent.artifact.parts[0].text)
} else {
console.warn("Received unknown event structure:", event);
}
}
console.log(`--- Streaming task ${streamingTaskId} finished ---`);
} catch (error) {
console.error(`Error during streaming task ${streamingTaskId}:`, error);
}
}
streamTask();
运行Coder示例
Coder示例是A2A代理的一个示例实现,可以处理与代码相关的任务。
设置
- 1. 安装依赖项:
git clone https://github.com/sing1ee/a2a-agent-coder.git
#or
git clone git@github.com:sing1ee/a2a-agent-coder.git
bun install
- 2. 确保您有所需的环境变量:
# set .env first
export $(cat .env | xargs)
运行示例
- 1. 启动a2a服务器(需要Node.js环境):
bun run agents:coder
- 2. 启动a2a客户端:
bun run a2a:cli
# result
$ bun x tsx src/cli.ts
A2A Terminal Client
Agent URL: http://localhost:41241
Attempting to fetch agent card from: http://localhost:41241/.well-known/agent.json
✓ Agent Card Found:
Name: Coder Agent
Description: An agent that generates code based on natural language instructions and streams file outputs.
Version: 0.0.1
Starting Task ID: a1a608b3-3015-4404-a83f-6ccc05083761
Enter messages, or use '/new' to start a new task.
Coder Agent > You: implement binary search
Sending...
Coder Agent [4:28:00 PM]: ⏳ Status: working
Part 1: 📝 Text: Generating code...
Coder Agent [4:28:02 PM]: ⏳ Status: working
Part 1: 📄 File: Name: src/algorithms/binary_search.py, Source: """
Implementation of the binary search algorithm in Python.
"""
def binary_search(arr, target):
"""
Performs a binary search on a sorted array to find the index of a target value.
Args:
arr (list): A sorted list of elements.
target: The value to search for in the array.
Returns:
int: The index of the target value if found, otherwise -1.
"""
low = 0
high = len(arr) - 1
while low <= high:
mid = (low + high) // 2 # Integer division to find the middle index
if arr[mid] == target:
return mid # Target found at index mid
elif arr[mid] < target:
low = mid + 1 # Target is in the right half
else:
high = mid - 1 # Target is in the left half
return -1 # Target not found in the array
Coder Agent [4:28:02 PM]: ✅ Status: completed
SSE stream finished for method tasks/sendSubscribe.
--- End of response for this input ---
Coder Agent > You:
Exiting terminal client. Goodbye!
错误处理
A2A协议定义了几个标准错误代码:
- •
-32700
:解析错误 - •
-32600
:无效请求 - •
-32601
:方法未找到 - •
-32602
:无效参数 - •
-32603
:内部错误 - •
-32000
:任务未找到 - •
-32001
:任务不可取消 - •
-32002
:不支持推送通知 - •
-32003
:不支持的操作
最佳实践
- 1. 错误处理:始终为所有A2A协议方法实现适当的错误处理
- 2. 身份验证:实现适当的身份验证机制以确保安全通信
- 3. 任务管理:维护适当的任务状态管理和清理
- 4. 推送通知:在支持时实现推送通知以获取实时更新
- 5. 日志记录:实现全面的日志记录以便调试和监控
其他资源
- • JSON-RPC 2.0规范
- • A2A协议模式
- • 服务器实现
- • 客户端实现
- • Coder代理实现