
目录
- 什么是 A2A JS SDK?
- A2A JS 安装与设置
- A2A JS 核心概念
- 创建你的第一个 A2A JS 代理
- A2A JS 服务端开发
- A2A JS 客户端使用
- A2A JS 高级特性
- A2A JS 最佳实践
- A2A JS 故障排除
什么是 A2A JS SDK?
A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库,用于构建符合 Agent2Agent (A2A) 协议 的智能代理应用程序。这个 A2A JS 框架让开发者能够轻松创建能够相互通信和协作的智能代理系统。
A2A JS 的核心优势
- 🚀 简单易用: A2A JS 提供直观的 API,让开发者能快速上手
- 🔄 实时通信: 支持流式处理和服务端推送事件 (SSE)
- 🛡️ 类型安全: 基于 TypeScript 构建,提供完整的类型支持
- 🌐 跨平台: A2A JS 可在 Node.js 和浏览器环境中运行
- 📡 标准协议: 完全实现 A2A 协议规范
A2A JS 安装与设置
安装 A2A JS SDK
使用 npm 安装 A2A JS SDK:
npm install @a2a-js/sdk
或者使用 yarn:
yarn add @a2a-js/sdk
验证 A2A JS 安装
创建一个简单的测试文件来验证 A2A JS 是否正确安装:
import { A2AClient, AgentCard } from "@a2a-js/sdk";
console.log("A2A JS SDK 安装成功!");
A2A JS 核心概念
在开始使用 A2A JS 之前,了解以下核心概念很重要:
1. Agent Card (代理卡片)
A2A JS 中的每个代理都需要一个 Agent Card,它描述了代理的能力和接口:
import { AgentCard } from "@a2a-js/sdk";
const agentCard: AgentCard = {
name: 'My A2A JS Agent',
description: '使用 A2A JS SDK 构建的智能代理',
url: 'http://localhost:3000/',
provider: {
organization: 'A2A JS Developers',
url: 'https://example.com'
},
version: '1.0.0',
capabilities: {
streaming: true,
pushNotifications: false,
stateTransitionHistory: true,
},
skills: [{
id: 'general_chat',
name: '通用对话',
description: '使用 A2A JS 进行通用对话',
tags: ['chat', 'a2a-js'],
examples: ['你好', '帮我解答问题']
}]
};
2. Agent Executor (代理执行器)
A2A JS 的核心执行逻辑通过 AgentExecutor 实现:
import { AgentExecutor, RequestContext, IExecutionEventBus } from "@a2a-js/sdk";
class MyA2AJSExecutor implements AgentExecutor {
async execute(
requestContext: RequestContext,
eventBus: IExecutionEventBus
): Promise<void> {
// 你的 A2A JS 代理逻辑
console.log("A2A JS 代理正在处理请求...");
}
async cancelTask(taskId: string, eventBus: IExecutionEventBus): Promise<void> {
console.log(`A2A JS 取消任务: ${taskId}`);
}
}
创建你的第一个 A2A JS 代理
让我们使用 A2A JS SDK 创建一个完整的代理示例:
步骤 1: 定义 A2A JS 代理卡片
import { AgentCard } from "@a2a-js/sdk";
const myAgentCard: AgentCard = {
name: 'Hello World A2A JS Agent',
description: '我的第一个 A2A JS 代理,用于学习 A2A JS SDK',
url: 'http://localhost:3000/',
provider: {
organization: 'A2A JS Tutorial',
url: 'https://example.com'
},
version: '1.0.0',
capabilities: {
streaming: true,
pushNotifications: false,
stateTransitionHistory: true,
},
defaultInputModes: ['text/plain'],
defaultOutputModes: ['text/plain'],
skills: [{
id: 'hello_world',
name: 'Hello World',
description: 'A2A JS 示例技能:回复问候',
tags: ['hello', 'greeting', 'a2a-js'],
examples: [
'你好',
'Hello',
'介绍一下 A2A JS'
],
inputModes: ['text/plain'],
outputModes: ['text/plain']
}],
supportsAuthenticatedExtendedCard: false,
};
步骤 2: 实现 A2A JS 执行器
import {
AgentExecutor,
RequestContext,
IExecutionEventBus,
Task,
TaskState,
TaskStatusUpdateEvent
} from "@a2a-js/sdk";
import { v4 as uuidv4 } from "uuid";
class HelloWorldA2AJSExecutor implements AgentExecutor {
private cancelledTasks = new Set<string>();
async cancelTask(taskId: string, eventBus: IExecutionEventBus): Promise<void> {
this.cancelledTasks.add(taskId);
console.log(`A2A JS 执行器取消任务: ${taskId}`);
}
async execute(
requestContext: RequestContext,
eventBus: IExecutionEventBus
): Promise<void> {
const userMessage = requestContext.userMessage;
const existingTask = requestContext.task;
const taskId = existingTask?.id || uuidv4();
const contextId = userMessage.contextId || existingTask?.contextId || uuidv4();
console.log(`A2A JS 代理处理消息: ${userMessage.parts[0]?.text}`);
// 创建新任务
if (!existingTask) {
const initialTask: Task = {
kind: 'task',
id: taskId,
contextId: contextId,
status: {
state: TaskState.Submitted,
timestamp: new Date().toISOString(),
},
history: [userMessage],
metadata: userMessage.metadata,
artifacts: [],
};
eventBus.publish(initialTask);
}
// 发布工作状态
const workingUpdate: TaskStatusUpdateEvent = {
kind: 'status-update',
taskId: taskId,
contextId: contextId,
status: {
state: TaskState.Working,
message: {
kind: 'message',
role: 'agent',
messageId: uuidv4(),
parts: [{ kind: 'text', text: 'A2A JS 代理正在思考...' }],
taskId: taskId,
contextId: contextId,
},
timestamp: new Date().toISOString(),
},
final: false,
};
eventBus.publish(workingUpdate);
// 模拟处理时间
await new Promise(resolve => setTimeout(resolve, 1000));
// 检查取消状态
if (this.cancelledTasks.has(taskId)) {
const cancelledUpdate: TaskStatusUpdateEvent = {
kind: 'status-update',
taskId: taskId,
contextId: contextId,
status: {
state: TaskState.Canceled,
timestamp: new Date().toISOString(),
},
final: true,
};
eventBus.publish(cancelledUpdate);
return;
}
// 生成响应
const userText = userMessage.parts[0]?.text || '';
let responseText = '';
if (userText.toLowerCase().includes('hello') || userText.includes('你好')) {
responseText = `你好!欢迎使用 A2A JS SDK!我是用 A2A JS 构建的智能代理。`;
} else if (userText.toLowerCase().includes('a2a js')) {
responseText = `A2A JS SDK 是一个强大的 JavaScript 库,用于构建智能代理应用程序!`;
} else {
responseText = `我是一个 A2A JS 代理,收到了你的消息:"${userText}"。感谢使用 A2A JS SDK!`;
}
// 发布最终结果
const finalUpdate: TaskStatusUpdateEvent = {
kind: 'status-update',
taskId: taskId,
contextId: contextId,
status: {
state: TaskState.Completed,
message: {
kind: 'message',
role: 'agent',
messageId: uuidv4(),
parts: [{ kind: 'text', text: responseText }],
taskId: taskId,
contextId: contextId,
},
timestamp: new Date().toISOString(),
},
final: true,
};
eventBus.publish(finalUpdate);
}
}
步骤 3: 启动 A2A JS 服务器
import express from 'express';
import {
A2AExpressApp,
DefaultRequestHandler,
InMemoryTaskStore
} from "@a2a-js/sdk";
const taskStore = new InMemoryTaskStore();
const agentExecutor = new HelloWorldA2AJSExecutor();
const requestHandler = new DefaultRequestHandler(
myAgentCard,
taskStore,
agentExecutor
);
const appBuilder = new A2AExpressApp(requestHandler);
const expressApp = appBuilder.setupRoutes(express(), '');
const PORT = process.env.PORT || 3000;
expressApp.listen(PORT, () => {
console.log(`A2A JS 代理服务器启动在 http://localhost:${PORT}`);
console.log(`A2A JS 代理卡片: http://localhost:${PORT}/.well-known/agent.json`);
console.log('按 Ctrl+C 停止 A2A JS 服务器');
});
A2A JS 服务端开发
任务存储
A2A JS 提供了内存任务存储,你也可以实现自定义存储:
import { TaskStore, Task } from "@a2a-js/sdk";
class CustomA2AJSTaskStore implements TaskStore {
private tasks = new Map<string, Task>();
async getTask(taskId: string): Promise<Task | undefined> {
console.log(`A2A JS 获取任务: ${taskId}`);
return this.tasks.get(taskId);
}
async setTask(task: Task): Promise<void> {
console.log(`A2A JS 保存任务: ${task.id}`);
this.tasks.set(task.id, task);
}
async deleteTask(taskId: string): Promise<void> {
console.log(`A2A JS 删除任务: ${taskId}`);
this.tasks.delete(taskId);
}
}
中间件支持
A2A JS 基于 Express.js,支持所有标准中间件:
import cors from 'cors';
import express from 'express';
const app = express();
// A2A JS 服务器中间件配置
app.use(cors());
app.use(express.json());
// 自定义 A2A JS 日志中间件
app.use((req, res, next) => {
console.log(`A2A JS 请求: ${req.method} ${req.path}`);
next();
});
A2A JS 客户端使用
基础客户端操作
import { A2AClient, MessageSendParams } from "@a2a-js/sdk";
import { v4 as uuidv4 } from "uuid";
const client = new A2AClient("http://localhost:3000");
async function testA2AJSClient() {
console.log("测试 A2A JS 客户端...");
const messageParams: MessageSendParams = {
message: {
messageId: uuidv4(),
role: "user",
parts: [{ kind: "text", text: "你好,A2A JS!" }],
kind: "message"
},
configuration: {
blocking: true,
acceptedOutputModes: ['text/plain']
}
};
try {
const response = await client.sendMessage(messageParams);
if (response.error) {
console.error("A2A JS 客户端错误:", response.error);
return;
}
console.log("A2A JS 响应:", response.result);
} catch (error) {
console.error("A2A JS 通信错误:", error);
}
}
testA2AJSClient();
A2A JS 流式处理
A2A JS 支持实时流式通信:
import { A2AClient, TaskStatusUpdateEvent } from "@a2a-js/sdk";
async function streamA2AJSResponse() {
const client = new A2AClient("http://localhost:3000");
console.log("开始 A2A JS 流式处理...");
const streamParams = {
message: {
messageId: uuidv4(),
role: "user",
parts: [{ kind: "text", text: "使用 A2A JS 进行流式对话" }],
kind: "message"
}
};
try {
const stream = client.sendMessageStream(streamParams);
for await (const event of stream) {
if (event.kind === 'task') {
console.log(`A2A JS 任务创建: ${event.id}`);
} else if (event.kind === 'status-update') {
const statusEvent = event as TaskStatusUpdateEvent;
console.log(`A2A JS 状态更新: ${statusEvent.status.state}`);
if (statusEvent.status.message?.parts[0]?.text) {
console.log(`A2A JS 消息: ${statusEvent.status.message.parts[0].text}`);
}
if (statusEvent.final) {
console.log("A2A JS 流式处理完成");
break;
}
}
}
} catch (error) {
console.error("A2A JS 流式处理错误:", error);
}
}
A2A JS 高级特性
工件处理
A2A JS 支持工件(Artifacts)的创建和管理:
import { TaskArtifactUpdateEvent } from "@a2a-js/sdk";
// 在 AgentExecutor 中发布工件
const artifactUpdate: TaskArtifactUpdateEvent = {
kind: 'artifact-update',
taskId: taskId,
contextId: contextId,
artifact: {
artifactId: "a2a-js-example",
name: "A2A JS 示例文件",
parts: [{
text: `# A2A JS 生成的内容\n\n这是使用 A2A JS SDK 生成的示例文件。`
}],
},
append: false,
lastChunk: true,
};
eventBus.publish(artifactUpdate);
安全配置
为 A2A JS 代理配置安全选项:
const secureAgentCard: AgentCard = {
name: 'Secure A2A JS Agent',
description: '安全的 A2A JS 代理',
// ... 其他配置
securitySchemes: {
apiKey: {
type: 'apiKey',
name: 'X-API-Key',
in: 'header'
}
},
security: [{
apiKey: []
}]
};
A2A JS 最佳实践
1. 错误处理
在 A2A JS 应用中实施全面的错误处理:
class RobustA2AJSExecutor implements AgentExecutor {
async execute(requestContext: RequestContext, eventBus: IExecutionEventBus) {
try {
// A2A JS 执行逻辑
await this.processRequest(requestContext, eventBus);
} catch (error) {
console.error("A2A JS 执行错误:", error);
// 发布错误状态
const errorUpdate: TaskStatusUpdateEvent = {
kind: 'status-update',
taskId: requestContext.task?.id || uuidv4(),
contextId: requestContext.userMessage.contextId || uuidv4(),
status: {
state: TaskState.Failed,
message: {
kind: 'message',
role: 'agent',
messageId: uuidv4(),
parts: [{ kind: 'text', text: 'A2A JS 处理时发生错误,请稍后重试。' }],
},
timestamp: new Date().toISOString(),
},
final: true,
};
eventBus.publish(errorUpdate);
}
}
}
2. 性能优化
优化你的 A2A JS 应用性能:
// 使用连接池优化 A2A JS 客户端
const client = new A2AClient("http://localhost:3000", {
keepAlive: true,
timeout: 30000
});
// A2A JS 代理响应缓存
class CachedA2AJSExecutor implements AgentExecutor {
private cache = new Map<string, string>();
async execute(requestContext: RequestContext, eventBus: IExecutionEventBus) {
const userText = requestContext.userMessage.parts[0]?.text || '';
const cacheKey = `a2a-js-${userText}`;
// 检查 A2A JS 缓存
if (this.cache.has(cacheKey)) {
console.log("A2A JS 使用缓存响应");
// 返回缓存的响应
}
// 处理新请求并缓存结果
}
}
3. 日志记录
为 A2A JS 应用添加详细的日志记录:
import { createLogger, format, transports } from 'winston';
const a2aJSLogger = createLogger({
level: 'info',
format: format.combine(
format.timestamp(),
format.printf(({ timestamp, level, message }) => {
return `[A2A JS] ${timestamp} ${level}: ${message}`;
})
),
transports: [
new transports.Console(),
new transports.File({ filename: 'a2a-js.log' })
]
});
// 在 A2A JS 代码中使用
a2aJSLogger.info('A2A JS 代理启动成功');
a2aJSLogger.error('A2A JS 处理错误', { error: errorDetails });
A2A JS 故障排除
常见问题解决
1. A2A JS 连接问题
// 检查 A2A JS 服务器连接
async function checkA2AJSConnection() {
try {
const client = new A2AClient("http://localhost:3000");
const response = await fetch("http://localhost:3000/.well-known/agent.json");
if (response.ok) {
console.log("A2A JS 服务器连接正常");
} else {
console.error("A2A JS 服务器响应异常:", response.status);
}
} catch (error) {
console.error("A2A JS 连接失败:", error);
}
}
也可以尝试如下方法:
- A2A 协议验证器
- 指南: 如何验证您的代理卡片
2. A2A JS 类型错误
确保正确导入 A2A JS 类型:
// 正确的 A2A JS 类型导入
import {
AgentCard,
AgentExecutor,
A2AClient,
Task,
TaskState,
Message,
MessageSendParams
} from "@a2a-js/sdk";
3. A2A JS 性能调试
// A2A JS 性能监控
class PerformanceA2AJSExecutor implements AgentExecutor {
async execute(requestContext: RequestContext, eventBus: IExecutionEventBus) {
const startTime = Date.now();
console.log(`A2A JS 开始处理: ${startTime}`);
try {
// 你的 A2A JS 逻辑
await this.processRequest(requestContext, eventBus);
} finally {
const endTime = Date.now();
console.log(`A2A JS 处理完成,耗时: ${endTime - startTime}ms`);
}
}
}
总结
A2A JS SDK 是构建智能代理应用程序的强大工具。通过本教程,你已经学习了:
- A2A JS 的核心概念和架构
- 如何创建和配置 A2A JS 代理
- A2A JS 服务端和客户端开发
- A2A JS 的高级特性和最佳实践
- A2A JS 应用的故障排除方法
现在你可以开始构建自己的 A2A JS 应用程序了!记住,A2A JS SDK 提供了丰富的功能来帮助你创建强大、可扩展的智能代理系统。
如需更多 A2A JS 资源和示例,请访问:
开始你的 A2A JS 开发之旅吧!🚀
Related Articles
Explore more content related to this topic
A2A JS Sample: Movie Agent
Movie information agent using A2A Protocol with TMDB API, OpenRouter AI integration, and Express.js server.
A2A Protocol Development Guide(TypeScript)
Master the A2A Protocol with this detailed TypeScript guide. Learn to build robust agent communication systems, implement JSON-RPC based messaging, and handle real-time updates with practical examples.
A2UI Introduction - Declarative UI Protocol for Agent-Driven Interfaces
Discover A2UI, the declarative UI protocol that enables AI agents to generate rich, interactive user interfaces. Learn how A2UI works, who it's for, how to use it, and see real-world examples from Google Opal, Gemini Enterprise, and Flutter GenUI SDK.
Agent Gateway Protocol (AGP): Practical Tutorial and Specification
Learn the Agent Gateway Protocol (AGP): what it is, problems it solves, core spec (capability announcements, intent payloads, routing and error codes), routing algorithm, and how to run a working simulation.
Integrating A2A Protocol - Intelligent Agent Communication Solution for BeeAI Framework
Using A2A protocol instead of ACP is a better choice for BeeAI, reducing protocol fragmentation and improving ecosystem integration.