尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
在 Cloudflare Agents 上构建 A2A 协议服务器:Agent Card 发现、JSON-RPC 传输与 SSE 流式示例全解析
在 Cloudflare Agents 上构建 A2A 协议服务器Agent Card 发现、JSON-RPC 传输与 SSE 流式示例全解析【免费下载链接】agentsBuild and deploy AI Agents on Cloudflare项目地址: https://gitcode.com/GitHub_Trending/agents1/agents本教程以examples/a2a示例为蓝本讲解如何把一个基于 Cloudflare Agents 框架构建的 AI Agent 暴露为标准 A2AAgent-to-Agent协议服务器并配套一个浏览器端的 A2A 客户端 UI。读完本文你将掌握 A2A Agent Card 发现机制、基于a2a-js/sdk的 JSON-RPC 传输与 SSE 流式推送、以及用 Durable Object SQLite 持久化任务状态的完整实战方案。示例概览Cloudflare Agent 如何成为 A2A 服务器examples/a2a是 Cloudflare Agents 仓库中一个端到端的 A2A 示例它的核心思路非常清晰复用 SDK 而不是手写协议。服务器端使用a2a-js/sdk提供的DefaultRequestHandler与JsonRpcTransportHandler组装协议处理链开发者只需要关心两件事——任务怎么执行实现AgentExecutor和任务状态存哪里实现TaskStore。该示例集中展示了以下五项能力与 README 一一对应Agent Card 发现在/.well-known/agent-card.json提供标准化的 Agent 元数据协议版本、能力、技能、端点 URL 等任何 A2A 客户端都能先发现、再交互JSON-RPC 传输通过a2a-js/sdk服务器端实现message/send与message/stream两种方法SSE 流式推送message/stream的返回以text/event-stream形式实时推送任务状态更新用户能看到提交 → 工作中 → 完成的全过程DO-backed TaskStore使用 Durable Object SQLite 作为任务持久化存储任务状态跨请求可恢复Workers AI 真实推理AI 响应由 Cloudflare Workers AI 提供Agent Card 描述中标注为 GLM 4.7 Flash而server.ts源码实际调用的是cf/moonshotai/kimi-k2.7-code模型。快速运行三行命令跑通完整链路在examples/a2a目录下执行npm install npm startnpm start实际运行的是vite dev见 package.json通过cloudflare/vite-plugin在本地同时拉起 Worker 与前端静态资源。启动后打开 http://localhost:5173 即可使用聊天 UI。任何 A2A 客户端都可以先通过 Agent Card 发现这个 Agentcurl http://localhost:5173/.well-known/agent-card.json该端点同时支持.well-known/agent-card.json与.well-known/agent.json两个路径见 server.ts返回的 Agent Card 带有Access-Control-Allow-Origin: *头便于跨域客户端读取。Agent Card 中的url字段指向http://localhost:5173/a2a即 JSON-RPC 端点。生产部署使用npm run deploy等价于vite build wrangler deploy。关键模式DefaultRequestHandler AgentExecutor不手写协议这是整个示例最值得借鉴的设计。A2A 协议本身包含 JSON-RPC 信封、方法分发、参数校验、SSE 流式封装等一系列样板逻辑手写很容易出错。示例直接使用 SDK 的服务器端组件把协议层与业务层解耦const handler new DefaultRequestHandler(agentCard, taskStore, executor); const transport new JsonRpcTransportHandler(handler);DefaultRequestHandler接收三个参数Agent Card协议元数据、TaskStore任务持久化实现、AgentExecutor实际执行任务的业务逻辑。它负责解析 JSON-RPC 请求、分发到message/send/message/stream/message/cancel等方法JsonRpcTransportHandler负责处理 JSON-RPC 2.0 信封与序列化业务方只需实现AgentExecutor接口通过ExecutionEventBus发布生命周期事件。在 MyA2A 构造函数 中可以看到三者的组装方式export class MyA2A extends AgentEnv { constructor(ctx: DurableObjectState, env: Env) { super(ctx, env); const taskStore new DurableObjectTaskStore(ctx.storage.sql); const executor new AIAgentExecutor(() this.env); this.handler new DefaultRequestHandler(agentCard, taskStore, executor); this.transport new JsonRpcTransportHandler(this.handler); } }MyA2A继承自agents框架的AgentEnv基类因此天然具备 Durable Object 的持久化能力ctx.storage.sql可以直接拿来做任务存储。AgentExecutor用事件总线表达任务生命周期AIAgentExecutor完整展示了 A2A 任务的状态机流转。它利用ExecutionEventBus依次发布submitted→working→ AI 响应消息→completed事件class AIAgentExecutor implements AgentExecutor { async execute(ctx: RequestContext, bus: ExecutionEventBus) { // 新任务先发布 submitted 状态 if (!task) { bus.publish({ id: taskId, contextId, history: [userMessage], kind: task, status: { state: submitted, timestamp: ... } }); } // 发布 working 状态 bus.publish({ kind: status-update, status: { state: working, ... }, ... }); // 调用 Workers AI const result await generateText({ model, messages }); // 发布 agent 回复消息 bus.publish({ kind: message, role: agent, parts: [{ kind: text, text: result.text }], ... }); // 发布 completed 状态final: true携带回复消息 bus.publish({ kind: status-update, final: true, status: { state: completed, message: responseMessage }, ... }); bus.finished(); } cancelTask async (): Promisevoid {}; }要点在于status-update事件的final: true标记任务终结同时可携带message字段把最终回复一并推送bus.finished()通知执行流结束。cancelTask在示例中是空实现生产环境中应在此实现任务取消逻辑。AI 调用workers-ai-provider Vercel AI SDKAI 推理部分没有直接调用 Workers AI 的 REST API而是用workers-ai-provider把它适配为 Vercel AI SDK 的模型接口再交给generateTextconst workersai createWorkersAI({ binding: this.getEnv().AI }); const result await generateText({ model: workersai(cf/moonshotai/kimi-k2.7-code), instructions: You are a helpful AI assistant. Keep responses concise and clear., messages: [{ role: user, content: userText }] });用户消息中的文本通过过滤parts中kind text的部分拼接而成见 server.ts这也体现了 A2AMessage多模态 parts 结构的使用方式。任务持久化Durable Object SQLite 版 TaskStoreA2A 协议要求任务状态可查询、可恢复因此TaskStore必须有真实的存储后端。示例给出了一个仅 20 余行的最小实现DurableObjectTaskStore见 server.ts直接构建在 Durable Object 的 SQLite 之上class DurableObjectTaskStore implements TaskStore { constructor(private sql: SqlStorage) { this.sql.exec( CREATE TABLE IF NOT EXISTS a2a_tasks ( id TEXT PRIMARY KEY, data TEXT NOT NULL ) ); } async save(task: Task): Promisevoid { this.sql.exec( INSERT OR REPLACE INTO a2a_tasks (id, data) VALUES (?, ?), task.id, JSON.stringify(task) ); } async load(taskId: string): PromiseTask | undefined { const rows [...this.sql.exec(SELECT data FROM a2a_tasks WHERE id ?, taskId)]; if (rows.length 0) return undefined; return JSON.parse(rows[0].data as string) as Task; } }整个 Task 对象被整体序列化为 JSON 存入单表id为主键、INSERT OR REPLACE实现幂等更新。schema 在构造函数中通过CREATE TABLE IF NOT EXISTS自举创建无需额外的迁移脚本。得益于 Durable Object 的持久化特性即使 Worker 重启任务状态也能从 SQLite 中恢复——这正是 Agent Card 中stateTransitionHistory: true能力声明的基础。路由与传输Agent 内部如何分发请求MyA2A的onRequest方法是协议入口完整覆盖三条路径见 server.tsAgent Card 发现GET /.well-known/agent-card.json或/.well-known/agent.json返回handler.getAgentCard()CORS 预检OPTIONS请求返回允许POST, OPTIONS与Content-Type头的响应头JSON-RPC 端点POST请求交给transport.handle(body)。handle的返回值有两种情况需要分别处理非流式结果直接Response.json(result)返回异步可迭代结果message/stream的场景将异步生成器逐个事件编码为 SSE 格式id: ...\ndata: ...\n\n通过TransformStream以text/event-stream响应头返回并设置Cache-Control: no-cache防止中间层缓存。顶层 Worker 入口则负责把 A2A 相关路径路由到 Durable Object 实例export default { async fetch(request: Request, env: Env) { const url new URL(request.url); if (url.pathname.startsWith(/.well-known/) || url.pathname /a2a) { const agent await getAgentByName(env.MyA2A, default); return agent.fetch(request); } return new Response(Not found, { status: 404 }); } } satisfies ExportedHandlerEnv;getAgentByName是agents框架提供的路由助手实现位于 packages/agents/src/agent-routing.ts它根据命名空间与实例名返回初始化后的 Agent stub这里把 default 单例实例作为 A2A 服务器的承载者。其余请求直接 404静态资源则由 Vite 插件托管。浏览器端 A2A 客户端零 SDK 依赖的轻量实现client.tsx展示了一个不打包 SDK、直接用 fetch 实现的 A2A 客户端非常适合理解协议本质。整个客户端分为三层1. Agent Card 发现组件挂载后先请求同源的/.well-known/agent-card.jsonasync function fetchAgentCard(baseUrl: string): PromiseAgentCard { const res await fetch(${baseUrl}/.well-known/agent-card.json); if (!res.ok) throw new Error(Failed to fetch agent card: ${res.status}); return res.json(); }拿到 Agent Card 后UI 会渲染协议版本徽章、Streaming 能力徽章、skills 列表以及 JSON-RPC 端点 URL见 client.tsx。2. 非流式发送 message/sendsendMessage构造标准 JSON-RPC 2.0 信封调用message/send方法const res await fetch(url, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ jsonrpc: 2.0, id: crypto.randomUUID(), method: message/send, params: { message } }) });3. 流式接收 message/streamstreamMessage是一个异步生成器负责解析 SSE 流按\n\n切分事件块、提取data:前缀的 JSON 负载并将result字段逐个yield出去。由于 SSE 事件可能被 TCP 分片截断实现里维护了一个buffer变量处理粘包见 client.tsx。客户端根据 Agent Card 的capabilities.streaming决定走哪条路径支持流式时先用占位气泡展示 Thinking... 状态再随事件流不断刷新文本与状态徽章不支持时回退到message/send。流式事件中kind为messageagent 回复、status-update状态变更status.message可能携带最终回复、task完整任务对象三种类型都会被消费这也完整对应了服务器端ExecutionEventBus发布的事件种类。配置解读wrangler.jsonc 的四个关键点示例的 Worker 配置集中在 wrangler.jsonc理解它才能顺利部署到生产环境配置项值作用mainsrc/server.tsWorker 入口即上面导出的fetch与MyA2A类compatibility_date/compatibility_flags2026-06-11/[nodejs_compat]兼容性日期与 Node.js 兼容层a2a-js/sdk等依赖可能用到 Node APIai.bindingAIremote: true声明 Workers AI 绑定对应env.AI见 env.d.tsdurable_objects.bindings类名与绑定名均为MyA2A注册 Durable Object 命名空间migrationsnew_sqlite_classes: [MyA2A]tagv1声明 MyA2A 使用SQLite存储这是ctx.storage.sql可用的前提assetsSPA 模式 run_worker_first: [/.well-known/*, /a2a]静态资源走单页应用回退同时保证 A2A 相关路径优先由 WorkerDurable Object处理assets.run_worker_first尤其关键它保证/.well-known/*与/a2a的请求先进入 Worker 路由而不会命中前端 SPA 的回退页面。vite.config.ts中的cloudflare()插件见 vite.config.ts正是依赖这份配置在本地模拟上述运行时环境。与其他示例的衔接该示例与仓库中另一个 AI Chat 示例 形成对照后者使用cloudflare/ai-chat构建同类 AI Agent而 A2A 示例强调的是协议互操作性——遵循 A2A 标准的任意客户端不仅是本示例自带的 UI都能发现并调用该 Agent。当你需要把自己的 Agent 接入更大的 Agent 生态时本文的DefaultRequestHandler AgentExecutor DO TaskStore模式就是一条经过验证的实现路径。小结回顾整个示例值得沉淀的三个工程要点是第一协议逻辑交给 SDK业务方只实现AgentExecutor与TaskStore两个接口即可获得完整的 A2A 服务器能力第二任务生命周期通过事件总线显式表达submitted → working → completed的状态流转天然适配 SSE 实时推送第三Durable Object SQLite 作为默认持久层让任务状态具备跨请求的可恢复性同时new_sqlite_classes迁移声明让整个过程零额外基础设施。【免费下载链接】agentsBuild and deploy AI Agents on Cloudflare项目地址: https://gitcode.com/GitHub_Trending/agents1/agents创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

钢铁ERP关键用户培训手册:从业务流程到SOP的实战编写指南

钢铁ERP关键用户培训手册:从业务流程到SOP的实战编写指南

简介:这是一份某钢铁集团ERP关键用户培训使用手册,系达钢ERP项目中的正式交付文档,面向企业内ERP关键用户、财务及供应链岗位人员,帮助其掌握用友NC客户端的配置、登录、主界面操作、单据状态与基础数据设置等核心技能。资源共1个…

📅 2026/9/18 8:44:45
Cherry Studio 性能工程:Barrel 文件聚合入口导入为何是 CRITICAL 级陷阱,以及它的工程化落地

Cherry Studio 性能工程:Barrel 文件聚合入口导入为何是 CRITICAL 级陷阱,以及它的工程化落地

Cherry Studio 性能工程:Barrel 文件聚合入口导入为何是 CRITICAL 级陷阱,以及它的工程化落地 【免费下载链接】cherry-studio 🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端 项目地址: https://gitcode.com/CherryHQ/cherry-st…

📅 2026/9/18 8:44:45
用 Claude Code 构建实时加密市场数据 Subagent:crypto-market-agent-sonnet 完整实战指南

用 Claude Code 构建实时加密市场数据 Subagent:crypto-market-agent-sonnet 完整实战指南

用 Claude Code 构建实时加密市场数据 Subagent:crypto-market-agent-sonnet 完整实战指南 【免费下载链接】claude-code-hooks-mastery Master Claude Code Hooks 项目地址: https://gitcode.com/GitHub_Trending/cl/claude-code-hooks-mastery 本文以当前仓…

📅 2026/9/18 8:44:45
MORE NEWS

更多资讯

📰

人授权、AI执行:基于BIP 6的智能体工程化实践

如果你也管着一个几十人的团队,一定体会过每天被“派活”支配的感觉:任务从聊天窗口里来,在表格里传递,在口头确认中丢失。半年前,我们团队把“派活”这件事搬进了BIP 6平台,逐步搭起一套“人授权、AI执行”…

📰

抖音无水印批量下载安装教程:从克隆仓库到跑通第一个任务

抖音无水印批量下载安装教程:从克隆仓库到跑通第一个任务 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback su…

📰

动态网页仪表盘不自动刷新?TaoToken 这样改 Codex 的排查路径再对照 glue_get_state

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Altium Designer高效快捷键指南:从原理图到PCB布线提速技巧

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

制造业AI落地施工图:工业互联网+边缘智能实施指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

PDF压缩原理与场景化实战:保真、降体积、不丢功能

1. 这不是“随便找个PDF压缩网站就行”的事——为什么90%的人压完PDF反而更卡、更糊、打不开你搜“压缩pdf免费工具”,页面刷出来几十个带“极速”“秒压”“无损”字样的网站,点进去上传文件,等30秒,下载回来——结果字体发虚、表…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬