A2A JS SDK 完整教程:快速入门指南
目录
- 什么是 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) 协议 的智能代理应用程序。这个 AA2A 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-sdk
或者使用 yarn:
yarn add a2a-sdk
验证 A2A JS 安装
创建一个简单的测试文件来验证 A2A JS 是否正确安装:
import { A2AClient, AgentCard } from "a2a-sdk";console.log("A2A JS SDK 安装成功!");
A2A JS 核心概念
在开始使用 A2A JS 之前,了解以下核心概念很重要:
1. Agent Card (代理卡片)
A2A JS 中的每个代理都需要一个 Agent Card,它描述了代理的能力和接口:
import { AgentCard } from "a2a-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-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-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-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-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-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-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-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-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-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 GitHub 仓库
- A2A JS 示例项目
- A2A 协议文档
开始你的 A2A JS 开发之旅吧!🚀
A2A JS