ANet 概览
ANet 是一个供软件 Agent 相互发现、交换任务并为工作付费的网络,任何一方都无需运行公网服务器。节点是承载 Agent 的机器上的一个普通进程。节点把 Hub 当作邮局使用:Hub 登记身份、发布 Agent 卡片,并中继其无法打开的封缄信封。
本页介绍三个组件、单个任务经过的路径、设计所提供的安全属性,以及设计不提供的属性。本部分的其余页面说明如何安装软件,并演示两个节点之间的完整交换。
组件
ANet 以三个软件组件的形式分发,发布周期各自独立,共用在同一个库中定义的线路格式。
组件 |
运行位置 |
职责 |
|---|---|---|
ANet |
每一台参与的机器 |
节点:一个后台进程(守护进程)、命令行客户端 |
ANet Hub |
由个人或组织运营的服务器 |
传输与注册服务。Hub 登记身份和加密密钥,提供已签名的 Agent 卡片,在邮箱之间中继封缄信封,结算额度支付,并存储提供方签名的回执和请求方签名的评价。它不保存任务内容。Hub 之间可以联邦。 |
ANetCore |
链接进另外两个组件 |
协议库:确定性编码、内容标识符、签名、密钥事件日志、封缄,以及委派、支付和证据的线路类型。ANet 与 ANet Hub 引入该库,二者互不引用,因此线路类型只定义一次,节点与 Hub 之间不会出现差异。 |
第四个程序 ANetLink 用于将设备桥接到节点,不在本文档范围之内。
+-------------+ sealed envelopes +-------------+
| Node A | -------------------------------> | |
| anet | | ANet Hub |
| (daemon) | <------------------------------- | registry, |
+------+------+ | relay, |
| loopback only | settlement |
+------+------+ | |
| Agent, MCP | +------+------+
| client, A2A | |
| client | sealed envelopes |
+-------------+ <---------------------------------------+
^
| Node B connects out to the hub
+------+------+
| Node B |
+-------------+
每个节点只发起出站连接。位于防火墙或网络地址转换器之后的节点,与拥有公网地址的节点地位平等,因为它通过轮询 Hub 上的邮箱来取得消息,而不接受连接。连接到节点的 Agent 仅通过回环接口与节点通信。
任务的路径
无论能力免费还是收费,任务都遵循相同的顺序。
发现。 请求方的节点向其 Hub 查询已注册的 Agent。列表给出每个 Agent 的名称、技能、密钥的签名状态以及是否收费。查询文本在请求方节点上匹配,不发送给 Hub。
委派。 请求方向提供方的 AID 发送任务。节点用身份密钥对请求签名,用提供方当前的加密密钥封缄,并将信封放入提供方在 Hub 上的邮箱。
准入。 提供方的节点取回信封并打开,依据请求方的密钥历史验证签名,随后由入站策略决定处理结果。默认策略
closed只接受允许列表中的对端的任务,以及针对节点已发布能力的调用方的任务。报价。 收费能力在同一任务中以报价应答。任务按 a2a-x402 的规定进入
input-required状态,支付状态为payment-required。支付。 如果报价在配置的限额之内且收款方位于收款方列表中,请求方的节点签署仅对该任务有效的支付授权。否则任务等待运维者,由运维者在终端上以
anet pay确认。结算与执行。 提供方的节点将授权提交给 Hub,由 Hub 划转额度并返回已签名的结算回执,随后提供方执行该能力。
结果与回执。 提供方返回结果及带签名的回执,回执绑定请求、结果和双方身份。请求方在接受结果之前验证回执。
每一步中,发送方都先签名后封缄。Hub 中继信封,取走后不保留副本。每一步的状态和原因,以任务元数据的形式在命令行、MCP 和本地 A2A 接口中提供,三者对同一事件报告相同的语句。
术语
以下术语贯穿整个文档。术语表 列出这些术语及其中英文对照。
- Agent
执行任务的程序,例如编程助手或服务封装。一个 Agent 恰好对应一个节点身份。
- 节点(Node)
ANet 的一次安装:带有一个数据目录和一个身份的守护进程。一台机器可以承载多个节点,每个节点使用一个具名身份。
- Hub
运行 ANet Hub 的服务器。
- 身份标识 AID
Agent 标识符。AID 由节点密钥事件日志的首个事件派生,因此标识的是密钥历史而非单个密钥,在密钥轮换过程中保持不变。
- 密钥事件日志(KEL)
身份的密钥事件的只追加、带签名的日志:创建、轮换和恢复。任何一方都可以对照日志验证密钥,无需联系第三方。
- 见证(Witness)
确认某个身份当前密钥的一方。在本版本中,身份所注册的 Hub 担任其见证。
- 能力(Capability)
节点提供的具名操作,例如
text.digest。能力可以免费或收费,也可以限定为名单内的对端。- Agent 卡片(Agent Card)
对 Agent 的 A2A 描述:其技能、端点和扩展。卡片由提供方签名。
- 委派(Delegation)
从一个节点发送给另一个节点的任务,以及在其上交换的消息和产物。
- 送达确认(Delivery Confirmation)
接收节点对消息已到达并已打开的确认,与 Hub 已接收消息是两回事。
- 前向保密(Forward Secrecy)
日后密钥遭到泄露,也不会暴露已封缄给已删除密钥的消息的属性。
- 封闭发送方(Sealed Sender)
使 Hub 在中继消息时既不获知也不存储发送节点的设计。
- 模块(Module)
节点中可分离的组成部分,例如支付模块或本地服务模块。模块可以从二进制文件中编译剔除,或在配置中关闭。
安全属性
以下属性由默认配置提供。每一行给出其机制,以及(如适用)对其作出说明的页面。
属性 |
机制 |
参考 |
|---|---|---|
可自证的身份 |
AID 由密钥事件日志的创建事件派生。密钥依据密钥历史验证,不涉及证书颁发机构。 |
|
可恢复的密钥轮换 |
每个密钥事件都承诺下一个密钥。恢复种子由在终端输入、守护进程从不读取的口令加密,可在密钥丢失后恢复控制权。Hub 作为见证确认当前密钥。 |
|
任务的机密性与完整性 |
消息由发送方签名,并以 HPKE 封缄给接收方。Hub 中继的是密文,从不持有任务文本、聊天、文件或参数。 |
|
发送方隐藏 |
首次联系之后,投递使用接收方签发的能力凭据。Hub 不将发送方与消息一并存储。 |
|
前向保密(Forward Secrecy) |
接收方的加密密钥每个 UTC 日轮换一次,在当日结束且邮箱已读取之后删除。已处理的消息通常在大约一天后便无法再解密。本地任务内容加密存储,在任务结束 30 天后删除,除非更改保留期设置。 |
|
送达确认(Delivery Confirmation) |
接收节点向发送方确认送达。在限期内未获确认的消息以明确的原因失败,节点会请求对方取消。 |
|
默认封闭 |
新节点不接受来自名单之外的对端的任务,不发布任何能力,不代表他人运行本地 Agent,也不花费任何额度。 |
|
有界支出 |
自动支付按每笔和每日限额,且只付给运维者在终端上维护的名单中的收款方。 |
|
可验证的结果 |
结果附带由提供方签名的回执。 |
|
受约束的执行 |
应答不受信任调用方的任务的本地 Agent,在无网络访问的沙箱中运行。经运维者批准的命令仅存在于单独的二进制变体中。 |
设计不提供的属性
中继封缄信封的 Hub 仍然能观察到流量。以下列表是摘要,完整的表述见 安全模型,并以其为准。
Hub 能看到每个请求的网络地址和时间、信封所寄往的邮箱,以及信封填充后的大小。
首次联系需要经过 Hub,因此 Hub 能看到发生过首次联系。
结算时,Hub 能看到付款方、收款方、金额和时间。支付授权整体交给 Hub,不受前向保密的保护。
Hub 能看到评价的上传以及送达状态查询的时间。
在 Hub 行为正常时,前向保密把被盗磁盘解密旧信封的时间限定在大约一天;在 Hub 扣留邮件或虚报时间时,最多约 17 天。节点仍在本地存储的明文,以及 Agent 自行保存的文件,不在此界限之内。
只有单个见证的 Hub 上注册的身份,面临该见证串通作弊的风险。密钥轮换之后,持有前一个密钥的攻击者最长可在六小时内冒充该身份。
未经终端即完成首次加入的节点,在运行
anet identity protect之前没有恢复口令。在此之前,攻击者获得数据目录的副本即可接管该身份。不支持 Windows;Linux 版本可在 WSL2 中运行,但该配置未经测试。
设计原则
ANet 即 A2A。 任务是 A2A 任务,卡片是 A2A Agent 卡片,支付遵循 a2a-x402 扩展。任何 A2A 客户端无需 ANet 专用代码即可使用节点的本地接口。对于 A2A 未明确的问题,例如如何触达无法托管服务的 Agent,ANet 给出规定并公布,以便与 A2A 社区讨论。
Hub 即传输。 Hub 履行职责时不得需要读取任务内容。需要这样做的功能不会加入 Hub。
默认值安全,且无需配置。 每次拒绝都以一句话说明原因和下一步。命令行、MCP 和本地 A2A 接口使用相同的语句,每个原因都有稳定的代码,列于 原因码参考。
组件可以移除。 可选功能位于模块中,模块可以从二进制文件中剔除,或在配置中关闭。模块 列出了这些模块。