
OmniRoute A2A Server 接入指南通过 JSON-RPC 2.0 让 Agent 协作生态调用智能路由网关【免费下载链接】OmniRouteNever stop coding. Free MIT AI gateway: one endpoint, 352 providers (150 free), 1200 models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline Copilot. Quota-aware auto-fallback, RTKCaveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550 contributors项目地址: https://gitcode.com/GitHub_Trending/om/OmniRoute本篇指南对应仓库中的 A2A Server 文档阿塞拜疆语译本原文为 docs/frameworks/A2A-SERVER.md以该文档为骨架展开。OmniRoute 的 A2A Server 以Agent-to-Agent Protocol v0.3协议把整个 AI 网关封装成一个一等公民智能路由 Agent任何外部 AgentLangChain、CrewAI、AutoGen 或自定义编排器都可以通过 HTTP JSON-RPC 2.0 发现它的能力、向其委派任务、以 SSE 方式接收流式结果。读完本文你将掌握 Agent Card 发现、message/send/message/stream/tasks/get/tasks/cancel四大方法的调用、六个内置技能的使用以及任务生命周期、TTL、错误码与多语言集成实战。一、A2A 接口双面JSON-RPC 与 RESTA2A Server 在 OmniRoute 中暴露为两个互补的接口面来源src/app/a2a/route.tsJSON-RPC 2.0POST /a2a是协议层面规范化的唯一入口支持四个方法message/send、message/stream、tasks/get、tasks/cancelREST辅助/api/a2a/*面向 Dashboard 与外部运维工具提供状态、任务列表、取消等操作。在源码层面任务由A2ATaskManager统一管理src/lib/a2a/taskManager.ts默认 5 分钟 TTL技能通过A2A_SKILL_HANDLERS注册表分发src/lib/a2a/taskExecution.ts。A2A Server 的整体调用链如下摘自 src/lib/a2a/README.md编排 AgentLangChain / CrewAI / AutoGen / 自定义 Agent │ 1. GET /.well-known/agent.json 发现 │ 2. POST /a2a JSON-RPC 2.0 ▼ OmniRoute A2A Server ├─ Task Manager生命周期管理 ├─ Skill Engine技能注册表 └─ SSE Streaming实时流式 │ ▼ OmniRoute 网关内部 /v1/chat/completions、/api/combos、/api/usage/quota二、Agent 发现/.well-known/agent.json任何 A2A 兼容的 Agent 都应在/.well-known/agent.json暴露一张Agent Card描述自身能力、技能列表与认证要求。OmniRoute 的 Agent Card 通过如下命令获取curl http://localhost:20128/.well-known/agent.json返回的 Agent Card 结构包含name、description、url指向/a2a、version、capabilitiesstreaming: true、pushNotifications: false、skills数组以及authenticationschemes: [api-key]、apiKeyHeader: Authorization。从源码看src/app/.well-known/agent.json/route.tsAgent Card 是动态生成的version字段直接取自process.env.npm_package_version每次发版自动与package.json保持同步技能列表在静态声明的六个技能之外还会通过getFleetSkills()合并 OmniConductor 集群的 fleet skills缓存约 60 秒Hub 未配置或离线时返回空数组卡片仍然有效响应头携带Cache-Control: public, max-age3600即 Agent Card 可被客户端缓存 1 小时。三、启用开关与认证3.1 启用 A2AA2A 由Endpoints → A2A开关控制默认关闭。当功能被禁用时GET /api/a2a/status返回status: disabled与online: false向POST /a2a发起的 JSON-RPC 调用返回HTTP 503并携带错误码-32000A2A endpoint is disabled。对应的实现位于 src/app/a2a/route.ts 中的rejectIfA2ADisabled()每次请求都会读取设置settings.a2aEnabled非true时直接返回{ code: -32000, message: A2A endpoint is disabled. Enable it from the Endpoints page. }。3.2 Bearer 认证所有/a2a请求都需要通过Authorization请求头携带 API KeyAuthorization: Bearer YOUR_OMNIROUTE_API_KEY若服务器未配置任何 API Key则绕过认证本地优先的免密钥姿势。认证逻辑的细节src/lib/a2a/authenticate.ts按优先级依次判断若REQUIRE_API_KEY特性开关启用则必须是合法有效的 OmniRoute API KeyisValidApiKey校验否则若配置了OMNIROUTE_API_KEY则用timingSafeEqual恒定时间比较进行令牌比对规避时序侧信道攻击对应测试 tests/unit/a2a-auth-timing-safe.test.ts均未配置时直接放行。此外每个请求还会被解析出一个调用者 ownerAPI Key 的 SHA-256 前 32 位十六进制用于任务可见性的隔离带 owner 的任务只对同一 owner 可见而无 key 的本地模式创建的任务对所有调用者可见对应测试 tests/unit/a2a-task-owner-idor.test.ts。四、JSON-RPC 2.0 核心方法统一入口为POST http://localhost:20128/a2a请求体遵循 JSON-RPC 2.0 规范jsonrpc、id、method、params。4.1message/send— 同步执行向某个技能发送一条消息并等待完整响应curl -X POST http://localhost:20128/a2a \ -H Content-Type: application/json \ -H Authorization: Bearer YOUR_KEY \ -d { jsonrpc: 2.0, id: 1, method: message/send, params: { skill: smart-routing, messages: [{role: user, content: Write a hello world in Python}], metadata: {model: auto, combo: fast-coding} } }典型响应{ jsonrpc: 2.0, id: 1, result: { task: { id: uuid, state: completed }, artifacts: [{ type: text, content: ... }], metadata: { routing_explanation: Selected claude-sonnet via provider \anthropic\ (latency: 1200ms, cost: $0.003), cost_envelope: { estimated: 0.005, actual: 0.003, currency: USD }, resilience_trace: [ { event: primary_selected, provider: anthropic, timestamp: ... } ], policy_verdict: { allowed: true, reason: within budget and quota limits } } } }请求参数说明参数类型说明skillstring要调用的技能 ID缺省为smart-routingmessagesarray[{role, content}]消息数组也兼容message.content或message.parts[]旧式结构metadata.modelstring目标模型如claude-sonnet-4、gpt-4o、auto缺省autometadata.combostring指定要路由的组合combo缺省为当前激活组合metadata.budgetnumber本次请求的美元成本上限metadata.rolestring任务角色提示coding、review、planning、analysis、debugging、documentation返回字段说明字段说明task任务对象{id, state}artifacts[].contentLLM 响应文本metadata.routing_explanation路由决策的人类可读解释选了哪个模型、哪个提供者、延迟与成本metadata.cost_envelope预估成本与实际成本含币种metadata.resilience_trace弹性事件数组primary_selected、fallback_needed等metadata.policy_verdict请求是否被策略允许及原因在路由层src/app/a2a/route.tsmessage/send的处理流程是解析并规范化消息 → 按skill查找A2A_SKILL_HANDLERS中的处理器未知技能返回-32601→createTask创建任务 → 置为working→ 调用处理器 → 置为completed并附加 artifacts → 若是smart-routing技能还会通过logRoutingDecision记录路由决策日志provider、model、cost 等。4.2message/stream— SSE 流式执行与message/send参数完全相同但返回 Server-Sent Events实现实时流式输出curl -N -X POST http://localhost:20128/a2a \ -H Content-Type: application/json \ -H Authorization: Bearer YOUR_KEY \ -d { jsonrpc: 2.0, id: 1, method: message/stream, params: { skill: smart-routing, messages: [{role: user, content: Explain quantum computing}] } }SSE 事件序列data: {jsonrpc:2.0,method:message/stream,params:{task:{id:...,state:working},chunk:{type:text,content:...}}} : heartbeat 2026-03-03T17:00:00Z data: {jsonrpc:2.0,method:message/stream,params:{task:{id:...,state:completed},metadata:{...}}}流式实现细节src/lib/a2a/streaming.ts每15 秒发送一条: heartbeat注释事件维持长连接技能执行结果以chunk事件逐段下发对非流式技能做模拟流式切块完成时发送携带metadata的completed事件出错发送failed事件metadata.error响应头为Content-Type: text/event-stream、Cache-Control: no-cache, no-transform、Connection: keep-alive、X-Accel-Buffering: no支持通过req.signal的客户端中止abort来取消流。4.3tasks/get— 查询任务状态curl -X POST http://localhost:20128/a2a \ -H Content-Type: application/json \ -H Authorization: Bearer YOUR_KEY \ -d {jsonrpc:2.0,id:2,method:tasks/get,params:{taskId:TASK_UUID}}tasks/get支持params.taskId或兼容params.id返回任务完整对象含状态、事件日志与 artifacts。任务不存在返回-32601。4.4tasks/cancel— 取消任务curl -X POST http://localhost:20128/a2a \ -H Content-Type: application/json \ -H Authorization: Bearer YOUR_KEY \ -d {jsonrpc:2.0,id:3,method:tasks/cancel,params:{taskId:TASK_UUID}}取消成功返回{task: {id, state: cancelled}}。底层由A2ATaskManager.cancelTask执行取消前先做 owner 可见性校验且对他人任务与不存在任务统一返回相同的 not-found 错误防止 IDOR 探测。4.5 A2A 1.0 兼容层路由入口内置了v1.0 ↔ v0.3 兼容层A2A 1.0 将方法重命名为SendMessage/SendStreamingMessage并改变了同步响应结构1.0 客户端从task.status.message.parts[].text读取回复。OmniRoute 对 1.0 方法名做了别名映射并将 v0.3 的同步响应重新塑造成 1.0 的Task结构TASK_STATE_*状态枚举、ROLE_AGENT、parts[].text因此 a2a-sdk 1.x、Hermes 等 1.0 客户端可以原样调用对应测试 tests/unit/a2a-v1-compat-10839.test.ts。五、内置技能Available SkillsOmniRoute 的 A2A 服务注册了6 个技能全部在 src/lib/a2a/taskExecution.ts 的A2A_SKILL_HANDLERS中接线每个技能模块位于 src/lib/a2a/skills/。技能ID说明Tags示例Smart Routingsmart-routing通过 OmniRoute 的组合引擎 评分将提示词路由到最优提供者/组合routing, providersRoute this prompt via the best modelQuota Managementquota-management报告各提供者配额状态帮助调用方决定何时限流/切换quota, providersCheck quota for anthropicProvider Discoveryprovider-discovery列出已安装提供者及其能力、免费档位标记、OAuth 状态providers, discoveryWhat providers are available?Cost Analysiscost-analysis基于目录与近期用量估算请求/对话成本cost, usageEstimate cost for this conversationHealth Reporthealth-report按提供者聚合断路器、冷却、锁定状态health, resilienceShow health status of all providersList Capabilitieslist-capabilities以 Markdown 表格返回完整的 Agent Skills 目录23 个 API 21 个 CLI 1 个配置及原始 SKILL.md URLcatalog, discovery, skillsList all OmniRoute capabilities其中smart-routing与quota-management是核心技能smart-routing内部实现src/lib/a2a/skills/smartRouting.ts读取task.input.messages与metadata中的model缺省auto、combo、budget向网关内部/v1/chat/completions发起带model、messages、stream: false的请求combo通过x-combo请求头透传使用AbortSignal.timeout(30000)做 30 秒超时保护。响应中的routing_explanation由实际命中的model、provider、latencyMs与cost拼装cost_envelope.estimated按prompt_tokens / 1_000_000 * 3.0粗估policy_verdict.allowed依据budget与实际成本比对超出预算时给出原因若响应携带fallbacksTriggeredresilience_trace会追加一条fallback_needed事件。quota-management查询模式来自 src/lib/a2a/README.md消息内容含ranking/most quota/best时按剩余配额排名返回提供者含free/suggest时列出免费组合或推荐免费档提供者默认返回完整配额汇总并警告低配额提供者。list-capabilities细节src/lib/a2a/skills/listCapabilities.ts对外部 Agent 特别有用返回带rawUrl列的 Markdown 表格Agent 可立即拉取完整 SKILL.md 注入上下文metadata.totalSkills反映目录规模当前 45 项。相关背景见 AGENT-SKILLS.md。六、任务生命周期与 TTLsubmitted → working → completed → failed → cancelledsubmitted任务创建、排队等待执行working技能处理器正在执行completed执行成功artifacts 可用failed执行失败或任务过期默认 TTL 5 分钟cancelled客户端通过tasks/cancel取消。终态为completed、failed、cancelled三者不可再迁移。每个状态迁移都会被记录进事件日志events[]。底层实现src/lib/a2a/taskManager.ts任务 ID 为 UUID v4内存Map为主存储可选的 SQLite 历史持久化persist为 best-effort失败只告警不阻断写路径严格校验状态迁移合法性VALID_TRANSITIONS规定了每个状态允许的下一状态非法迁移直接抛错TTL 默认 5 分钟new A2ATaskManager()构造器缺省ttlMinutes 5位于 taskManager.ts 的构造器签名中如需自定义可 fork 实例化如new A2ATaskManager(15)即为 15 分钟后台定时器每60 秒清扫一次过期任务submitted/working状态的过期任务被自动标记为failedTTL expired终态任务在超过2× TTL后被垃圾回收历史清理每 24 小时节流一次保留天数由环境变量OMNIROUTE_A2A_HISTORY_RETENTION_DAYS控制缺省 30 天。七、错误码Code含义-32700Parse error无效 JSON-32600Invalid request / Unauthorized-32601Method 或 skill 不存在-32602Invalid params缺少或非法参数-32603Internal error技能执行失败-32000A2A 端点未启用HTTP 503其中-32700、-32600、-32601、-32603分别映射 HTTP 200/400/404/500详见 src/app/a2a/route.ts 的jsonRpcError-32600 → 400、-32601 → 404、-32603 → 500、其余为 200。八、多语言集成示例8.1 Pythonrequestsimport requests resp requests.post(http://localhost:20128/a2a, json{ jsonrpc: 2.0, id: 1, method: message/send, params: { skill: smart-routing, messages: [{role: user, content: Hello}] } }, headers{Authorization: Bearer YOUR_KEY}) result resp.json()[result] print(result[artifacts][0][content]) print(result[metadata][routing_explanation])8.2 TypeScriptfetchconst resp await fetch(http://localhost:20128/a2a, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer YOUR_KEY, }, body: JSON.stringify({ jsonrpc: 2.0, id: 1, method: message/send, params: { skill: smart-routing, messages: [{ role: user, content: Hello }], }, }), }); const { result } await resp.json(); console.log(result.metadata.routing_explanation);8.3 典型编排模式多 Agent 编码流水线编排器先以role: coding委派smart-routing生成代码再以role: review委派同一技能做代码评审最后打印两次的cost_envelope.actual核对成本配额感知的 Agent 集群多个 Agent 共享配额时先调quota-management询问剩余配额最多的提供者再带budget调用smart-routing若policy_verdict.allowed为 false立即请求免费组合作为降级路径实时流式 Dashboard用message/stream逐 chunk 渲染输出completed事件中读取metadata.cost_envelope与routing_explanationfailed事件中渲染错误任务轮询模式对长耗时任务改用tasks/get轮询2 秒间隔超过超时上限后调用tasks/cancel止损。九、扩展如何新增一个技能仓库文档docs/frameworks/A2A-SERVER.md给出了清晰的扩展路径与源码结构一一对应创建技能文件src/lib/a2a/skills/your-skill.ts导出异步函数(task: A2ATask) Promise{ artifacts, metadata }参考 smartRouting.ts 的既有写法注册处理器在 src/lib/a2a/taskExecution.ts 的A2A_SKILL_HANDLERS中新增一条懒加载映射export const A2A_SKILL_HANDLERS { // ...existing skills your-skill: async (task) { const skillModule await import(./skills/yourSkill); return skillModule.executeYourSkill(task); }, };写入 Agent Card在 src/app/.well-known/agent.json/route.ts 的skills数组追加{id, name, description, tags, examples}条目使外部 Agent 可以发现它编写测试tests/unit/a2a-your-skill.test.ts覆盖正常路径与错误路径更新文档在 A2A-SERVER 文档的 Available Skills 表中登记。十、测试与质量保障仓库为 A2A 服务配备了完整的单元测试矩阵可作为行为契约参考tests/unit/a2a-tasks-auth.test.ts — 任务接口认证tests/unit/a2a-task-owner-idor.test.ts — 任务 owner 隔离与 IDOR 防护tests/unit/a2a-v1-compat-10839.test.ts — A2A 1.0 兼容层行为tests/unit/a2a-auth-timing-safe.test.ts — 恒定时间令牌比较tests/unit/a2a-enabled-route.test.ts — A2A 开关与 503 行为tests/unit/a2a-memory-hits.test.ts — 记忆命中观测OMNIROUTE_A2A_MEMORY_HITS0可关闭tests/unit/a2a-routing-logger.test.ts — 路由决策日志。十一、小结通过 A2A ServerOmniRoute 不再只是一个被动的 API 网关而是可以主动被其他 Agent发现、委派与协作的智能路由 Agent。其核心价值在于外部编排器以统一 JSON-RPC 2.0 接口调用smart-routing等技能时能同时获得路由解释、成本信封、弹性轨迹与策略裁决四类可观测元数据从而把选哪个模型、花多少钱、有没有回退、是否超预算这些原本黑盒的决策变成可供上层 Agent 直接消费的结构化事实。结合任务生命周期管理、5 分钟 TTL、SSE 流式与 1.0 兼容层它可以平滑嵌入 LangChain、CrewAI、AutoGen 等既有多 Agent 体系成为配额感知、成本可控的协作中枢。【免费下载链接】OmniRouteNever stop coding. Free MIT AI gateway: one endpoint, 352 providers (150 free), 1200 models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline Copilot. Quota-aware auto-fallback, RTKCaveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550 contributors项目地址: https://gitcode.com/GitHub_Trending/om/OmniRoute创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考