ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Agent网络协议白皮书深度解读:ANP如何让Agent互联与协作

Agent网络协议白皮书深度解读:ANP如何让Agent互联与协作 这篇“Agent Network Protocol 技术白皮书草案”出现的时间点很微妙——大家手里已经攒了一堆能聊天、能写代码、能查资料的Agent但彼此之间基本是孤岛。各家Agent各有各的工具调用方式、消息格式和身份体系让它们协作就像让说不同方言的人开圆桌会议得靠翻译、靠磨合、靠各种临时的胶水代码。ANP草案想做的就是给Agent之间定一套“普通话”。如果你正在做多Agent系统、Agent平台或者准备让自家Agent接入外部生态这份草案值得细读。它不解决“单个Agent怎么更聪明”解决的是“一群Agent怎么好好说话”。这篇文章我结合草案思路从设计动机、协议分层、关键机制到动手搭最小链路把核心内容拆开讲也会补上一些实践中大概率踩到的坑。1. 白皮书的真实动机Agent之间为什么需要一套网络协议先想一个实际场景。你有一个个人助理Agent它能帮你管理日程、读邮件、订机票。现在你希望它帮你完成一次跨机构协作让翻译Agent把合同翻成英文再让法律Agent检查条款风险最后让财务Agent估算预算。如果每个Agent都是独立的API孤岛你的助理Agent就得分别对接三家不同的接口规范、鉴权方式和返回结构每接一个就写一套适配逻辑。Agent数量一多这种两两之间的“点对点适配”会呈指数级爆炸维护成本高到没法看。1.1 从API调用到Agent互联一个需求层次的变化过去的集成方式是把Agent当成API来调本质还是“中心化调度点对点集成”。调用方要知道每个Agent的地址、参数格式、鉴权方式写死调用关系。这种模式在系统规模小、Agent数量有限时没什么问题但一旦Agent变成一种常态化的数字服务问题就来了能力发现靠人工对接消息格式各自为政状态管理散落各处失败重试逻辑每对接一个都要重新实现。ANP想要解决的是把“调用一个API”升级成“进入一个网络”。类比一下没有TCP/IP之前两台计算机要通信就得拉专线、对参数、约定信号格式有了网络协议之后设备只要入网就能被找到、能通信、能协作。Agent网络协议做的事情类似——给Agent一个标准化的身份、一套标准化的消息语言、一套可被发现的能力目录以及一套可靠的消息投递机制。1.2 “白皮书草案”意味着什么协议仍处于快速演进期看这份草案要有正确预期。它不像是RFC那种已冻结多年的成熟标准更像是一个正在快速迭代的设计文档。这意味着三件事第一协议核心骨架已经划定——身份、发现、路由、消息、安全这些层次都在方向是清晰的第二很多细节比如消息包大小的上限、重试退避的具体算法、加密套件的强制项还在讨论中第三现在基于草案做的实现大概率需要跟着版本演进做兼容性调整。对开发者来说草案期恰恰是入局的好时机。协议还没被某一家大厂绑死你的实现有机会影响后续标准走向。但也意味着要做兼容性设计——不要把草案里的字段当作不可变契约要做好版本协商和字段扩展的准备。2. 核心设计拆解ANP如何为Agent构建“通用语言”一套网络协议能不能立住看两个东西一是它对“通信双方”的抽象是否清晰二是它对“通信过程”的约定是否完整。ANP的设计思路是把Agent当成网络中的节点参考了互联网协议分层思想但针对Agent的特点做了几个关键调整。2.1 Agent身份体系不仅仅是ID而是一套可验证的实体标识ANP给每个Agent分配一个全局唯一的Agent ID。这个设计看起来很基础但细节里有讲究。Agent ID不只是UUID那串字符串它承载了三层信息一是身份标识让消息可以寻址到具体Agent二是验证凭证搭配密钥材料使用防止有人冒充某个Agent身份三是属性载体可以携带Agent的类型、所属组织、能力域名等元数据。我在本地测试时最直观的感受是身份设计决定了后面所有机制的可行性。没有严格身份体系就会发现路由、鉴权、审计都是空中楼阁。草案里把身份验证材料设计成可轮换的这很关键——Agent实例的部署周期短、版本迭代快固定的长期密钥风险太大。2.2 能力注册与发现让Agent可以被“找到并理解”过去要找一个能翻译PDF的Agent你得知道它在哪、它的API长什么样、怎么鉴权。ANP引入了能力目录服务Agent Directory每个Agent上线时向目录注册自己的ID、端点地址、技能列表和约束条件。调用方只需要问目录谁有翻译能力目录返回符合条件的候选列表。这里有一个容易被忽略的设计点能力描述不能只是自然语言标签——比如“我能翻译”——还要有结构化参数比如支持的语言、输入输出格式、费用模型、并发上限。这样才能让调用方在真正发起消息之前判断这个Agent适不适合这项任务。实测下来翻译类能力用结构化描述让上层Agent做决策的准确率明显高于纯文本描述因为决策模型能直接解析参数而不必依赖语义猜测。2.3 消息与会话模型从“一问一答”升级到“多轮协作”单个Agent对话是简单的请求-响应一个提问一个回答。但Agent之间的协作往往是多轮的A请求B翻译B却说需要先确认术语表A返回术语表B再给出译文之后C还要对译文做合规检查可能会提出修改意见。每一条消息都属于同一个会话ANP为此设计了会话上下文管理机制——不是简单地把所有历史消息堆在一起而是让会话具备状态当前上下文、待办事项、已完成步骤、阻塞原因。这个总结和分析工作是这次拆解中最有价值的部分。多Agent协作中的大量“翻车”现场根源都不在某个Agent模型能力不行而是上下文断链。A在等待B的翻译结果时自己新增了一条消息引用旧结果C发起合规检查时看不到A和B之前的术语约定。ANP的会话模型就是为了解决这种“跨Agent上下文断裂”而生的。2.4 消息路由与可靠投递Agent之间通信不能靠“发个请求等个响应”Agent之间的通信不是简单的HTTP调用因为对方可能暂时不可用、可能处理一个任务需要几分钟、可能在等待外部输入。草案把消息投递设计成异步可靠的模式发送方先把消息交给消息队列或转发节点由中转层负责重试、排队、超时处理接收方处理完后再通过同样的通道把结果回传。有人会问为什么不用同步HTTP因为同步模型在Agent协作场景下的容错性太差。一次协作里有5个Agent参与中间有一个卡了20秒整个链路都被阻塞更麻烦的是一个Agent宕机时同步调用直接失败上游必须自己做重试逻辑、自己决定是丢弃还是缓存任务。而异步投递把“这活儿干了没有”的责任从业务层下沉到了协议层业务层只需要关心事件通知。2.5 安全与权限控制让陌生人Agent可以协作但不能乱来匿名Agent之间的协作会带来一系列安全问题对方会不会窃取会话数据会不会在消息里夹带恶意指令会不会冒充已授权Agent草案在安全设计上至少考虑了四个维度——传输层加密防窃听、身份验证防冒充、能力授权防越权、内容审计事后追溯。这四层缺一个都容易出事故。最容易被忽视的是“内容审计”一开始我也觉得传输加密就够了后来跑了一次协作链路才明白多Agent协作出错时最大的痛苦是不知道哪一步出了问题、哪个Agent发了一条错误消息。有了审计日志排查效率能提升一个量级。3. 定位与边界ANP和MCP、工作流引擎到底是什么关系看过草案的开发者都有一个共同困惑ANP和最近很火的MCP模型上下文协议是什么关系是替代还是互补我的判断很明确互补但定位不同。3.1 ANP和MCP一个管“横向互联”一个管“纵向连接”MCP解决的是Agent访问工具、数据、模型的问题——一个Agent要通过MCP去调用一个搜索API、读一个数据库、触发一个函数相当于打通了Agent和能力之间的纵向通道。ANP解决的是Agent与Agent之间的横向互联——让A能发现B、给B发消息、协作完成一个跨Agent流程。一个类比MCP是标准化的“电源插座”让Agent能插上各种外部工具和模型ANP是标准化的“电网”让每个接上电的设备能够相互供电、彼此协作。两者服务层次不同但都是Agent生态的基础设施。一个成熟的Agent系统很可能同时使用MCP接入工具和ANP跨Agent协作它们各管一段。3.2 和工作流引擎ANP不是替代品而是更底层的通信契约传统工作流引擎比如n8n、LangGraph里的流程编排解决的是“任务步骤怎么编排”——先做A再做B条件分支怎么走失败怎么重试。ANP解决的是“编排中的每一步消息怎么在Agent之间传输”。如果你用一个工作流引擎可以在编排层决定“先让翻译Agent干活再让法律Agent检查”到了真正执行时这每一步的Agent间通信就可以走ANP。所以合理的架构是上层有编排引擎底层有通信协议。编排引擎关心业务流程ANP关心消息能否可靠、安全地到达对端。两者不是二选一而是不同抽象层级。3.3 为什么AI Agent场景需要“新协议”而不是直接复用HTTP/RPC这是很多人的第一个问题直接用HTTPJSON不就行了吗如果你只做单次API调用当然可以。但Agent协作有几个HTTP没解决的场景第一Agent之间需要动态发现而HTTP调用要求调用方提前知道URL第二Agent需要能力协商——你找翻译Agent但它可能只支持中译英、不支持法译中这需要在调用前完成协商第三Agent任务的执行时长是不确定的HTTP的常规超时设计在这种场景下会很尴尬第四多Agent间的会话上下文要保持一致这在无状态的HTTP请求里很难做。这些需求叠加起来就需要一套面向会话、面向发现、面向协作的协议层。ANP不是重造轮子而是针对Agent协作场景做一个更贴合的轮子。4. 动手跑通最小ANP链路注册、发现、消息、回调全流程只看文档容易飘实际跑一遍才能理解这套协议解决的真实问题。我这里分享一个基于草案思路的最小实现不依赖完整实现用简单的Python脚本把核心机制走通。底层传输先用HTTPJSON模拟理解核心逻辑之后再替换成完整的ANP实现也不难。4.1 最小环境准备与身份初始化先做两件事启动一个目录服务用于Agent注册和发现准备两个Agent。目录服务不需要重一个FastAPI应用就够核心接口就两个注册能力和查询能力。# directory.py — 最小能力目录服务 from fastapi import FastAPI, HTTPException from pydantic import BaseModel import uuid app FastAPI() class AgentRegistration(BaseModel): agent_id: str endpoint: str skills: list[str] # 如 [translate, legal_check] params: dict {} # 可选如 {languages: [zh, en]} # 内存目录正式实现里通常是带索引的数据库 REGISTRY {} app.post(/agent/register) def register(reg: AgentRegistration): if reg.agent_id in REGISTRY: raise HTTPException(409, agent already exists) REGISTRY[reg.agent_id] reg.model_dump() return {status: registered, agent_id: reg.agent_id} app.get(/agent/discover) def discover(skill: str): matches [info for info in REGISTRY.values() if skill in info[skills]] # 真实协议里这里会做更复杂的能力过滤和打分 return {agents: matches}这里要提醒一个身份初始化的细节Agent ID 最好由目录服务统一签发或做幂等校验不要让Agent自己随便填。否则你会在实践中遇到ID冲突、重名、伪造等情况。我之前的做法是Agent启动时发送签名注册请求目录在校验签名后签发ID并把公钥指纹存入目录。4.2 注册Agent上线后如何“自我介绍”有了目录服务Agent启动后第一步就是注册。注意注册内容不是一成不变的——技能、端点、状态都会变化所以注册接口应该支持重复调用update语义这比只支持一次性注册更贴合真实场景。# agent_a.py — 翻译Agent import requests AGENT_SELF { agent_id: agent-translate-001, endpoint: http://localhost:8100/agent/invoke, skills: [translate], params: {languages: [zh, en, ja], max_doc_size_mb: 10} } # 注册并定期发送心跳/更新 def register(): resp requests.post(http://localhost:8000/agent/register, jsonAGENT_SELF) print(resp.json())注册之后目录里就能被搜索到“谁会翻译”。这一步看似简单但有个实操坑注册信息里不要写死临时端口或内网IP否则在容器化部署或跨网络环境下其他Agent根本连不上你。更好的做法是注册一个稳定的外部网关地址内部路由由网关处理。4.3 发现与协商调用方Agent如何找到合适的协作方现在让一个“协调Agent”来发起协作它需要翻译服务于是向目录发起查询按技能筛选再按参数做二次过滤比如要求支持中文到英文。# agent_b.py — 协调Agent部分逻辑 def find_translator(src_lang, dst_lang): # 1. 按技能找候选 candidates requests.get( http://localhost:8000/agent/discover, params{skill: translate} ).json()[agents] # 2. 按语言参数过滤出真正满足要求的 usable [] for agent in candidates: langs set(agent[params].get(languages, [])) if src_lang in langs and dst_lang in langs: usable.append(agent) return usable这里有个容易踩的坑只按技能名筛选。技能名太粗我要找的是“中文翻译成英文”结果候选Agent都会标记“translate”但真正支持中英互译的可能只有一半。所以发现阶段一定要做参数级过滤。ANP草案里也在强调结构化能力描述为的就是让这层过滤可计算而不是靠人去读自然语言描述。4.4 消息交互与回调如何异步拿到跨Agent的返回结果发现目标之后协调Agent向目标Agent发送任务消息。这里最核心的设计是不要等同步响应而是把这次请求标记为一个可以回传结果的异步任务。# 协调Agent发起翻译请求异步模式 task_payload { task_id: task-20240601-001, session_id: session-abc-123, source_text: Hello, this is an agent network test., target_lang: zh, callback_url: http://localhost:8200/callback/translate } resp requests.post(http://localhost:8100/agent/invoke, jsontask_payload)被调用的翻译Agent收到后做自己的事这里可以直接调任何内部模型或外部API完成后把结果回传给协调Agent指定的回调地址。翻译Agent可以选择在同一个HTTP响应里直接返回也可以延后回传——这在长任务场景非常有用# 翻译Agent完成任务后回调协调Agent result_payload { task_id: task-20240601-001, session_id: session-abc-123, status: completed, result: { translated_text: 你好这是一次Agent网络测试。, model_used: demo-model, tokens: 27 } } requests.post(http://localhost:8200/callback/translate, jsonresult_payload)这个模式解决了一个实际问题如果翻译Agent的执行时间不确定同步等待会让调用方一直挂着。异步回调则安排双方都不阻塞调用方可以去处理其他任务翻译完成后通过回调自动恢复流程。4.5 最小链路整体验证与关键观察点把上面四步串起来就是一条完整的“注册-发现-调用-回调”最小链路。我建议你在本地用三个终端分别跑目录服务、翻译Agent和协调Agent然后用协调Agent发起一次翻译任务重点观察几个现象第一次调用协调Agent返回了一个任务ID并没有立刻拿到翻译结果——因为异步模式不阻塞。隔几秒再查任务状态看到状态变成completed回调里带了译文字段。如果你同时注册两个翻译Agent一个只支持中英、一个支持中英日发现接口返回的候选列表不同能验证参数过滤是否生效。这一步跑通后你就理解了ANP最核心的骨架。后面的路由优化、安全认证、会话状态同步都是在这条最小链路上做加固和扩展。5. 常见问题与排查技巧实录Agent互联过程中的实际坑协议草案好看落地全是坑。把这段时间实际遇到的高频问题整理成一个速查表按出现的频率从高到低排问题现象根因分析排查方法解决方案A找不到B的能力能力注册遗漏或技能标签不一致查目录服务的注册记录确认B上线时是否成功调用了注册接口统一技能标签词表注册后主动触发一次目录查询自检调用超时但任务其实完成了同步等待太长任务实际异步执行看Agent端日志确认任务执行时长改成异步回调模式不要用HTTP同步等待回调丢失导致调用方永远在等待回调URL不可达或回调消息无确认机制查回调目标端访问日志确认是否有请求到达增加回调重试机制回调失败时发送通知并记录到待处理队列同一个会话上下文错乱消息缺少会话ID或者会话ID生成逻辑不一致检查所有协作消息是否都携带了统一session_id在消息结构里强制要求session_id并增加会话维度的日志索引两个Agent互相认为对方是冒牌货身份验证不通过密钥或证书不匹配检查双方配置的私钥/公钥是否匹配把密钥轮换流程做成自动化轮换后自动重新注册目录数据越来越脏下线Agent没有反注册更新注册信息失败定期抽查目录中有多少Agent是“僵尸”增加“心跳租约”机制超期未续约的Agent自动标记为不可用5.1 最隐蔽的坑能力标签的“同级不同名”问题两个Agent都宣称自己有“translate”能力但A内部定义的是“translation”B定义的是“translate”——即便技能本质相同发现机制也匹配不上。这种问题的隐蔽性在于代码和日志看起来一切正常但协作就是建立不起来。建议从一开始就定义一套共享的能力词表类似协议里的枚举值新Agent上线时做词表校验不存在的标签不允注册。5.2 测试环境里容易忽略的“时间同步”问题在多Agent协作场景消息可能经过多个中转节点会话超时、任务过期都要依赖时间戳。如果各节点的系统时间不一致就会出现“回调比请求还早”、任务被误判为过期的诡异现象。在这个问题上建议所有Agent节点统一启用NTP时间同步并在关键判断逻辑里计算时间差容忍度而不是用死值做对比。5.3 网络拓扑变化对发现机制的影响容器化部署、动态扩缩容环境下Agent的IP和端点是会漂移的。如果你在注册信息里写死了IPAgent重启后目录里还是旧地址调用方自然会失败。这也是草案里强调“端点用稳定的服务名或网关地址”的原因。在测试环境我用的是localhost没什么问题但一旦跨容器、跨机器部署必须一开始就设计好地址注册与更新机制。6. 草案落地建议如果你要接ANP从这几个优先级开始最后聊点实际建议。如果你所在团队正在考虑接入ANP我建议不要一开始就追求全量协议特性而是按优先级逐步落地。6.1 第一步先把“身份与注册”做扎实无论你用不用协议的其他部分一套统一的Agent身份体系和注册发现机制都能立竿见影地降低系统复杂度。这一步做不好后面所有功能都很难可靠运行。建议先统一Agent ID生成规则、注册流程、密钥管理让每个Agent都能被目录准确找到。6.2 第二步把消息交互改成“异步回调”把同步调用逐步替换成异步消息回调是投入产出比非常高的一次改造。你会发现调用方Agent的并发能力明显提升不再被长任务阻塞失败重试的逻辑也更好写。注意设计好回调重试和超时告警避免任务“悄无声息”地丢失。6.3 第三步再上能力协商与安全加固能力协商不只是发现还包括确认参数、约束、费用等和安全加固传输加密、身份验证、审计日志可以放到后续阶段。协议草案期先把核心链路跑通、形态稳定再逐步补安全水位是更稳妥的路径。安全和协议演进可以并行做但别让安全设计成为验证核心机制的阻碍。6.4 最后积极回馈草案演进这一点容易被技术团队忽略但非常重要。草案期的协议是需要各方输入才能成熟的。如果你在实现过程中发现了字段缺失、流程矛盾、边界场景空白主动记录并向草案维护方反馈不仅能优化协议本身也能让你的实现与协议演进保持一致。自己做一套“私有方言”是最后的路短期方便、长期锁死。我个人在跑通最小链路后又做了一件小事把注册、发现、调用、回调的接口定义固化成一份OpenAPI描述文件让不同语言的Agent都能按这份定义生成客户端。这事不用等协议完全冻结越早做后面整个团队接入的摩擦就越小。Agent之间的“普通话”早学会的人早受益。
返回列表