目录
- [什么是 A2A JS SDK?](#什么是 A2A JS SDK?)
- [A2A JS 安装与设置](#A2A JS 安装与设置)
- [A2A JS 核心概念](#A2A JS 核心概念)
- [创建你的第一个 A2A JS 代理](#创建你的第一个 A2A JS 代理)
- [A2A JS 服务端开发](#A2A JS 服务端开发)
- [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:
bash
npm install a2a-sdk
或者使用 yarn:
bash
yarn add a2a-sdk
验证 A2A JS 安装
创建一个简单的测试文件来验证 A2A JS 是否正确安装:
typescript
import { A2AClient, AgentCard } from "a2a-sdk";
console.log("A2A JS SDK 安装成功!");
A2A JS 核心概念
在开始使用 A2A JS 之前,了解以下核心概念很重要:
1. Agent Card (代理卡片)
A2A JS 中的每个代理都需要一个 Agent Card,它描述了代理的能力和接口:
typescript
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 实现:
typescript
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 代理卡片
typescript
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 执行器
typescript
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 服务器
typescript
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 提供了内存任务存储,你也可以实现自定义存储:
typescript
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,支持所有标准中间件:
typescript
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 客户端使用
基础客户端操作
typescript
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 支持实时流式通信:
typescript
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)的创建和管理:
typescript
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 代理配置安全选项:
typescript
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 应用中实施全面的错误处理:
typescript
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 应用性能:
typescript
// 使用连接池优化 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 应用添加详细的日志记录:
typescript
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 连接问题
typescript
// 检查 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 类型:
typescript
// 正确的 A2A JS 类型导入
import {
AgentCard,
AgentExecutor,
A2AClient,
Task,
TaskState,
Message,
MessageSendParams
} from "a2a-sdk";
3. A2A JS 性能调试
typescript
// 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 开发之旅吧!🚀