开放Agent Web与GEA:构建可被智能代理发现和调用的服务入口 📅 发布时间:2026/8/31 9:13:11 👁 浏览次数: 说明以下内容基于公开资料中关于“开放 Agent Web”与 GEA通用入口/接入层的讨论整理与推演。GEA 这一概念目前仍在快速演进文中对具体协议细节的表述采取“工程推导 当前常见实践”的方式并非引用某一份官方 RFC。把重点放回“你作为工程师该怎么理解、怎么落地”。如果你平时关注 AI 应用开发最近一定频繁看到两个词Agent 和 MCP。但你有没有发现现在绝大多数 Agent 都还是“孤岛”模型供应商给出一个 API你在里面写 Prompt、挂工具、跑 Workflow最后发布成一个聊天机器人。换个平台又要重新注册、重新配工具、重新对齐数据结构。企业的 CRM、ERP、数据库、工单系统每个系统都有一套 API每个 Agent 都要单独做一遍集成。GEA在开放 Agent Web 语境下通常指面向智能代理的“通用入口/接入层”和开放 Agent Web 想解决的正是这个问题让 Agent 不再困在单个平台里而是像网页一样可以被发现、被调用、被组合。本文不打算追逐概念热词而是从工程角度拆三件事开放 Agent Web 到底改变了什么它和“开放 API”“MCP”“A2A”是什么关系GEA 作为入口层在架构上承担哪些职责作为开发者你现在能把一个普通 HTTP 服务改造成可被 Agent 发现和调用的节点。文章后面会给出可直接运行的示例代码和排查思路。如果你正在做 Agent 应用、企业系统智能化改造或者只是想知道下一代 Web API 长什么样这篇值得看完。1. 为什么“开放 Agent Web”不是口号而是架构问题很多人把“Agent Web”理解为“网页里塞一个 AI 窗口”这是误解。过去二十年Web 解决的是“人找信息”。浏览器通过 URL 找到页面人类阅读、点击、填表。这个模式下Web 的原子单位是文档交互方式是人为操作。Agent Web 解决的是“程序代你做事”。AI 代理需要自己理解意图、找到能力、调用服务、确认结果。这个模式下Web 的原子单位应该变成能力交互方式是机器协商。一个典型场景你让助手帮你安排一次跨部门会议。传统方式下你必须预定会议室、查参会人日程、发日历邀请、同步会议纪要。每一步都靠人操作或者靠一个已经写死的业务系统。Agent 方式下你希望助手自己去调用日历 API、会议室系统、通讯录工具并且自动协调冲突。问题来了这些系统分属不同厂商各有各的认证方式、字段定义、接口协议。助手怎么知道“会议室系统”在哪儿“取消预订”用什么参数“忙碌时间”以什么格式返回如果所有能力都必须预先写进同一个 Agent 平台那平台会变得越来越重最后变成一个新的“超级 ERP”。这既不可维护也不开放。开放 Agent Web 的关键判断是服务提供方应该主动暴露一个“可被 Agent 理解的入口”能力发现、身份认证、任务分发、状态同步都应该有通用规则不同平台的 Agent 之间可以协作而不是每一次协作都写定制胶水代码。GEA 就是在这一层出现的。从现有讨论看GEA 更接近“Agent 世界的入口规范”或“网关层协议”。它负责回答三个问题你的 Agent 从哪里进来—— 入口和发现进来之后怎么认证—— 身份与授权调用到什么能力、以什么契约完成—— 接口与执行流转。换句话说MCP 提供了“模型调用工具”的标准A2A 提供了“Agent 对 Agent”的交互协议而 GEA 更偏整个开放网络中的统一接入与路由层。三者不是竞争关系而是不同层次的组成。2. 基础概念从 URI、MCP、A2A 到 GEA 的关系很多文章把 MCP、A2A、GEA 混在一起讲结果读者越看越乱。这里先用一张表把这些概念分开。概念解决的问题类比常见表达API / Web API暴露一个服务的具体操作一个商店的柜台GET /ordersMCP让模型以标准方式调用工具商店门口的导购机器人model_context_protocolA2A让代理之间互相交流任务商店之间签合作协议agent-to-agentGEA统一入口、发现、路由、认证、结算商业街管委会 门牌系统gateway entry agent这样看就清楚了MCP 是“模型—工具”之间的协议A2A 是“代理—代理”之间的协议GEA 则是更外层的基础设施它让 Agent 能像浏览器访问网站一样访问整个 Web。如果还是觉得抽象可以回想 DNS 和 HTTPS 的作用。浏览器之所以能访问任意网站是因为有 DNS 做域名解析有 TLS 做传输加密有 HTTP 定义请求格式有 HTML 描述页面。Agent Web 也需要一套“为机器设计的 HTTP HTML”。GEA 在设想中承担的角色就类似这个网络层的“注册中心 网关 路由表”。它不负责具体业务而是让一个 Agent 能够按名找到另一个能力节点并完成安全调用。那么普通 Web 和 Agent Web 在架构上有哪些本质差异下面列几条最重要的。第一响应目标不同。Web API 返回 JSON 给人看Agent Web 返回的内容还要携带“意图、状态、可执行动作”。一个订单接口如果返回订单号Agent 可能还得查状态如果这个响应里直接标注“订单已创建下一步可调用取消/支付/物流查询”Agent 就能自动决策。第二发现机制不同。传统 API 靠开发者文档Agent Web 必须有机器可读的能力清单。这个清单应该包含提供哪些操作、每个操作的输入输出、调用需要什么权限、费用如何计算。第三会话状态不同。人调用 API 通常是“请求—响应”模式Agent 却经常需要多轮、长时间运行的任务。所以 Agent Web 不仅要关心“调用成功没有”还要关心“这个长任务跑到哪一步了、能不能暂停、能不能续跑”。第四信任模型不同。Web 时代我们通过域名和 HTTPS 证书建立信任Agent Web 里 Agent 会主动调用第三方因此信任要建立在“身份 授权 可审计”之上。GEA 要处理的正是这四个差异在工程上的落地。它不是一两个接口而是一整套接入约定。3. GEA 的核心职责入口、发现、路由、执行、审计如果把 GEA 看成一个系统它的核心职责可以拆成五块。3.1 统一入口每个能力节点都应该有一个稳定地址Agent 可以把它当作“基础 URL”。这个入口只负责两件事确认对方身份、返回能力清单。在实际工程中我建议入口路径设计成POST /gea/discover POST /gea/invoke/{action} POST /gea/eventsdiscover用于能力发现invoke用于具体的操作调用events用于长任务事件订阅。路径不一定要完全按这个命名但它应该是约定俗成的这样每个 Agent 节点开箱即用。3.2 能力发现一个 Agent 节点要向外部描述自己它是做什么的它支持哪些操作每个操作的入参出参是什么它的身份标识和联系方式。对应到接口上GEA 可以设计成类似下面的 discover 响应{ name: company-reservation-service, version: 1.0.0, owner: ops-team, agent_type: seat_reservation, endpoint: https://reservation.example.internal, actions: [ { name: book_meeting_room, description: 根据时间、人数、地点要求预订一个可用会议室, input_schema: { type: object, required: [start_at, end_at, people_count], properties: { start_at: {type: string, format: date-time}, end_at: {type: string, format: date-time}, people_count: {type: integer, minimum: 1}, require_projector: {type: boolean} } }, output_schema: { type: object, properties: { reservation_id: {type: string}, room_name: {type: string}, status: {type: string, enum: [CONFIRMED, PENDING]} } }, auth: {type: oauth2, scopes: [meeting:book]} } ] }这个 JSON 的价值在于Agent 第一次接触你的服务不需要人类提供说明书就能知道你能干什么、怎么调用。3.3 任务路由当多个 Agent 节点协同工作时GEA 需要知道“某个请求应该交给谁”。这很像微服务架构里的 API 网关客户端不直接访问后端服务而是通过网关按路由规则转发。区别在于微服务网关的路由规则由开发者配置而 Agent Web 的路由要考虑文本意图和语义匹配。一个 Query 可能是“帮我订一间能坐六人、有投影仪的会议室”路由层要先把它解析成目标动作book_meeting_room然后找到对应的节点。实践中这一步通常由“意图分类 服务注册表匹配”共同完成。大模型负责把人类指令翻译成结构化意图注册表负责查询候选节点。3.4 执行编排执行阶段最大的坑是长任务。Agent 调用一个接口接口可能五分钟、一小时甚至一天后才完成。如果客户端傻等体验会非常差。GEA 层面的执行编排通常会支持三种模式同步模式请求发出等待返回结果适合耗时短、确定性的操作异步模式请求发出立刻返回 task_id任务完成通过事件通知流式模式适用于生成、推理、日志类场景客户端通过 SSE 或 WebSocket 持续接收结果。3.5 审计与结算Agent 调用另一个 Agent 的能力不能是无偿的也不能是无痕迹的。至少需要谁在调用调用了什么操作消耗了多少钱或多少资源是否涉及敏感数据有没有脱敏有没有审批记录。GEA 网关应该把每次调用记录成标准事件输出给日志系统和计费系统。否则 Agent 生态一旦放大企业会对“失控的自动调用”非常恐惧。4. 从零实现一个可被 Agent 发现的节点理论讲太多容易飘我们现在直接写一个最小可运行的 Agent 节点。技术栈选 Python FastAPI因为简单而且生态成熟。4.1 环境准备建议使用 Python 3.10 或以上版本。python -m venv .venv source .venv/bin/activate pip install fastapi uvicorn pydantic没有特殊版本要求以上依赖截至文章写作时保持默认最新即可。如果你的网络环境不方便安装外部依赖也可以换成 Flask 或标准库实现核心思路相同。4.2 实现 GEA 风格的入口与用法发现新建一个项目目录结构如下gea-agent-demo/ ├── main.py ├── discover.json └── requirements.txtmain.py是一个 FastAPI 应用暴露两个端点/gea/discover和/gea/invoke/book_meeting_room。# 文件路径gea-agent-demo/main.py from fastapi import FastAPI, HTTPException from pydantic import BaseModel, Field import uvicorn import uuid from datetime import datetime app FastAPI(titleGEA Agent Node Demo) # 能力清单实际项目中通常读自配置文件 CAPABILITIES { book_meeting_room: { description: 预订一个可用会议室, input_schema: { type: object, required: [start_at, end_at, people_count], properties: { start_at: {type: string, format: date-time}, end_at: {type: string, format: date-time}, people_count: {type: integer, minimum: 1}, require_projector: {type: boolean, default: False} } }, auth: {type: oauth2, scopes: [meeting:book]} } } class BookRoomRequest(BaseModel): start_at: str end_at: str people_count: int Field(..., gt0) require_projector: bool False app.get(/gea/discover) def discover(): 让 Agent 发现这个节点的能力清单。 return { name: company-reservation-service, version: 1.0.0, owner: ops-team, endpoint: https://reservation.example.internal, actions: [ { name: action_name, description: action_info[description], input_schema: action_info[input_schema], auth: action_info[auth] } for action_name, action_info in CAPABILITIES.items() ] } app.post(/gea/invoke/book_meeting_room) def invoke_book_meeting_room(request: BookRoomRequest): 执行会议室预订操作。 # 真实项目中这里会查会议室系统、写订单表、发日历邀请 reservation_id uuid.uuid4().hex[:8] room_name fMeeting-{request.people_count}-{request.require_projector} # 构造一个 agent 友好的响应带上状态和下一步动作 return { reservation_id: reservation_id, room_name: room_name, status: CONFIRMED, booked_by: assistant-agent, start_at: request.start_at, end_at: request.end_at, next_actions: [ {action: check_meeting_room_status, params: {reservation_id: reservation_id}}, {action: cancel_reservation, params: {reservation_id: reservation_id}} ] } if __name__ __main__: uvicorn.run(app, host0.0.0.0, port8000)代码里值得注意的点/gea/discover返回了整个能力清单Agent 第一次接触就可以决定是否调用next_actions字段是我特意加的它的作用是告诉 Agent“任务完成后还可以做什么”省去 Agent 在多个接口之间猜测的步骤真实项目中book_meeting_room内部会调用公司内部的会议室系统这个示例只做占位。4.3 启动并验证启动服务uvicorn main:app --host 0.0.0.0 --port 8000打开另一个终端先用 curl 看能力发现接口curl http://127.0.0.1:8000/gea/discover你应该能看到类似下面的输出省略部分字段{ name: company-reservation-service, version: 1.0.0, actions: [ { name: book_meeting_room, description: 预订一个可用会议室, input_schema: { type: object, required: [start_at, end_at, people_count] } } ] }再调用会议室预订curl -X POST http://127.0.0.1:8000/gea/invoke/book_meeting_room \ -H Content-Type: application/json \ -d {start_at:2025-07-01T10:00:00Z,end_at:2025-07-01T11:00:00Z,people_count:6,require_projector:true}返回结果{ reservation_id: a3f8b9c1, room_name: Meeting-6-True, status: CONFIRMED, booked_by: assistant-agent, start_at: 2025-07-01T10:00:00Z, end_at: 2025-07-01T11:00:00Z, next_actions: [ {action: check_meeting_room_status, params: {reservation_id: a3f8b9c1}}, {action: cancel_reservation, params: {reservation_id: a3f8b9c1}} ] }到这里你已经拥有一个可以被外部 Agent 发现和调用的服务节点了。虽然它还没有接入任何 Agent 框架但接口契约已经符合开放 Agent Web 的基本要求。5. 让 Agent 客户端能自动调用你的节点服务端准备好了客户端才是关键。下面写一个轻量 Agent 客户端它先 discover再根据返回值动态构造调用。这里不依赖 LangChain 这类框架只用 Python requests 和一个最简化的大模型意图识别。实际项目中你可以把意图识别换成 GPT、通义、文心或本地模型。# 文件路径gea-agent-demo/agent_client.py import requests import json class OpenAgentClient: def __init__(self, node_url: str): self.node_url node_url.rstrip(/) def discover(self) - dict: resp requests.get(f{self.node_url}/gea/discover) resp.raise_for_status() return resp.json() def invoke(self, action: str, payload: dict) - dict: resp requests.post( f{self.node_url}/gea/invoke/{action}, jsonpayload, headers{Authorization: Bearer stub-token}, ) resp.raise_for_status() return resp.json() if __name__ __main__: client OpenAgentClient(http://127.0.0.1:8000) # 1. 发现能力 discovery client.discover() print(发现能力节点:, discovery[name]) for action in discovery[actions]: print(可用操作:, action[name], action[description]) # 2. 调用能力 result client.invoke( book_meeting_room, { start_at: 2025-07-01T10:00:00Z, end_at: 2025-07-01T11:00:00Z, people_count: 6, require_projector: True, }, ) print(调用结果:, json.dumps(result, ensure_asciiFalse, indent2))运行python agent_client.py输出略但你应该看到从“发现”到“调用”的完整链路。这个客户端的核心价值是它不需要写死任何业务接口只需要知道 GEA 入口地址。这就是开放 Agent Web 与普通 API 集成的最大不同。普通 API 集成是“点对点”的开放 Agent Web 是“一点对全网”的。只要所有节点实现相同的发现与调用规则新增一个服务只需要注册入口。6. 能力发现的进阶设计语义路由还是硬路由上面的例子用的是硬编码动作名book_meeting_room。真实世界里Agent 收到用户消息“帮我找个能开会的地方”不会精确对应到这个动作名。它需要语义映射。工程上有两种做法。第一种是“关键词 规则路由”。适合能力明确、动作较少的内部系统。比如配置{ route_rules: [ { intent_keywords: [会议室, 预订, booking, meeting], action: book_meeting_room }, { intent_keywords: [取消, cancel], action: cancel_reservation } ] }第二种是“向量检索 LLM 选择”。把所有能力描述做向量化用户请求也向量化先召回 Top-K 能力再用大模型选择最合适的动作。第二种更接近开放 Agent Web 的目标因为你的 Agent 节点不可能永远只有两三个动作。当动作数量达到上百个时规则路由基本维护不动。需要注意路由层无论怎么选最终都要落到规范化的action payload结构上。GEA 的价值不是让路由更聪明而是让路由的结果能统一执行。7. 开放 Agent Web 落地时最常见的四个坑概念阶段看着很美好落地阶段到处是坑。下面列四个我判断最容易出问题的地方。7.1 只做接口不做契约版本管理Agent 节点升级接口后旧版本 Agent 仍然在用旧参数这时候如果直接改 schema线上必炸。建议discover接口返回的每个 action 都要带version字段。执行层在做路由时如果发现 Agent 期望的版本和节点提供的不一致要能返回“版本不兼容”的明确错误而不是因为缺参报 400。{ name: book_meeting_room, version: 1.1.0, deprecated: false }7.2 忽略长任务的异步状态同步很多团队刚把接口暴露给 Agent就开始用同步模式跑结果一个耗时长任务直接把 HTTP 连接占死。正确设计是耗时操作先返回 task_id然后通过事件订阅通知结果。一个简单的设计app.post(/gea/async/book_meeting_room) def async_book(request: BookRoomRequest): task_id uuid.uuid4().hex # 伪代码把 task 丢进队列后台 worker 处理 background_tasks.enqueue(task_id, request) return {task_id: task_id, status: ACCEPTED}7.3 不做调用鉴权就开放开放不等于裸奔。任何 Agent 调用必须携带可验证的身份令牌。这个令牌可以是 OAuth 2.0 的 access_token也可以是企业内部的 JWT。建议在网关层统一校验而不是每个业务接口自己实现一遍。from fastapi import Header, HTTPException def verify_token(authorization: str Header(...)): # 伪代码解析并校验 token if not authorization.startswith(Bearer ): raise HTTPException(status_code401, detailInvalid token) # 真实项目这里会调用 API Gateway 或本地验证 JWT7.4 没有调用可观测性Agent 自动调用多个系统一旦出问题排查链条会比人工操作长得多。必须做全链路 Trace把“用户请求 ID”贯穿到每一个 Agent 调用节点。这个坑在 B 端尤其严重。很多企业系统都是五六年前的老系统接口日志不完整一旦 Agent 在某一步把数据写错很难定位是哪个节点引起的。8. 常见问题与排查方法问题现象可能原因排查方式解决方案discover 返回 404节点没有实现 GEA 入口或路径拼错查看服务日志和路由表确认入口路径为/gea/discover并在网关层配置转发invoke 返回 400payload 不符合 input_schema用 Pydantic/FastAPI 的自动校验查看具体字段错误核对 required 字段、类型、枚举值Agent 调用超时业务操作是长任务但用了同步调用在节点日志里看请求耗时分布改成异步 task_id 事件订阅调用成功但数据没写库业务代码异常被吞掉或事务未提交查看应用异常日志和数据库事务日志补充异常处理增加入库成功标记权限校验失败Agent 没有申请对应 scope查看网关鉴权日志在 Agent 配置中增加 OAuth scope不同 Agent 对同一字段理解不一致缺少字段语义字典对比各节点 discover 的 json schema维护统一的字段术语表必要时加入全局语义层9. 工程落地建议与安全边界如果你所在团队准备尝试开放 Agent Web 和 GEA 思路建议按以下节奏推进不要一上来就搞大平台。9.1 先做三个内部节点不要急着把所有系统都 Agent 化。选三个典型的、且调用频繁的内部系统会议/日程系统工单系统知识库检索。为它们实现同一种 GEA 风格入口。内部跑通之后再扩到其他系统。这里的关键不是选大模型有多强而是把数字化系统的“可编程入口”先标准化。9.2 先定契约再写代码每个能力节点先画 JSON Schema再写内部实现。团队成员 review schema 的时间应该多于 review 代码的时间。Schema 是开放 Agent Web 的“API 文档”但它是机器可读且可执行的。9.3 安全边界不能省最小权限Agent 令牌只授予它执行具体动作所需的最小 scope敏感操作二次确认涉及删除、转账、批量改数据时Agent 必须返回“等待人工确认”状态限流每个 Agent 调用方设置独立的 QPS 上限和日调用上限审计每次调用记录 who、when、what、result至少保留 180 天数据脱敏响应给 Agent 的数据中手机号、身份证、密钥等字段按规则脱敏。9.4 测试与回滚把 Agent 当成外部用户来测试。每个入口都准备一组“正常 payload 异常 payload 越权 payload”的测试用例。升级 schema 时兼容旧版本至少一个周期。生产环境出现异常时优先在网关层关闭某个 Agent 的调用权限而不是逐个业务系统回滚。9.5 参与开放生态如果你希望自己的服务不仅被内部 Agent 调用还希望被外部 AI 生态发现可以关注主流 Agent/框架对 MCP、A2A、GEA 的支持情况。给自己的服务写一个标准入口比在每个平台分别适配省得多。用更直白的话说未来不是“我的 API 被谁集成”而是“我的能力节点是否在网络里可被发现、可被信任、可被计量”。10. 总结现在该做什么回到题目GEA 和开放 Agent Web 到底在讲什么我的判断是它本质上是一次“从私有接口到公共能力网络”的迁移。过去我们做集成靠的是人力写代码未来我们做集成靠的是遵循统一入口、具备发现和信任机制的 Agent 节点。MCP 已经让“模型调工具”变得标准化A2A 正在让“Agent 调 Agent”变得标准化而 GEA 这类入口规范要解决的是这些能力怎么被找到、怎么被信任、怎么安全地组合。对普通开发者最值得做的不是急着追协议而是把现有服务的能力清单结构化至少做到 discover 可读在响应中加入 next_actions让调用方知道“接下来能做什么”排查自己的认证、限流、审计是否满足自动调用场景找一个低风险业务跑通一个最小 Agent 调用闭环持续关注 MCP、A2A、GEA 和主流框架的兼容情况。开放 Agent Web 的最终形态现在还没定型但它的大方向是确定的Agent 会越来越多封闭的接口会越来越贵。早一点把节点接入标准入口你的系统就早一点获得被 AI 生态调用的能力。这份成本不是浪费而是在为下一个十年的信息协作打地基。