文章指出智能体调用包含两层问题:模型侧通过函数调用或MCP发现工具,以及进程之间真正建立连接并传输请求。仅解决工具Schema不足以保证跨机器部署时的可达性与稳定性。
你想运行一个 AI Agent,让它把其他 Agent 当作工具调用:由一个编排 Agent 将子任务交给研究 Agent、编码 Agent 或人工审批 Agent。理论上,这只是工具调用——与调用计算器或网页搜索工具使用的是同一种机制。但在实践中,“调用 Agent”其实是两个叠加在一起的问题,而大多数教程只解决了其中一个。
第一个问题是框架层的工具调用:模型用来发现并调用工具的接口。第二个问题是传输层的 Agent 可达性:一个 Agent 的进程能否真正连接到另一个 Agent 的进程。它们属于不同的层。混淆这两者,正是许多多 Agent 系统在笔记本电脑上演示得非常漂亮,但 Agent 一旦部署到不同机器上就立刻崩溃的原因。
先来看看框架层实际上做了什么。LLM API 中的 function calling 会向模型提供一组带有 JSON schema 的类型化函数;模型返回结构化调用,再由你的运行时执行。MCP 在此基础上进一步实现了标准化——工具成为客户端可以发现和调用的资源,服务器则通过 stdio 或 HTTP 运行。
两者都确实很有用。尤其是 MCP,它是真正意义上的进步:一个客户端可以与多个服务器通信,而且整个生态正在快速发展。但请注意,它们都基于同一个前提:工具所在的进程是可达的。stdio MCP server 位于你的进程树中。HTTP MCP server 位于某个 URL 背后,而这个 URL 必须能够被解析、正确路由并接受连接。这两个层都没有任何机制,可以让云端 VPC 中的 Agent 访问一台位于 NAT 后方笔记本电脑上的 Agent。这本来就不是它们负责解决的问题。
下面这个场景会让演示系统失效。你的编排 Agent 运行在云端 VM 上,而你想作为工具调用的 Agent——可能保存着私有数据,或能触发只有它才有权限执行的操作——运行在家中的笔记本电脑上,或者位于客户的私有网络内部。
框架层已经准备就绪:编排 Agent 知道这个工具存在,也知道它的 schema,并且能够生成一个有效调用。随后调用被发送出去,却直接石沉大海。没有路由。NAT。防火墙只允许出站连接。IP 地址今天早上刚刚发生了变化。
这就是传输问题,也是“调用 Agent”中工具调用框架明确不会解决的另一半。常见的变通方案各有代价:暴露公共 endpoint(需要开放入站端口、使用静态 IP,还要持续维护 DNS)、轮询共享队列(带来延迟和状态管理问题),或者让所有东西都运行在同一台主机上(演示时没问题,但不适合生产环境)。
要让 Agent A 把 Agent B 当作工具调用,A 的进程就需要一条稳定、有效、能够连接到 B 进程的路径。这是一个网络问题,也有对应的网络层解决方案:为 Agent 构建 overlay network。它与 mesh VPN 属于同一类技术,但专门针对 Agent 的使用场景进行了设计:
每个 Agent 都拥有永久的虚拟地址,即使 IP 发生变化或 Agent 在不同云之间迁移,该地址仍然不变。
使用加密 UDP tunnel——X25519 key exchange、AES-GCM——确保 Agent 流量不会以明文形式暴露在公共互联网上。
通过 STUN、hole punching 和 relay fallback 实现 NAT traversal,让位于 NAT 后方的 Agent 无需开放入站端口也能被访问。
明确的信任机制:每个 peer 都需要完成 handshake 并获得双方批准,因此“已连接”绝不会在不知不觉间等同于“已信任”。
这一层的意义在于:可达性不再只是一个未经验证的假设。只要 Agent 位于网络中,它就会拥有一个其他 Agent 可以访问的地址,无论它实际运行在哪里。
因此,一个真正能够工作的多 Agent 系统包含两个层,而且二者缺一不可。
第一层——框架:模型发现工具并生成结构化调用。你可以使用 function calling,也可以使用由客户端和服务器组成的 MCP。
第二层——传输:各个进程之间能够相互访问。它需要稳定地址、加密 tunnel 和信任关系。
下面看看它在实践中是什么样子。继续使用 MCP 作为框架层——它很擅长解决这一层的问题。在它的底层部署一个 Agent-native network。例如,Pilot Protocol 提供了一个 MCP server(pilot-mcp),用于连接这两个层:你的 MCP client 会把其他 Agent 发现为工具,每次工具调用都会通过加密 tunnel 传输到位于 NAT 后方的 peer。模型看到的是一个普通工具,而在线路上传输的则是一个发往可达 peer 的请求。
传输层还提供了确保调用能够送达所需的底层管道:
# establish mutual trust with the agent you want to call
pilotctl handshake <peer> "orchestrator calling you as a tool"
pilotctl trust # confirm mutual trust
# then call it — stable address, encrypted tunnel
pilotctl send-message <peer> --data '{"task": "summarize the incident", "return": "tool_result"}'
由于工具层和传输层相互独立,工具本身也可以通过相同方式交付。Pilot 的 app store 将 capability app 作为类型化 IPC service 分发——输入 JSON,输出 JSON;安装后自动启动,并且能被网络中的 24.3 万多个 Agent 发现。整个流程是 pilotctl appstore catalogue → install → call:
pilotctl appstore catalogue
pilotctl appstore install <id>
pilotctl appstore call <id> <method> '{"query": "..."}'
模型的工具调用会变成一条发送给本地、经过签名验证的 app 的 JSON 消息。框架位于上层,传输位于下层——两者都被明确构建,而不是被默认为已经存在。
跳过框架层,你会得到一群虽然彼此可达、却没有任何东西能够调用的 Agent:进程之间可以通信,但没有模型驱动它们形成循环。跳过传输层,你会得到一套看起来非常漂亮的工具调用系统,但部署时,每一次对其他 Agent 的调用都会因连接错误而失败。前者是设计缺陷,后者则会耗掉你整个周末。
坦率地说:MCP 和 function calling 确实解决了一个真实问题——接口。不要在 overlay 上临时拼接一套自定义工具调用协议;应该使用标准的框架层。同样,也不要把可达性视为工具调用的实现细节;它是一种网络属性。使用生态系统已经标准化的框架解决接口问题,再通过底层的 Agent-native network 解决可达性问题——永久地址、NAT traversal 和明确的信任机制。
当你运行一个把其他 Agent 当作工具调用的 AI Agent 时,它会在线路层先于 schema 层失败。把这两个层都构建好,“调用 Agent”就会变成它在演示中一直呈现出的样子:只需一行命令,一切就能正常工作。
curl -fsSL https://pilotprotocol.network/install.sh | sh
接下来,请阅读 Pilot Protocol 文档,了解 MCP bridge 和 app store 命令。来源:github.com/pilot-protocol。
若要采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。