OmniRoute A2A Server 接入指南:基于 JSON-RPC 2.0 的智能路由 Agent 协议 📅 发布时间:2026/9/12 10:29:07 👁 浏览次数: 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/OmniRouteOmniRoute 以智能路由 Agent 的身份对外提供 Agent-to-Agent ProtocolA2Av0.3 服务外部 Agent、工具链与自动化脚本可以通过统一的标准接口把提示词交给 OmniRoute 的智能路由流水线执行并拿到路由决策解释、成本明细与弹性追踪。读完本文你将掌握 A2A 服务的发现与认证方式、四个 JSON-RPC 2.0 方法的完整调用格式、六个内置技能的能力边界以及如何在本地部署中扩展自定义技能并接入 REST 辅助端点。A2A 服务在 OmniRoute 中的定位A2AAgent-to-Agent Protocol是让不同 Agent 之间可以互相发现能力、委派任务并交换结果的标准协议。OmniRoute 作为 AI 网关其 A2A Server 将智能路由能力封装成标准化的 Agent 服务对外暴露两张面JSON-RPC 2.0 规范入口POST /a2a这是官方约定的规范调用点定义于 src/app/a2a/route.ts。REST 辅助端点/api/a2a/*面向仪表盘与外部工具提供状态查询、任务列表与任务取消能力。任务的完整生命周期由A2ATaskManager管理src/lib/a2a/taskManager.ts默认 5 分钟 TTL技能通过 src/lib/a2a/taskExecution.ts 中的A2A_SKILL_HANDLERS分发。Agent 发现Agent Card任何 A2A 客户端接入前都应先通过标准发现端点获取 OmniRoute 的 Agent Card代理能力卡了解其能力、技能与认证要求curl http://localhost:20128/.well-known/agent.json该端点返回的 Agent Card 包含以下关键信息字段说明name/descriptionAgent 名称与能力描述urlA2A 规范入口/a2aversion当前版本号取自process.env.npm_package_versioncapabilities是否支持流式streaming: true等能力标记skills[]已注册的技能清单id、名称、描述、标签、示例调用authentication认证方案api-key请求头Authorization从实现看src/app/.well-known/agent.json/route.ts 是动态生成Agent Card 的version字段直接读取process.env.npm_package_version随每次发版自动与package.json同步无需手工维护skills数组除内置六个技能外还会追加 OmniConductor 舰队技能getFleetSkills()当 hub 未配置或离线时返回空数组卡片依然有效。响应带有Cache-Control: public, max-age3600缓存头客户端可缓存 1 小时。认证机制所有/a2a请求都需要通过Authorization头携带 API 密钥Authorization: Bearer YOUR_OMNIROUTE_API_KEY认证的具体逻辑位于 src/lib/a2a/authenticate.ts采用与/v1流水线一致的REQUIRE_API_KEY姿态分为三种情况服务端配置了密钥请求必须携带匹配的密钥使用timingSafeEqual进行常数时间比较避免时序侧信道否则返回 JSON-RPC 错误-32600Unauthorized。要求 API 密钥的开关开启REQUIRE_API_KEY必须提供合法的 OmniRoute 密钥。未配置任何密钥认证被绕过允许无密钥调用keyless 本地优先模式这也是开箱即用的默认行为。值得注意的安全细节resolveA2AOwner()会对调用方的 API 密钥取 SHA-256 哈希并截取前 32 位作为owner id用于任务可见性隔离——带 owner 的任务只对同一 owner 可见无密钥的本地调用产生的任务则对所有人可见。相应的越权防护测试见 tests/unit/a2a-task-owner-idor.test.ts。启用 A2A 服务A2A 由Endpoints端点→ A2A开关控制默认关闭。当开关关闭时GET /api/a2a/status报告status: disabled、online: false对POST /a2a的 JSON-RPC 调用返回 HTTP 503并带 JSON-RPC 错误码-32000A2A endpoint is disabled。该逻辑在 src/app/a2a/route.ts 的rejectIfA2ADisabled()中实现读取settings.a2aEnabled非true时直接拒绝。对应测试见 tests/unit/a2a-enabled-route.test.ts。因此接入前请先确认服务端已开启该开关。JSON-RPC 2.0 方法详解规范入口POST /a2a提供四个方法message/send同步执行、message/streamSSE 流式、tasks/get查询任务、tasks/cancel取消任务。路由处理器内部还会将方法名做归一化并兼容 A2A 1.0 客户端的方法命名详见下文1.0 兼容层。message/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 } } } }params中的可选字段说明字段默认值说明skillsmart-routing要调用的技能 id未指定时默认走智能路由messages必填[{ role, content }]消息数组也兼容{ message: { content } }或{ message: { parts: [...] } }的旧式形状见 src/app/a2a/route.ts 的toMessageArray()metadata.modelauto期望的模型auto表示由路由引擎决定metadata.combo无指定组合combo策略例如fast-codingmetadata.budget无成本预算上限触发策略裁决检查result.metadata中的四个核心字段是智能路由技能smart-routing返回的可观测数据从 src/lib/a2a/skills/smartRouting.ts 的实现可以看到它们的来源routing_explanation最终选择的模型与提供者、实测延迟latencyMs与成本cost_envelope成本包络包含estimated按 prompt tokens 估算与actual上游真实返回的cost字段以及币种USDresilience_trace弹性追踪数组记录primary_selected事件若上游触发回退raw.fallbacksTriggered还会追加fallback_needed事件policy_verdict策略裁决结果当请求携带budget且实际成本超限时allowed为false并给出原因。message/stream— SSE 流式输出与message/send相同但通过 Server-Sent EventsSSE实时返回结果适合长耗时请求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 ...注释行维持连接某些中间层代理会因超时掐断空闲 SSE 连接分块技能执行完成后将artifacts逐个以chunk事件发出对非流式技能做了模拟流式终态最后发送completed事件并携带完整metadata出错时发送failed事件并带metadata.error取消监听客户端abortSignal连接中断时立即终止并标记失败响应头Content-Type: text/event-stream、Cache-Control: no-cache, no-transform、X-Accel-Buffering: no禁用 Nginx 缓冲保证实时性。tasks/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}}返回任务的完整对象id、skill、state、events 事件日志、artifacts、metadata 等。查询时若任务已过期见下文 TTL且处于submitted/working中间态会被自动标记为failedTask expired后再返回。tasks/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}}取消操作带 owner 校验调用方只能取消属于自己的任务无 owner 的本地任务对所有人开放。为防 IDOR 探测任务不存在与存在但不属于你返回相同的Task not found错误。A2A 1.0 兼容层src/app/a2a/route.ts 内置了一层A2A v1.0 ↔ v0.3 兼容层A2A 1.0 将方法重命名为SendMessage/SendStreamingMessage并把同步响应的正文放到task.status.message.parts[].text。该层会对 1.0 方法名做别名映射并将响应重塑为 1.0 的 Task 形状使 a2a-sdk 1.x、Hermes 等 1.0 客户端可以不改动直接调用v0.3 客户端则完全不受影响。对应测试见 tests/unit/a2a-v1-compat-10839.test.ts。可用技能Available SkillsA2A_SKILL_HANDLERSsrc/lib/a2a/taskExecution.ts目前注册了六个技能每个技能模块位于 src/lib/a2a/skills/ 目录技能ID说明标签示例提问智能路由smart-routing通过 OmniRoute 的组合引擎 评分将提示词路由到最优提供者/组合routing, providersRoute this prompt via the best model配额管理quota-management报告各提供者配额状态辅助调用方决定何时限流/切换quota, providersCheck quota for anthropic提供者发现provider-discovery列出已安装提供者的能力、免费层标记、OAuth 状态providers, discoveryWhat providers are available?成本分析cost-analysis依据目录与近期用量估算请求/会话成本cost, usageEstimate cost for this conversation健康报告health-report汇总各提供者的熔断、冷却、锁定状态health, resilienceShow health status of all providers列出能力list-capabilities以 Markdown 表格返回完整 Agent 技能目录及原始 SKILL.md 链接catalog, discovery, skillsList all OmniRoute capabilities其中smart-routing与quota-management是两个最有代表性的技能源码实现分别位于 src/lib/a2a/skills/smartRouting.ts 与 src/lib/a2a/skills/quotaManagement.tssmart-routing内部调用自身网关的/v1/chat/completions30 秒超时透传model、messages与x-combo头把上游返回的模型、提供者、成本、回退标记组装成上文所述的routing_explanation、cost_envelope、resilience_trace、policy_verdict。quota-management会并行拉取/api/usage/quota与/api/combos各 10 秒超时然后对自然语言问题做意图分类包含ranking/most quota/best时返回按剩余配额排序的排行榜包含free/suggest时推荐免费组合combo 名称含free/gratis者其余情况返回汇总概览并对剩余配额 ≤10% 的提供者给出警告。list-capabilities技能详解该技能对外部 Agent 特别有用——在发送 API 调用之前先让它发现自己能做什么。它返回结构化 Markdown 表格工件| ID | Name | Category | Area | Endpoints/Commands | Raw URL | | --- | --- | --- | --- | --- | --- | | omni-auth | Auth Sessions | api | auth | POST /api/auth/login, ... | https://raw.githubusercontent.com/... | ...实现位于 src/lib/a2a/skills/listCapabilities.ts调用getCatalog()读取技能目录computeCoverage()统计覆盖率每行包含rawUrl列Agent 可以直接拉取完整 SKILL.md 注入上下文metadata.totalSkills镜像目录规模。技能目录的完整定义见 docs/frameworks/AGENT-SKILLS.md。REST 辅助端点POST /a2a是规范入口而下面的 REST 端点为仪表盘和外部工具提供辅助访问端点方法说明认证/api/a2a/statusGET服务端状态与已注册技能公开/api/a2a/tasksGET带过滤条件列出任务management/api/a2a/tasks/[id]GET按 ID 获取任务management/api/a2a/tasks/[id]/cancelPOST取消运行中的任务management/.well-known/agent.jsonGETAgent CardA2A 发现缓存 3600s公开/api/a2a/tasksPOST入站委派将编码任务转发给 OmniConductor 舰队Bearer vsOMNIROUTE_API_KEYa2aEnabled其中GET /api/a2a/status的实现src/app/api/a2a/status/route.ts除返回status/online外还会附带当前任务统计tasks按状态计数、活动流数量、最近任务时间并在启用时动态内嵌 Agent Card 摘要name、description、version、skills。最后一个 REST 端点是入站 Conductor 委派外部 A2A Agent 可以通过POST /api/a2a/tasks把编码工作委派给 OmniConductor 舰队。请求体形如{ skill: conductor | conductor-cli-profile, messages: [...], metadata: { conductor: { repo: { url, base_ref? }, mode?, cli?, model? } } }其中metadata.conductor.repo.url必填舰队在 git 仓库上工作路由会使用服务端CONDUCTOR_ORCHESTRATOR_TOKEN回退CONDUCTOR_HUB_TOKEN转换为 hub 的POST /v1/tasks返回201 { conductor_task_id, state: submitted }任务状态通过 SSE→A2A 镜像流回并可通过GET /api/a2a/tasks?skillconductor查看。任务生命周期与 TTLA2A 任务遵循如下状态机定义于 src/lib/a2a/taskManager.tssubmitted → working → completed → failed → cancelled任务默认在5 分钟后过期TTL 可配置终态包括completed、failed、cancelled每次状态迁移都会记录到事件日志events[]并在开启持久化时写入 SQLite 历史表a2a_tasks同时通过事件总线广播agent.task.updated。实现细节A2ATaskManager构造函数签名为new A2ATaskManager(ttlMinutes 5, persistence)TTL 以分钟为单位换算为毫秒后台每60 秒清扫一次过期任务将中间态任务标记为failed、TTL expired并将超过 2 倍 TTL 的终态任务从内存中移除。历史记录的保留天数由OMNIROUTE_A2A_HISTORY_RETENTION_DAYS环境变量控制默认 30 天清理节流为每 24 小时至多一次。自定义 TTL 的方法forkA2ATaskManager的实例化并传入不同的值例如new A2ATaskManager(15)得到 15 分钟 TTL。任务执行前的可观测内存召回memory hits默认 1.5 秒超时可通过OMNIROUTE_A2A_MEMORY_HITS0关闭见 src/lib/a2a/taskExecution.ts 与 tests/unit/a2a-memory-hits.test.ts。错误码代码含义-32700解析错误无效 JSON-32600无效请求 / 未授权-32601方法或技能不存在-32602参数无效-32603内部错误-32000A2A 端点已禁用各错误码对应的 HTTP 状态在 src/app/a2a/route.ts 的jsonRpcError()中定义-32600→ 400-32601→ 404-32603→ 500其余为 200JSON-RPC 语义以错误码为准。集成示例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])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);扩展添加新技能如果你需要让 OmniRoute 的 A2A Server 暴露更多能力仓库给出了清晰的五步扩展路径创建技能文件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: your-skill, name: Your Skill, description: Brief, intent-focused description, tags: [routing, quota], examples: [Sample natural-language invocation] }编写测试tests/unit/a2a-your-skill.test.ts覆盖正常路径与错误路径。更新文档在本文对应的英文原版 docs/frameworks/A2A-SERVER.md及其多语言译本如 中文版的 Available Skills 表中补充新技能。小结OmniRoute 的 A2A Server 让智能路由以标准 Agent 协议对外可发现、可调用、可观测通过/.well-known/agent.json完成能力发现通过POST /a2a的四个 JSON-RPC 方法完成同步/流式任务执行与生命周期管理通过六个内置技能覆盖路由、配额、成本、健康等运维场景并通过 REST 端点与 OmniConductor 舰队联动实现跨 Agent 的编码任务委派。对希望把 OmniRoute 接入自有 Agent 编排体系如 OpenCode、Claude Code、Codex 生态的开发者而言这套接口既是网关能力的标准出口也是可以按上文五步路径自由扩展的开放框架。【免费下载链接】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),仅供参考