【免费下载链接】agentmesh
Agent Mesh
Agent Mesh 是面向 AI Agent 的开源 P2P 服务发现与调用网络:每个 Agent 身边运行一个agentmesh-node,把 MCP 工具、大模型和 A2A 智能体发布出去,其他节点即使躲在 NAT、防火墙或移动网络后面也能互相找到、互相调用。它的底层由三件技术协同完成:libp2p 传输层负责"连得上",路由器之间共享的 Kademlia DHT 负责"找得到",Relay v2 中继加 hole punching 负责"两端都进不来时也能通"。这篇文章用通俗的语言把这三层原理一次讲透 🔍
一、为什么 Agent 需要一张能穿越 NAT 的网络
大多数 Agent 并不跑在"人人可直达"的服务器上:
- 🏠 笔记本、手机上的本地 Agent
- 📦 容器与 Kubernetes 集群里的 Agent(出站有公网,入站被 SNAT 挡住)
- ☁️ 多台云服务器,彼此在 NAT 之后
传统做法是"每台机器都要有公网地址 + 端口映射",这对上面三种场景几乎全部失效。Agent Mesh 的设计目标是:能直连就直连,连不上就走中继,而且任何节点默认都不可达,必须持有一个可离线验证的凭证。
整个网格由三种角色构成 🧩:
| 组件 | 职责 | 源码位置 |
|---|---|---|
agentmesh-control-plane | 审核谁可以加入、签发凭证、保存策略(不在数据路径上) | internal/controlplane/server.go |
agentmesh-router | 固定可拨号的中转点:运行 DHT、维护服务目录、中继流量 | internal/router/router.go |
agentmesh-node | 紧贴你的 Agent:发布服务、发现服务、验证对端、代理请求 | internal/node/node.go |
节点加入网格时,通过一次性的 bootstrap token 或浏览器 OIDC 登录完成注册,这是后文一切安全机制的前提:
二、libp2p 传输底座:一条连接跑所有协议
每个节点都是一个 libp2p peer:持有自己的 Ed25519 私钥,peer ID 直接由密钥推导,整个网络只认 peer ID,不认 IP —— 这正是"节点换网、换 NAT 后一切照常"的根源。
节点启动时(见 internal/node/node.go)打开了一整套"穿越 NAT 工具箱":
- 多传输:默认同时监听 QUIC(
udp/5001)和 TCP(tcp/5002);路由器额外提供 WebSocket / WebTransport / WebRTC 给浏览器端 - 安全层:优先 TLS 1.3,Noise 作为浏览器可用的备选。两种握手都把连接绑定到对端 peer ID
libp2p.EnableRelay()+libp2p.EnableHolePunching():中继客户端与打洞能力(后文详述)libp2p.EnableAutoNATv2():由路由器拨号回测,判断自己是否对外可达- TCP 优先的拨号策略(
tcpFirstDialRanker):TCP 地址立即拨,QUIC 地址延后 250ms。原因是 QUIC 连接固定只有 256 个流,而节点与路由器之间的一条连接要为"每一个经它中继的对端"各挂一个流,TCP(yamux)没有这个限制
值得注意:NAT/防火墙只为"连接"建表,不为"流"建表,keepalive 每 15~30 秒一跳,空闲连接也能保持穿透。
三、Kademlia DHT 服务发现:谁在提供什么服务?
"网格里有谁、提供什么服务"这张目录表,并不存在某台中心服务器上,而是由所有路由器共同维护的 Kademlia DHT承载。这是 Agent Mesh 最有意思的一处设计取舍:
只有路由器跑 DHT,节点不跑
节点自身不维护任何 DHT,只与它持有的 2 个路由器保持会话。DHT 的重活(表、复制、查询)全部由路由器承担,节点侧开销极低——这是单节点空闲仅约 55 MiB 内存、支撑 10000 成员测试网的关键之一。
路由器以 Server 模式运行 Kademlia(internal/router/dht.go),路由器之间互为全网格,bucket 大小为 64,并用/mesh协议前缀把这张表与公网 DHT 完全隔离。而且只有完成认证的路由器才会进入路由表(admitPeerRouter),未认证的 peer 拿不到任何目录服务。
记录放在"离 key 最近"的路由器上
节点发布服务(比如mcp://code-reviewer)时,把记录交给它持有的路由器。路由器做两件事:
- 自己留存一份副本(带 TTL 的 recordStore)
- 通过 DHT 路由表找出离这个服务名 key 最近的
replication个路由器(默认 3 个),把副本放上去(closestRouters、placeRecord)
节点每 5 分钟(--dht-reprovide-interval)重新宣告一次;下线时主动撤回记录;忘记撤回的记录会在三个周期后自动过期。
一次查询的完整旅程
当某个 Agent 想调用远端工具时,discover_remote_services背后的流程是:
- 节点向它持有的路由器发起
find_providers请求 - 路由器先查本地记录,同时并发询问 key 最近的 3 台路由器(每台 5 秒超时)
- 合并、按新鲜度过滤后返回提供者列表及可达地址
整个过程节点只问了它认识的路由器,DHT 查询被封装在路由器之间——目录对未注册者完全关闭 🔒
四、Relay 中继:两端都进不来,怎么办?
预留 relay 通道(reservation)
"双方都无法接受入站连接"是常态,libp2p 的解法是Circuit Relay v2:节点先向一台自己有直连的中继(路由器)申请预留,成功后它就能被访问于形如/p2p/<router-peer-id>/p2p-circuit的地址。
Agent Mesh 的做法(internal/node/node.go):
- 每个节点持有2 个路由器,并在每个上通过 AutoRelay 维护一份预留(
WantRouters=2),路由器列表打散随机,让整支舰队的预留均匀铺开 - 预留成功后,路由器把该节点的 circuit 地址写入 peerstore,于是任何路由器都能从 DHT 查到"这个节点经由我可达"
- 节点默认
--reachability private:无论 AutoNAT 探测结果如何都持有预留,确保在任何 NAT 背后都可达
中继不是免费的:ACL 与预算
路由器上开了 Relay 服务,但层层设卡(internal/router/router.go、relay_limit.go):
| 关卡 | 规则 |
|---|---|
预留 ACL(AllowReserve) | 被 ban 的 peer 一律拒绝;未通过凭证握手的 peer 拒绝 |
建路 ACL(AllowConnect) | 源和目的两端都必须已认证——路由器只在中继"它验证过的两个成员之间"转发 |
| 预算 | 单 peer 最多 1024 条中继连接、单条默认 1 小时超时 + 数据量上限,超了即切断 |
Hole punching:中继连接自动升级直连 🕳️
Relay 只是保底,不是终点。因为节点启用了libp2p.EnableHolePunching(),一次中继连接建立后,两端会尝试DCUtR 打洞:向对端的公网侧地址发起"同时拨号",若 NAT 恰好放行,连接就无缝升级为点对点直连,中继随即退出数据路径。打洞不改变 TCP 优先的常规拨号顺序(它对所有地址同时尝试)。
效果是:手机、笔记本、容器组成的网格,大部分流量最终跑在直连上,中继只兜底最坏情况。
五、安全边界:中继看到的只是密文
P2P 网络里"中继节点"天然是个敏感角色,Agent Mesh 的防线是:
- 每一跳之间都有独立加密的安全通道(TLS 1.3 或 Noise),且绑定 peer ID——中继转发的是端到端密文,只知道"两个成员在说话",不知道内容
- 成员与路由器、调用方与提供方之间都先跑一次凭证握手(验证控制平面签发的 Biscuit 令牌),验证失败或凭证过期,目录、Gossip、Relay 全部拒绝服务
- 控制平面只看到注册、刷新、租约等管理流量,永远不在数据路径上
换句话说:被攻陷的路由器能"拒绝服务",但不能"偷看数据"或"授予权限" ⚖️
六、源码导读:从哪些文件开始读
想亲手验证本文的每个说法,推荐按这个顺序 👇
- internal/node/node.go —— 节点 libp2p 选项全集:Relay、HolePunching、AutoNAT v2、AutoRelay 预留
- internal/router/router.go —— 路由器启动流程:DHT 初始化、Relay 服务、GossipSub、鉴权流
- internal/router/dht.go —— Kademlia 参数:bucket 64、
/mesh前缀、仅认证 peer 入表 - internal/router/directory.go —— 目录服务:
closestRouters与记录放置 - internal/router/relay_limit.go —— Relay 预算如何随网格规模放大
- 官方文档:Networking 概念文档、架构文档、可扩展性指南
公开测试网的数据可以佐证这套设计:6 台 2 vCPU 的路由器承载了 10000 个成员,全程无掉线(见 site/content/docs/guides/scalability.md)。
七、总结:一张表看懂"穿越 NAT 的魔法"
| 问题 | 用到的技术 | 发生在哪里 |
|---|---|---|
| 我到底有没有公网可达? | AutoNAT v2 拨号回测 | 节点 ↔ 路由器 |
| 找不到对方怎么发现? | Kademlia DHT(仅路由器维护)+ 服务目录 | 路由器全网格 |
| 两端都在 NAT 后面? | Relay v2 预留 + circuit 建路 | 节点 ↔ 路由器 ↔ 节点 |
| 直连机会出现了? | Hole punching(DCUtR)自动升级 | 打洞成功即脱离中继 |
| 怎么防止中继被滥用? | 双端凭证 ACL + 连接/时长/流量预算 | 路由器 |
| 内容会不会泄露? | TLS 1.3 / Noise 端到端加密 | 每一跳 |
Agent Mesh 把 libp2p 的传输能力、Kademlia DHT 的去中心化寻址和 Circuit Relay 的兜底中继组合成了一套完整的"最后一公里"方案:AI Agent 从此不需要公网 IP、不需要端口映射,也能在笔记本、手机和集群之间自由发现彼此、调用彼此的服务 🚀
【免费下载链接】agentmesh
Agent Mesh
相关推荐
iroh 中继(Relay)机制全解析:Home Relay 选择、NAT 穿越与本地 iroh-relay 部署指南
iroh 中继(Relay)机制全解析:Home Relay 选择、NAT 穿越与本地 iroh relay 部署指南 iroh 的核心设计理念是"IP 地址会
网络通信RL Swarm节点发现机制:DHT与Kademlia算法详解
RL Swarm节点发现机制:DHT与Kademlia算法详解 RL Swarm是一个完全开源的框架,用于在互联网上创建RL训练集群。其核心功能之一是通过分布式
人工智能强化学习分布式训练大模型微调如何高效实现BitTorrent DHT路由表:Kademlia算法在Go中的完美应用指南
如何高效实现BitTorrent DHT路由表:Kademlia算法在Go中的完美应用指南 BitTorrent DHT(分布式哈希表)是P2P网络的核心组件,
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考