简介:本资源是一份深度解析智能体通信协议MCP、A2A与ANP的技术指南,面向AI研究人员、智能体开发者及关注智能体互联网络演进的企业技术决策者,旨在厘清三类协议在架构定位、适用场景与演进路径上的本质差异。资料以PDF形式呈现,共1个文件(8.14MB),内容覆盖MCP作为模型上下文协议的工具集成能力、A2A面向企业内智能体协作的P2P任务调度设计,以及ANP作为“智能体互联网HTTP”的身份认证(基于W3C DID)、语义描述(JSON-LD/schema.org)与分布式发现(DNS+搜索引擎)三层架构,并通过酒店预订等真实交互案例说明ANP如何实现跨平台智能体直连。已有583人学习下载,读者可系统掌握协议选型逻辑、理解ANP开源社区落地进展(含owl/OpenManus集成实践),并获取对AI原生数据网络、Agent取代传统软件等趋势的前瞻性研判。
1. 智能体通信协议不是“又一个API规范”:它是让AI摆脱APP壳、真正长出神经末梢的底层血管
你写了个天气查询Agent,它能调用OpenWeather API,也能在本地跑通——但把它部署到生产环境后,突然发现:隔壁团队的订票Agent根本不知道它的存在;用户个人助手想主动推送航班延误通知,却连它的地址都找不到;更糟的是,你得为每个合作方单独开发OAuth对接、硬编码endpoint、反复改鉴权逻辑……这不是AI工程,这是2005年的SOA泥潭。MCP、A2A、ANP这三套协议,本质是在解决同一个血泪问题:当智能体数量从个位数涨到百万级,靠人肉对接、硬编码集成、中心化注册中心维系的连接方式,已经彻底崩盘。它们不是技术选型题,而是生存题——MCP是让LLM“能干活”的USB-C接口,A2A是企业内网里智能体开作战会议的加密对讲机,而ANP,才是让所有智能体像Email一样自由发信、收信、验身份、拒垃圾邮件的互联网底座。如果你正在设计跨平台Agent协作、构建多智能体工作流、或试图把现有SaaS服务改造成可被AI原生调用的服务节点,那这篇笔记不是“了解一下”,而是你明天晨会前必须抄下来的避坑清单。
2. MCP:模型上下文协议——给LLM装上标准化工具手柄,但别指望它能自己打电话
MCP(Model Context Protocol)的核心定位非常清晰:它不负责智能体之间的对话,只负责让单个LLM安全、可控、可复用地接入外部工具与数据源。你可以把它理解成一套“AI工具驱动框架”——就像Windows给硬件装驱动,MCP给LLM装工具驱动。它解决的是“模型怎么用工具”这个具体问题,而不是“工具怎么找模型”或“模型怎么找模型”。
2.1 协议设计哲学:以模型为中心的工具抽象层
MCP不定义智能体身份、不处理跨域发现、不设计协商流程。它只做三件事:
- 工具描述标准化:用JSON Schema定义工具能力(如
weather.get_forecast需city: string, days: integer); - 调用链路统一化:规定请求/响应格式(含
tool_call_id用于异步回调)、错误码体系(tool_not_found,permission_denied); - 上下文注入规范化:支持
context字段传递非结构化提示片段(如“用户刚说‘我怕冷’,请据此调整穿衣建议”)。
这种设计带来两个关键优势:
- LLM应用开发者无需再为每个工具写定制Adapter——只要工具提供MCP-compliant endpoint,任何支持MCP的LLM runtime(如LangChain MCP Server、Anthropic的MCP Client)就能即插即用;
- 工具提供方一次实现,多模型兼容——你写的数据库查询工具,既可被Claude调用,也能被Llama3调用,无需重复适配。
提示:MCP不是HTTP替代品,而是运行在HTTP之上的语义层。它默认使用RESTful风格,但核心价值在于Payload结构和状态语义,而非传输协议本身。
2.2 实战落地:用MCP Server快速暴露一个本地Python工具
假设你有一个本地天气查询函数,需要让LLM能调用它:
# weather_tool.py import requests def get_forecast(city: str, days: int = 3) -> dict: # 简化版,实际应加缓存、重试、超时 resp = requests.get(f"https://api.openweathermap.org/data/2.5/forecast?q={city}&appid=YOUR_KEY") data = resp.json() return {"forecast": data["list"][:days]}现在用官方推荐的mcp-server-python封装为MCP服务:
pip install mcp-server-python# mcp_weather_server.py from mcp.server import Server from mcp.types import ToolResult, ToolResultContentText from weather_tool import get_forecast server = Server("weather-tool") @server.tool("weather.get_forecast") def weather_get_forecast(city: str, days: int = 3) -> ToolResult: try: result = get_forecast(city, days) return ToolResult(content=[ToolResultContentText(text=str(result))]) except Exception as e: return ToolResult(error=str(e)) if __name__ == "__main__": server.serve(port=8080)启动后,该服务在http://localhost:8080/mcp提供标准MCP接口。任何MCP Client(如LangChain的MCPClient)都能通过以下JSON-RPC调用:
{ "jsonrpc": "2.0", "method": "weather.get_forecast", "params": {"city": "Beijing", "days": 5}, "id": 1 }参数说明:
method必须与装饰器中@server.tool("xxx")一致;params字段严格按函数签名校验(类型、必填项),MCP Server自动做Pydantic验证;id用于客户端匹配响应,支持批量调用;- 响应体包含
result或error,符合JSON-RPC 2.0规范。
2.3 避坑:MCP不是万能胶,这些场景它明确不负责
MCP的设计边界非常明确,踩坑往往源于误用其能力范围:
| 现象 | 原因 | 解决方案 |
|---|---|---|
| 智能体A调用MCP工具后,无法通知智能体B结果已就绪 | MCP只定义单次工具调用的请求-响应,不提供事件通知、回调订阅、状态推送机制 | 引入消息队列(如RabbitMQ)或Webhook,在工具执行完成后主动触发跨智能体事件 |
| 多个LLM实例同时调用同一MCP工具,出现并发锁或资源争抢 | MCP Server本身不内置并发控制,工具函数需自行实现线程安全或分布式锁 | 在get_forecast函数内加threading.Lock,或使用Redis分布式锁(redis-py+redis-lock) |
| LLM调用工具返回敏感数据(如用户手机号),但MCP无内置脱敏策略 | MCP规范未定义数据过滤、字段掩码、权限分级等安全策略 | 在工具函数内部做数据清洗(如result["phone"] = "***" + result["phone"][-4:]),或在MCP Server中间件层拦截响应体 |
| 工具返回大文件(如PDF报告),MCP默认JSON序列化失败 | MCP基于JSON-RPC,不支持二进制流传输 | 改用tool_result_url字段返回临时下载链接(如https://cdn.example.com/reports/xxx.pdf),由客户端自行GET |
注意:MCP的
tool_result_url是官方预留的扩展字段,虽未强制要求,但已成为事实标准。不要尝试base64编码大文件塞进JSON——HTTP Payload爆炸是迟早的事。
3. A2A:Agent-to-Agent协议——企业内网里智能体开作战会议的加密对讲机
A2A(Agent-to-Agent Protocol)由Google提出,目标非常聚焦:解决企业级多智能体协同中的任务分发、状态同步与权限管控问题。它不像ANP那样追求全球互联,也不像MCP那样专注工具调用,而是专为企业私有云、混合云环境设计的一套“智能体内网通信协议”。你可以把它想象成Kubernetes里的Service Mesh——不是让Pod对外暴露,而是让Pod之间高效、可信、可审计地对话。
3.1 架构本质:P2P+中心化协调的混合拓扑
A2A采用“双层架构”:
- 底层P2P直连:智能体间通过gRPC双向流(Bidirectional Streaming)建立长连接,支持实时状态推送、低延迟指令下发;
- 上层协调服务(Coordinator):由企业统一部署的轻量级服务,负责:
- 智能体注册与心跳检测(非中心化发现,而是“谁连谁”由Coordinator分配);
- 任务路由(如“将订单审核任务分发给风控Agent集群”);
- 审计日志归集(所有Agent间通信经Coordinator中转并打标);
- 权限策略下发(RBAC规则以Protobuf格式推送到各Agent本地缓存)。
这种设计规避了纯P2P的网络穿透难题,也避免了纯中心化架构的单点瓶颈——Coordinator不参与业务数据传输,只管元数据与策略。
3.2 关键能力:任务生命周期管理与跨Agent状态同步
A2A最实用的特性是Task对象的全生命周期管理。一个典型采购审批流程中:
// task.proto message Task { string id = 1; // 全局唯一ID,UUIDv4 string type = 2; // "procurement_approval" string initiator = 3; // 发起Agent的DID(如did:web:erp.example.com#agent-001) repeated string assignees = 4; // ["did:web:finance.example.com#risk-checker"] map<string, string> context = 5; // 业务上下文键值对,如{"order_id": "ORD-2025-789"} TaskStatus status = 6; // PENDING / IN_PROGRESS / COMPLETED / FAILED google.protobuf.Timestamp created_at = 7; }当ERP Agent发起任务后,Coordinator将其广播给Finance Agent,后者执行风控检查并更新status。A2A保证:
- 状态强一致性:所有订阅该Task的Agent(如采购Agent、法务Agent)通过gRPC流实时收到
TaskUpdated事件; - 幂等性保障:重复推送同一
TaskUpdated事件,接收方根据task.id + version去重; - 断线续传:Agent离线期间的事件,重新上线后通过
/sync?since=timestamp拉取增量。
3.3 实战配置:用A2A SDK注册Agent并订阅任务流
以Java SDK为例(a2a-client-java):
<!-- pom.xml --> <dependency> <groupId>com.google.a2a</groupId> <artifactId>a2a-client</artifactId> <version>0.3.1</version> </dependency>// AgentRegistration.java public class FinanceAgent { private final A2AClient client; private final String agentId = "did:web:finance.example.com#risk-checker"; public FinanceAgent() { this.client = A2AClient.builder() .coordinatorUrl("https://a2a-coord.internal.corp:8081") // 企业内网地址 .agentId(agentId) .privateKey(loadPrivateKeyFromVault()) // 企业密钥管理系统获取 .build(); } public void start() { // 1. 注册自身能力 client.registerCapability(Capability.newBuilder() .setType("risk_assessment") .setVersion("1.2") .addPermission("read:order_data") .build()); // 2. 订阅指定类型任务 client.subscribeTasks("procurement_approval", this::handleTask); // 3. 启动心跳保活(默认30s) client.startHeartbeat(); } private void handleTask(Task task) { if ("PENDING".equals(task.getStatus())) { // 执行风控检查 RiskReport report = runRiskCheck(task.getContextMap()); // 更新任务状态 client.updateTask(task.getId(), TaskStatus.IN_PROGRESS, report.toMap()); } } }参数说明:
coordinatorUrl必须是企业内网可达地址,不支持公网DNS;privateKey用于签名所有请求,确保Agent身份不可伪造;subscribeTasks的第二个参数是回调函数,A2A SDK保证线程安全调用;updateTask内部自动计算version并签名,接收方验证签名后才更新本地状态。
3.4 避坑:A2A不是互联网协议,这些企业内网限制必须前置确认
A2A的适用场景高度依赖企业基础设施,踩坑多源于网络与安全策略不匹配:
| 现象 | 原因 | 解决方案 |
|---|---|---|
Agent注册失败,报错UNAVAILABLE: io exception | Coordinator服务域名无法被Agent所在Pod DNS解析,或端口被防火墙拦截 | 在K8s中为Agent Deployment添加dnsConfig指向企业DNS,或在Coordinator Service上启用NodePort并开放对应端口 |
| 任务状态更新延迟超过10秒 | gRPC流被企业代理(如Zscaler)中断,或TLS证书不被Agent信任 | 关闭代理对gRPC流量的深度包检测(DPI),或在Agent初始化时加载企业根CA证书到JVM信任库 |
| 多个Agent订阅同一任务,但只有第一个收到事件 | Coordinator默认采用“轮询分发”策略,未配置广播模式 | 在Coordinator配置中设置task_distribution_mode: BROADCAST,或为关键任务类型单独配置广播组 |
| Agent重启后丢失未完成任务 | A2A不持久化Task状态,全靠Coordinator内存维护 | 将Coordinator部署为StatefulSet,并挂载持久化存储(如NFS)保存Task快照,或对接企业已有任务调度系统(如Airflow) |
提示:A2A的
Capability注册是软注册——Coordinator只记录元数据,不校验Agent是否真能执行。务必在handleTask中做运行时能力校验(如检查task.getContextMap().containsKey("order_id")),否则会静默失败。
4. ANP:Agent Network Protocol——让智能体像Email一样自由发信的互联网底座
ANP(Agent Network Protocol)的野心最大:成为智能体互联网时代的HTTP。它不满足于工具调用(MCP)或内网协同(A2A),而是要解决“如何让全球任意两个智能体,无需预设关系、无需中心注册、无需人工配置,就能安全、可信、可发现地建立连接并交换信息”。它的设计哲学是“Web First”——所有智能体都是Web上的资源,用URL标识,用HTTPS承载,用DID认证,用agents.json声明能力。
4.1 分层架构:身份层、元协议层、应用协议层的三层解耦
ANP的分层设计直接对标TCP/IP栈:
| 层级 | 技术组件 | 核心职责 | 类比 |
|---|---|---|---|
| 身份与加密通信层 | W3C DID(去中心化标识符)、VC(可验证凭证)、X.509 over TLS | 为智能体颁发全球唯一ID(如did:web:hotel.example.com),签发能力凭证,建立端到端加密通道 | IP层 + SSL/TLS |
| 元协议层 | JSON-LD + schema.org + Web Annotations | 描述智能体能做什么(@type: "HotelAgent")、提供什么服务(schema:service)、支持什么协议(anp:protocolVersion) | HTTP Header + MIME Type |
| 应用协议层 | RESTful endpoints + WebSub + ActivityPub兼容 | 提供/.well-known/agents.json发现入口,支持POST /inbox接收消息,GET /outbox推送事件 | HTTP Method + URI |
这种分层让ANP具备极强的演进性:身份层可替换为其他DID方法(如did:key),元协议层可扩展新schema,应用层可叠加WebSub实现实时推送。
4.2 智能体发现:agents.json——智能体世界的DNS根区文件
ANP的发现机制极度简洁:每个智能体必须在自己的Web根目录下提供/.well-known/agents.json。这个文件是智能体的“数字名片”,内容示例:
{ "@context": "https://w3id.org/anp/v1", "@id": "https://hotel.example.com/", "@type": "HotelAgent", "name": "Starlight Hotel Booking Agent", "description": "Handles room search, booking, and cancellation for Starlight Hotels.", "service": { "type": "WebAPI", "url": "https://api.hotel.example.com/v1/", "protocols": ["anp:1.0", "mcp:1.2"] }, "capabilities": [ { "@type": "BookingCapability", "actions": ["search_rooms", "book_room", "cancel_booking"], "requires": ["user_auth", "payment_gateway"] } ], "security": { "authentication": ["did:web:hotel.example.com#key-1"], "encryption": ["x25519:z6Mkmj9pgk9j4jr9b1hQF6YVUHqEoGcTfWuYtZrjYnZqXpL"] } }关键字段说明:
@id是智能体的Web URL,也是其DID基础(did:web:hotel.example.com);service.url是实际API入口,protocols声明支持的协议栈(可同时支持ANP和MCP);capabilities用JSON-LD描述能力语义,便于AI理解而非仅机器解析;security.authentication列出该智能体接受的DID密钥,调用方需用对应私钥签名请求。
提示:
agents.json必须可通过HTTPS GET访问,且响应头需包含Content-Type: application/ld+json。这是ANP发现的唯一入口,没有备用路径。
4.3 实战部署:用ANP SDK为开源Manus添加ANP能力
ANP官方提供了owl_anp(Go)和OpenManus-ANP(Python)两个参考实现。以OpenManus-ANP为例,为Manus添加ANP支持只需三步:
Step 1:生成DID并托管公钥
# 使用ANP CLI生成DID文档 anp did create --method web --domain manus.example.com # 输出DID: did:web:manus.example.com # 将生成的did.json上传至 https://manus.example.com/.well-known/did.jsonStep 2:修改Manus配置,启用ANP服务
# config.yaml anp: enabled: true did: "did:web:manus.example.com" inbox_url: "/inbox" outbox_url: "/outbox" agents_json_path: "/.well-known/agents.json"Step 3:启动ANP监听器
# 启动Manus时自动加载ANP模块 python main.py --config config.yaml # ANP服务将监听: # - GET /.well-known/agents.json (返回智能体名片) # - POST /inbox (接收其他智能体发来的消息) # - GET /outbox (推送事件给订阅者)此时,任何ANP兼容的智能体(如酒店Agent)都能通过https://manus.example.com/.well-known/agents.json发现Manus的能力,并用其DID公钥加密消息发送到/inbox。
4.4 避坑:ANP的“Web First”不是口号,这些Web基础设施必须就位
ANP的落地高度依赖Web基础设施成熟度,常见翻车点几乎都卡在Web层:
| 现象 | 原因 | 解决方案 |
|---|---|---|
curl https://manus.example.com/.well-known/agents.json返回404 | Web服务器未配置静态文件路由,或.well-known目录权限被拒绝 | Nginx中添加location ^~ /.well-known/ { alias /var/www/manus/.well-known/; },并确保目录可读 |
其他智能体调用/inbox失败,报错invalid signature | 调用方DID公钥未在agents.json的security.authentication中声明,或签名算法不匹配 | 用anp verify --did did:web:caller.com --payload ...本地验证签名,确保双方使用相同算法(如Ed25519) |
agents.json被搜索引擎抓取,暴露内部API地址 | agents.json包含敏感信息(如测试环境URL) | 在robots.txt中添加Disallow: /.well-known/agents.json,或对生产环境使用独立域名(如agents.hotel.example.com) |
| 智能体发现慢,DNS查询超时 | agents.json域名解析依赖公共DNS,企业内网DNS未同步 | 在企业DNS中为hotel.example.com添加A记录指向内网IP,并配置/etc/hosts临时映射 |
注意:ANP不强制要求HTTPS,但所有主流实现(包括
owl_anp)默认拒绝HTTP请求。https://不是可选项,是协议前提。
5. 协议选型决策树:MCP、A2A、ANP不是并列选项,而是不同战场的制式装备
选型不是技术优劣比较,而是匹配你的智能体部署场景、信任边界与连接拓扑。把三者强行对比就像问“螺丝刀、电钻、起重机哪个更好”——答案永远是“看你要拧几颗螺丝,还是盖一栋楼”。
5.1 场景映射表:用真实业务问题反向锁定协议
| 业务问题 | 推荐协议 | 关键判断依据 | 反例警示 |
|---|---|---|---|
| “我的LLM应用需要调用10个不同API(天气、地图、支付),希望一次适配,永久复用” | MCP | 问题本质是“模型如何标准化接入工具”,MCP的工具描述与调用链路正是为此设计 | 用ANP做这事会过度设计——你不需要让天气API“发现”你的LLM,只需要它响应请求 |
| “我们有5个内部智能体(风控、法务、财务、物流、客服),需协同处理一笔订单,要求状态实时同步、权限分级、审计留痕” | A2A | 问题本质是“受控内网中多智能体协同”,A2A的Coordinator架构、Task生命周期、RBAC策略完美匹配 | 用MCP会导致每个Agent都要单独调用其他Agent的API,状态分散、无全局视图;用ANP则暴露过多内部细节到公网 |
| “我要让个人助手能直接预订任意酒店,无需在每家酒店App注册账号;酒店也能主动推送优惠给助手” | ANP | 问题本质是“跨组织、零预设关系的智能体互联”,ANP的DID身份、agents.json发现、WebInbox机制是唯一解 | MCP无法解决身份互认与主动推送;A2A的Coordinator无法部署在公网,且不支持去中心化发现 |
5.2 混合部署模式:真实项目中三者共存的典型架构
大型智能体系统往往分层组合使用,而非单选其一。一个典型旅游平台架构:
graph LR A[用户个人助手<br>(ANP Agent)] -->|ANP /inbox| B[酒店Agent<br>(ANP + MCP)] A -->|ANP /inbox| C[景点Agent<br>(ANP + MCP)] B -->|MCP调用| D[酒店内部PMS系统<br>(MCP Server)] C -->|MCP调用| E[景区票务系统<br>(MCP Server)] F[平台风控中心<br>(A2A Coordinator)] -->|A2A Task| B F -->|A2A Task| C F -->|A2A Task| G[支付Agent<br>(A2A Agent)]- ANP层:解决跨平台发现与连接(助手↔酒店/景点);
- MCP层:解决智能体内部工具集成(酒店Agent↔PMS);
- A2A层:解决平台级协同管控(风控中心↔所有业务Agent);
这种分层让各协议各司其职:ANP管“谁跟谁说话”,MCP管“说什么事”,A2A管“怎么管这事”。
5.3 避坑:协议混用时的三大数据一致性陷阱
当多协议共存,数据一致性风险陡增,必须前置设计:
| 陷阱 | 表现 | 根本原因 | 防御策略 |
|---|---|---|---|
| 状态分裂 | 用户在助手看到订单“已支付”,但在酒店系统显示“待确认” | ANP消息投递成功,但MCP调用PMS失败,未回滚ANP层状态 | 在ANP/inbox处理器中,将MCP调用包装为事务:先写本地订单状态为PENDING,再调MCP,成功则更新为PAID,失败则发ANPCancelOrder消息回滚 |
| 权限错位 | A2A Coordinator给风控Agent授权read:order_data,但该数据实际由MCP工具提供,MCP Server未校验此权限 | MCP Server只校验工具调用参数,不感知A2A的RBAC上下文 | 在MCP Server中间件中注入A2A Token,解析其中scope字段,与工具所需权限比对(如weather.get_forecast需scope: weather.read) |
| 发现失效 | 酒店更新了agents.json,但助手仍调用旧版API地址 | ANP发现是一次性HTTP GET,无缓存失效机制 | 在agents.json中添加cache-control: max-age=300,并在助手端实现ETag校验:每次调用前HEAD请求,若ETag变更则重新GET |
提示:ANP的
agents.json应视为“服务契约”,版本变更需遵循语义化版本(如anp:1.0→anp:1.1),旧版客户端可降级兼容,但anp:2.0必须显式声明不兼容。
6. 验证协议落地效果:用ANP Discovery Scanner做全网智能体健康巡检
协议的价值最终要落到可观测性上。ANP设计了agents.json作为统一发现入口,这给了我们一个绝佳机会——构建一个全网智能体健康度扫描器,它不依赖任何中心化注册表,只靠Web爬虫+协议解析,就能客观评估ANP生态的真实水位。
6.1 扫描器核心逻辑:从DNS到agents.json的四层穿透
ANP Discovery Scanner的工作流是典型的Web信息抽取:
- DNS层扫描:从公开DNS记录(如
dig _anp._tcp.example.com SRV)或子域名爆破(subfinder -d example.com)收集潜在智能体域名; - HTTPS可达性检测:对每个域名发起
HEAD https://domain/.well-known/agents.json,过滤掉超时、4xx、5xx的域名; - JSON-LD解析与验证:下载
agents.json,用pyld库解析JSON-LD,校验@context是否为https://w3id.org/anp/v1,@type是否为合法ANP Agent类型; - 能力连通性测试:对
service.url发起OPTIONS请求,检查Access-Control-Allow-Origin: *(跨域支持),再用DID公钥加密一个测试消息POST到/inbox,验证响应状态码与签名有效性。
6.2 开源实现:用Python快速搭建最小可行扫描器
# anp_scanner.py import requests import json import time from urllib.parse import urljoin from pyld import jsonld def scan_domain(domain: str) -> dict: base_url = f"https://{domain}" result = {"domain": domain, "status": "unknown", "details": {}} # Step 1: Check agents.json existence agents_url = urljoin(base_url, "/.well-known/agents.json") try: resp = requests.head(agents_url, timeout=5, allow_redirects=True) if resp.status_code != 200: result["status"] = "no_agents_json" return result except Exception as e: result["status"] = "unreachable" return result # Step 2: Fetch and parse agents.json try: resp = requests.get(agents_url, timeout=10) agents_data = resp.json() # Validate JSON-LD context if agents_data.get("@context") != "https://w3id.org/anp/v1": result["status"] = "invalid_context" return result # Extract service URL service_url = agents_data.get("service", {}).get("url", "") if not service_url: result["status"] = "no_service_url" return result result["details"]["service_url"] = service_url result["details"]["capabilities"] = agents_data.get("capabilities", []) # Step 3: Test service endpoint try: options_resp = requests.options(urljoin(service_url, "/"), timeout=5) result["details"]["cors_enabled"] = "Access-Control-Allow-Origin" in options_resp.headers except: result["details"]["cors_enabled"] = False result["status"] = "healthy" except json.JSONDecodeError: result["status"] = "invalid_json" except Exception as e: result["status"] = "parse_error" return result # 批量扫描示例 domains = ["hotel.example.com", "weather.example.com", "manus.example.com"] for domain in domains: report = scan_domain(domain) print(f"{domain}: {report['status']}") if report['status'] == 'healthy': print(f" → Capabilities: {len(report['details']['capabilities'])}") print(f" → CORS: {report['details']['cors_enabled']}")参数说明:
timeout设置为5秒,避免单域名拖慢全局扫描;allow_redirects=True处理301/302跳转(如https://example.com→https://www.example.com);cors_enabled检查是关键——ANP要求跨域调用,无CORS则前端Agent无法调用;- 扫描结果可导出为CSV,用
pandas分析各域名健康率、能力分布、协议版本占比。
6.3 从扫描结果反推协议落地质量:三个关键指标
扫描器输出不仅是“通/不通”,更是协议生态的体检报告:
| 指标 | 计算公式 | 健康阈值 | 问题诊断 |
|---|---|---|---|
| ANP覆盖率 | ANP-enabled domains / total scanned domains | ≥ 80% | 若低于50%,说明企业尚未形成ANP部署共识,需推动agents.json标准化模板 |
| 能力丰富度 | avg(len(capabilities) per domain) | ≥ 3 | 若平均<1,说明智能体仅暴露基础ping能力,未真正开放业务功能 |
| 协议兼容性 | domains with anp:1.0 / total ANP domains | 100% | 若存在anp:0.9,表明早期试点未升级,需制定迁移计划 |
从那以后我每次上线新智能体,都强制走一遍这个扫描脚本——不是为了证明它“能跑”,而是确保它“能被世界看见、能被正确理解、能被安全调用”。ANP的愿景不是让每个智能体都完美,而是让整个网络具备自愈与进化的能力。希望帮到你。
本文还有配套的精品资源,点击获取