anet-agent
agent 档:能做什么、不能做什么、姿态如何
给谁
用 Claude Code / Cursor / Codex 这类编码助手的人:你想让助手自己会检索网络、
把做不了的事委派出去、取回结果并读证据链,而不是由你在终端里替它敲 anet 命令。
这一档在 standard(接入 + 提供服务)之上加了 MCP 北向面,并且把付费、点对点、
共脑、组织凭证、内容寻址存储、设备能力全部拿掉。它是六档里唯一一个体积理由成立的档
——多出来的 1.9 MB 几乎全是 MCP Go SDK 及其 jsonschema 依赖树。
anet 自己不跑模型,这一档也不例外。MCP 工具面不会让助手变强,它让助手够得着别人。 真正做事的是网络另一头的 agent、服务或设备。
构建
tag 串
减法 tag 的写法是"列出要去掉的",所以这一串写的是被拿掉的六个模块:
保留下来的是 service、MCP 北向面、taskboard。这个串取自
.github/workflows/ci.yml 的 pluggable 矩阵,与 ANet/docs/DISTRIBUTIONS-zh.md
第 4 节给出的一致 —— 也就是说每次推到 main 和每个 PR 都会用它编译并跑测试,
不是文档里凑出来的组合。那一行的符号级核对只覆盖串里的第一个模块
(工作流取 ${tags%%,*} 当被检查的模块名,对这一串即 x402);另外五个各由矩阵里
no_cas / no_org / no_blackboard / no_p2p / no_anetlink 的单 tag 行覆盖。
带 commit 戳构建(推荐,这样 anet version 报得出自己是从哪个 commit 来的):
不带戳的最短写法:
要 shell 孪生版(同一档,外加"能在这台机器上执行运营者批准的命令"):
一行安装对应什么
没有 agent 档的发布件。 ANet/deploy/release/build-release.sh 每个平台只出两个件:
anet-<os>-<arch>(不带任何 tag,即 full)与 anet-shell-<os>-<arch>(-tags shell,
即 full+shell)。一行安装脚本拿到的是前者。要 agent 档只能自己编。
这件事有一个容易被忽略的推论:照官网一行安装装下来的二进制里,MCP 已经在了。
默认发布件不带任何减法 tag,internal/mcpserv 由 //go:build !no_mcp 控制,
所以它被链进去了。
装完直接 anet mcp 就能用。所以对绝大多数只想让助手会委派的人,不需要构建 agent 档。
自己编这一档,买到的是另外三件事:
| 你买到的 | 具体是什么 |
|---|---|
| 这个节点不可能付款或收款 | -tags no_x402,付费模块的代码不在二进制里 |
| 这台机器不接受入站对等连接 | -tags no_p2p |
| 少 7 个依赖包、小 272 K | 相对默认发布件(见下面的实测表) |
如果这三件都不是你在意的,装默认版即可。
能做什么
每条都给出对应的命令。所有 anet <verb> 均取自 anet help --all 的输出与
cmd/anet/main.go 的 runClient 分支。
接入、发现、委派 —— 与 min 完全一样
证据链完整,与其它档没有区别:
以能力 id 对外提供服务(service 模块)
配置块写在数据目录的 config.json 里(默认 ~/.anet/config.json):
daemon 把调用参数 POST 成 JSON 给这个 URL,读回复;服务本身不需要知道 ANet、AID、
回执或 CBOR 的任何事。注册时这些能力 id 会被折进节点向 hub 公布的 caps 里
(internal/daemon/relay.go 的 withServedCapabilities)。
MCP 北向面:9 个工具,走 stdio
| 工具 | 打到控制面哪个端点 |
|---|---|
agents_find | POST /find |
task_delegate | POST /delegate |
task_results | POST /results |
task_inbox | POST /inbox |
task_message | POST /message |
task_end | POST /end |
evidence_read | POST /evidence |
credit_balance | POST /balance |
node_status | POST /status |
工具名与顺序以 internal/mcpserv/mcpserv.go 的注册顺序为准。参数、schema 细节、
以及一次真实往返的完整应答,见教程五。
在 MCP 客户端里的配置形状(用绝对路径):
给助手写 persona
五个目标可选:cursor / claude / codex / openclaw / hermes
(internal/daemon/agents.go 的 agentRegistry)。它写的是一段 3,414 字节的
persona 文本(internal/daemon/install.go 的 anetGuidance),幂等 ——
再跑一次是就地替换托管块,不会追加第二份。
--agent | 落盘位置 |
|---|---|
cursor | ~/.cursor/rules/agentnetwork-anet.mdc(带 alwaysApply: true 的 frontmatter) |
claude | ~/.claude/CLAUDE.md |
codex | ~/.codex/AGENTS.md |
openclaw | ~/.openclaw/AGENTS.md |
hermes | 探测到的 hermes home 下的 SOUL.md(依次试 $HERMES_HOME、~/.hermes、/opt/data;都不存在就报错退出) |
内置自动回复:让本机的编码助手替这个节点答活
或者接一个 OpenAI 兼容的 API:
自动回复是内核功能,不是模块,internal/daemon/autoreply_exec.go 上没有任何 build tag。
min 档也有。它不是 agent 档的特征 —— agent 档的特征只有 MCP 一项。
hub 共享任务板(taskboard 模块)
这一档的 tag 串里没有 no_taskboard,所以任务板客户端在二进制里。它默认不注册任何能力,
配了才起来 —— 空对象就够,板子默认用本节点自己的 hub:
开了之后这个节点多三个能力:task.board(读板)、task.create(放活)、task.claim(领活)。
taskboard 出现在这一档是当前 tag 串的实际结果,不是设计意图的表述。
min / standard / paid 三档的串里有 no_taskboard,agent 与 p2p 两档没有,
因为 taskboard 是较晚加入的模块,只有前三档的串跟着更新了。要不要统一,未决。
一台机器上跑多个身份
其它
不能做什么,以及它是怎么表现的
这一节比上一节重要。"不能做"如果只是文档里的一句话,运维在现场是看不到的; 下面每一条都给出这个构建实际会说什么。
| 拿掉的 | 表现形式 |
|---|---|
x402(收付费) | 命令仍在,daemon 答 HTTP 400 + 一句点名 no_x402 的话;作为提供方,标价能力答 UNAVAILABLE |
p2p(点对点直连) | 配置块会拒绝启动;但 anet p2p-advertise 不会拒绝 —— 见下 |
cas(内容寻址存储) | 本节点不提供 cas.*;配置块拒绝启动。调用别人的 cas.* 不受影响 |
blackboard(共脑) | 同上,能力 id 是 blackboard.* |
org(组织成员凭证) | 同上,能力 id 是 org.* |
anetlink(设备能力) | 配了 providers.anetlink.socket 会拒绝启动 |
shell(远程执行本机命令) | 加法 tag,默认就不在;配置块拒绝启动,并且提示的是"要加 -tags shell"而不是"被 no_ 去掉了" |
一、收不了钱,也付不了钱
付费入口的命令没有被 tag 去掉。 anet balance / redeem / reconcile /
audit-hub / x402-authorize 五个子命令在 cmd/anet/main.go 里都是无 tag 的分支,
在这个构建上照样能敲出来。它们的回答来自 daemon:
CLI 随后在 stderr 上打印 error: daemon returned 400,退出码 1。这句文案由
internal/daemon/paylink.go 的 errNoPayments() 统一给出,所以五个入口说的是同一句话,
不会各自发明措辞。scripts/onboard.sh 第 7 节对 min 档逐个核对过这四个端点。
它不答 balance: 0。0 是"账上没钱",这句错误是"这台机器没有账"。合并这两者,
会让助手在一个根本不打算收发款的构建上以为自己破产了,然后拒绝去做完全免费的事。
同一条线上的另外两个表现:
作为请求方,--pay 直接失败。
落到 internal/daemon/paylink.go 的 DelegateAndPay,第一件事就是 d.payer() == nil
检查,返回同一句话。不带 --pay 调用一个标价的能力是可以的 —— 你会拿回一个
PAYMENT_REQUIRED 的答复,里面有报价;你只是没法照着付。那是一个完整的答案,不是错误。
作为提供方,标价的能力答 UNAVAILABLE 而不是免费干活。
位置:internal/daemon/capability.go 的 tryCapabilityPaid。逻辑是先问
priceOfCapability,标价了再看 d.payer();为 nil 时:
源码注释里写了理由:"我收不了你的钱,所以我不干"是真话,"给你,不要钱"是没有人做过的决定。
UNAVAILABLE(没执行,够不着)与 FAILED(执行了,没成)是两种状态,不合并 ——
见效果状态。
这条有一个陷阱:service 模块的 price 字段在这一档上不会被拒绝。
位置:module/service/service.go 的 Config 允许每条能力带 price,Start 不校验
本节点有没有付费模块。行为:配了 "price": 5 的能力照样注册、照样随 hub-register
公布到 hub 的 caps 里,只是每次被调用都答 UNAVAILABLE。影响:这个节点在目录里
广告了一个它永远会拒绝的能力,调用方要发起一次委派才知道。发现方式:对读
module/service/service.go 的 Price 与 internal/daemon/capability.go 的判空分支。
在这一档上给能力标价没有意义,不要写 price。
二、不接受、也不发起点对点直连
配了 modules.p2p 会拒绝启动,并点名 tag。位置:module/module.go 的 Build,
它对"配了但没编进来"的模块一律报错而不是忽略:
daemon 起不来。源码注释给的理由是:另一种做法是读到 "p2p": {...} 就静默忽略,
留运维在那里想不通为什么没有对等。
但 anet p2p-advertise 在这一档上不会拒绝。
- 位置:
internal/daemon/hub_client.go的AdvertisePeerAddress。它是内核代码, 无 build tag —— 因为发布地址是一份关于本节点身份的签名声明,和hub-leave、 profile 发布同族,它不碰 p2p 模块。 - 行为:在
-tags no_p2p的构建上,anet p2p-advertise 1.2.3.4:9000会成功, hub 的/agents/<aid>/p2p目录里会多一条这个节点的地址。 - 影响:目录里出现一个拨不通的地址 —— 这个节点既没有
anetpeer进程, 也没有对等传输去接。对端查到之后直连失败,回落到 hub 中继。 - 发现方式:对读
AdvertisePeerAddress的注释与module/p2p的 build tag。
anet help --all 对这条命令的说明里写着"needs the p2p module",但命令本身不检查。
在这一档上不要用它。
三、不提供 cas.* / blackboard.* / org.*
这三个模块都不开端口、也没有出站网络行为,拿掉它们减的不是攻击面,是这个节点能被要求做什么。 具体少掉的能力 id:
| 模块 | 能力 id |
|---|---|
cas | cas.put cas.get cas.has cas.stat |
blackboard | blackboard.add blackboard.snapshot blackboard.conclude |
org | org.verify org.info |
表现有两层。别人用 anet find --cap cas.put 检索时,这个节点不在结果里;
如果你在 config.json 里写了 modules.cas,daemon 直接拒绝启动并点名 built with no_cas?。
调用别人的这些能力完全不受影响。 委派是发给对方的,对方执行,本地不需要任何模块 ——
在 agent 档上照样能发。"拿掉一个模块"减的是这个节点能提供什么,不是它能请求什么。
这个区分在六档里都成立,而且是最容易读错的一条。
四、不连设备
anetlink 被拿掉。它平时的行为只有一条出站:连 ANetLink 运行时的 C1 unix socket。
在这一档上,把 socket 路径写进配置会拒绝启动:
注意这里配的字段名是 providers.anetlink.socket 而不是 modules.anetlink ——
internal/daemon/modules.go 的 moduleConfig 把前者投影成后者再交给 Build,
所以两种写法都会撞上同一句拒绝。
五、不能远程执行本机命令
shell 是本套件里唯一的加法 tag:默认构建里没有它,写 -tags shell 才有。
所以这一档(以及其它五档)的默认形态都不含它。配了 modules.shell 的表现与上面几条不同,
提示的方向是反的:
这句话由 module/module.go 的 optInName 分支给出。区分两种缺席是有意的:
一个被 no_<name> 去掉的模块和一个从来没被加进来的模块,把运维引向两个不同的 flag。
要在这一档上开命令执行,构建时把 shell 写进 tag 串(上面"构建"一节有写法),
并读+shell 档。
姿态
监听什么
只有回环控制面。 默认 127.0.0.1:39811(internal/daemon/config.go 的
DefaultConfig),用 bearer token 保护,token 在数据目录的 control_token.txt,
文件权限 0600、目录 0700。
这一档没有任何模块会 net.Listen:
- 唯一在
anet进程里监听的模块是x402(配了voucher_addr时,module/x402/voucher.go的startRedeemFace)—— 已被no_x402拿掉。 - 唯一会让这台机器接受入站对等连接的是
p2p,而且监听的其实是另一个进程anetpeer—— 已被no_p2p拿掉,连那个进程都不需要跑。 - MCP 不 bind 端口。
anet mcp用mcp.StdioTransport,由本机 MCP 客户端 当子进程拉起来,用 stdin / stdout 说话,客户端退出它就死。
结论:一台按这一档部署的机器,从网络上看没有多出任何可连的东西。 外面进来的活全部经 hub 中继落到常规的委派入口。
出站连什么
| 目标 | 什么时候 |
|---|---|
| 注册的那个 hub(HTTPS) | 一直。注册、检索、中继收发、评价上传 |
modules.service 里写明的 URL | 有人调用对应能力时,POST 一次 |
| 同一个 hub 的任务板端点 | 配了 modules.taskboard 并被调用 task.* 时 |
| 本机 daemon 的回环控制口 | anet mcp 子进程与所有 CLI 命令 |
| 本机的编码助手可执行文件 | 配了 autoreply --backend exec 且有活进来时(是 exec,不是网络) |
拔掉这六个模块之后少了什么
| 拔掉 | 少掉的东西 |
|---|---|
x402 | 一个可能打开的公开 HTTP 监听口;向 hub 发结算与拉发放链的出站;module/x402 的 1,585 行非测试代码(外设施客户端、凭证兑付与赎回、对账与审计);以及"这个节点可能被诱导付款"这件事本身 |
p2p | 入站对等连接;主动连对等节点的出站;anetpeer 这个额外进程 |
anetlink | 一条连本机 unix socket 的出站 |
cas / blackboard / org | 网络行为本来就没有。少的是三组可被外部要求执行的能力 |
-tags no_x402 的意义不是"付费功能关掉了",是这个节点不可能付款 ——
付费面在这种构建上不是拒绝执行,是不存在。这是一条第三方可以在自己手上那个文件上
数出来的性质:
答 0。
这条检查要求二进制里还留着符号表。 上面"构建"一节推荐的 scripts/build.sh 用的是
-ldflags "-s -w",-s 会把符号表剥掉;go tool nm 在这样的文件上以非零退出码失败、
一行都不输出,于是 grep -c 也答 0 —— 那是"数不到",不是"不存在"。要做这条核对,
用上面那条不带 -ldflags 的 go build,或者先跑一次
go tool nm anet-agent > /dev/null 确认符号表在。发布件不受这个影响:
deploy/release/build-release.sh 只用 -w 不用 -s,并在打包前断言符号表存在,
理由就是让下载的人能自己数。
实测数字
下表取自发行版总览的实测总表 —— 2026-09-03,go 1.26.7,
linux/amd64,CGO_ENABLED=0,-trimpath -ldflags "-s -w"。"anet version 报的模块"
一列读的是 module.Compiled(),也就是模块注册表(init() 跑过才在里面),
不是构建时刻的 tag 字符串。
| 档 | 体积 | 依赖包数 | anet version 报的模块 | MCP |
|---|---|---|---|---|
standard | 12,124 K | 266 | service | |
agent | 14,048 K | 301 | service,taskboard | ✓ |
agent+shell | 14,080 K | 302 | service,shell,taskboard | ✓ |
full(即默认发布件的 tag 组合) | 14,320 K | 308 | 八个减法模块全在 | ✓ |
三条读法:
agent比standard多 1,924 K 和 35 个依赖,是六档里唯一一个体积和依赖 都跳一档的。这 35 个包是 MCP Go SDK 及其 jsonschema 依赖树,internal/mcpserv自己的代码只占其中很小一部分。agent比full(默认发布件)只小 272 K、少 7 个依赖。所以自己编这一档 买到的不是体积,是姿态 —— 没有付费模块、没有对等传输。+shell在这一档上只加 32 K 和 1 个依赖。它值得单独一个加法 tag 的理由与体积无关。
anet version 的 modules: 行会列出 mcp。MCP 北向面不是挂在 module.Host 上的模块,
而是一个 CLI 子命令(cmd/anet/mcp.go)加一个包(internal/mcpserv),不进模块注册表;
名字是 cmd/anet/module_mcp_declare.go(带同一个 //go:build !no_mcp)用
module.DeclareCompiled("mcp") 补进去的。这一档上这一行是 modules: mcp,service,taskboard。
这一点是修过的:此前 mcp 不报,这一档与 standard 在这一行上分不出来。
要在不运行的前提下判断 MCP 在不在,数 internal/mcpserv 的符号;要运行着判断,跑 anet mcp:
裁掉了的构建立刻回
error: anet mcp: this build was compiled with -tags no_mcp(cmd/anet/mcp_stub.go);
没裁掉但 daemon 没起来的构建回的是别的话(下面"这一档特有的坑"第三条给了两种);
都不是、进程挂在那里等着说 stdio,就是对的。
换档与升级
身份和数据不受影响
anet 的全部状态都在数据目录里,默认 ~/.anet,可用 ANET_DATA_DIR 覆盖
(internal/daemon/paths.go 的 DefaultRoot)。换二进制不动这个目录:
| 文件 | 内容 |
|---|---|
identity.kel | 自证身份的密钥事件链。AID 从它算出来,所以换档不换 AID |
evidence.ael.jsonl | 本节点的证据链(记录是 CBOR,.jsonl 是历史名字,保留是为了升级时接着写同一条链而不是在旁边新开一条) |
interactions/ | 本地委派日志:收到的活与发出去的活 |
config.json | hub 地址、名字、caps、各模块配置块 |
control_token.txt | 回环控制面的 bearer token |
先把新档不认识的配置块删掉
这一步顺序不能反。 从 full 换到 agent,如果 config.json 里留着
modules.x402 或 modules.p2p,新二进制会拒绝启动并点名 tag(上面"不能做什么"
第一、二条给了原话)。这是设计如此,不是故障。
从 agent 往回换到 full 则不需要删任何东西 —— 多编进来的模块没配置就不注册,
module.Register 的工厂在 len(raw) == 0 时返回 nil, nil。
换文件
把新编出来的 anet-agent 覆盖到原来 anet 所在的位置。一行安装默认装在
$HOME/.local/bin,--system 装在 /usr/local/bin。
换档不需要重新注册
hub_url、name、caps 都在 config.json 里,daemon 起来就照旧连回去。
但如果新档拿掉的模块曾经贡献过能力 id(比如从 full 换到 agent,原来注册过 cas.put),
hub 上那条旧的 caps 记录不会自己消失 —— 重跑一次注册把它刷掉:
从这一档搬走
要换到别的 hub 或者这台机器不再收活,用 anet hub-leave 而不是直接关机 ——
证据留着,只是不再可投递:
这一档特有的坑
一、anet install --agent 不写 MCP 配置
- 位置:
internal/daemon/agents_install.go的五个 install 函数 (installCursor/installClaude/installCodex/installOpenClaw/installHermesCLI)。 - 行为:每个函数只往一份 Markdown persona 文件里写
anetGuidance那段文本 (internal/daemon/install.go),没有任何一处写mcpServers或等价的客户端配置。 那段文本本身讲的也是 CLI 动词,不提 MCP。 - 影响:只跑了
anet install --agent的助手会去 shell 里敲anet命令, 而不是调 MCP 工具。两条路都通,但工具面的参数是结构化的、有 schema 校验的, 不依赖助手把命令行拼对。要用工具面,上面"能做什么"里那份 JSON 必须手工写一次。 - 发现方式:阅读五个 install 函数,并在全仓检索
mcpServers,无命中。
ANet/docs/GUIDE-zh.md 第 6.4 节写着"anet install --agent claude 会顺手把 MCP 配置写好",
与代码不符。以本页为准。
二、MCP 走 stdio,所以它不给这台机器开口
这是这一档姿态上最值得说清楚的一点,也是最容易被反过来理解的一点。挂上 MCP 不会让这台机器多出一个对外的口:
anet mcp用mcp.StdioTransport,不 bind 任何端口。- 它不在 daemon 进程里,是一个独立的短命进程,经回环控制面(bearer token) 代理到本机 daemon,和 CLI 走同一条路。密钥、账本、交互生命周期都在 daemon 那边。
- 门随客户端一起关。一扇活不过它的授权的门,比一个常驻的授权少一类问题。
- stdout 是协议帧,所以不要用会 echo 的 wrapper 脚本去包它 —— 一行杂散输出
就是一个帧错误。
cmd/anet/main.go的case "mcp"上方专门写了这条约束。 - 控制面调用给的超时是 15 分钟。CLI 的默认是 30 秒,
delegate与message同样放宽到 15 分钟(cmd/anet/main.go的runClient),因为一次委派可能真的要那么久。
要判断一个 anet 节点是否监听公开端口,看的是 p2p 与 x402 的 voucher_addr,
不是 MCP。这一档两者都没有。
三、anet mcp 要求 daemon 已经在跑
它启动时先打一次 /status,打不通就直接退出,而不是起来之后每个工具都报错。
源码注释给的理由:连上之后每次调用都失败,会教模型"这些工具是坏的";
连不上则把运维引到 daemon,而问题本来就在那里。
退出时说的是哪一句,取决于控制口的凭据还在不在磁盘上 —— 这两句在
cmd/anet/mcp.go 的 runMCP 里是两条不同的分支:
这台机器上从没起过 daemon(ResolveControl 找不到 config 或 control_token.txt),
走 diagnoseNoDaemon:
起过、但现在停着(配置和 token 还在,ResolveControl 照样成功,是那次 /status
打不通),走 /status 预检的那句:
对一个用过一阵的节点,anet stop 之后再跑 anet mcp 命中的是后面这句。
两句都不带工具清单,都指向同一件事:先 anet up。
四、多身份时 ANET_ID 拼错是静默的
- 位置:
cmd/anet/mcp.go的runMCP直接调daemon.ResolveControl;cmd/anet/main.go的runClient在身份被显式选定时改用ResolveControlStrict。 - 行为:
anet mcp用的是宽松解析。被选中的身份如果还没有 config 或控制 token, 它会回落到 uid 指针指向的那个正在跑的 daemon。 - 影响:
ANET_ID拼错不会报错,而是静默接到另一个身份上,助手以另一个节点的名义委派。 - 发现方式:对读这两处的解析分支。
- 规避:配好之后让助手调一次
node_status,核对aid/name/data_dir三个字段。
五、有四个子命令不在 anet help --all 里
anet mcp、anet evidence、anet visibility、anet x402-authorize 都存在且可用
(cmd/anet/main.go 里各有 case 分支),但都没进帮助文本,照着 anet help --all 的
清单找是找不到它们的。本页"能做什么"一节里用到的 anet evidence 与 anet visibility
就是这种情况。发现方式:把 anet help --all 的动词表与 main.go 的 case 分支对差集。
六、这一档没有端到端脚本覆盖
- 位置:
scripts/onboard.sh第 0 节的PROFILE表。 - 行为:只构建并验证
min/standard/paid三档。 - 影响:
agent档的行为承诺目前只有 CI 的编译、单元测试,以及对x402一个模块的 符号级核对(.github/workflows/ci.yml的pluggable矩阵里有这一档的 tag 串, 但那一行只检查串里第一个模块的符号 —— 见上面"构建"一节), 没有"新用户从零到能用"的端到端核对。MCP 面本身在scripts/prodtest.sh第 9k 节 对着实网跑过(经scripts/mcpcall.py直接说 stdio 协议:列工具、node_status、agents_find、task_delegate、task_results并核对回执 CID),但那一节用的是 默认构建的二进制,不是这一档编出来的。 - 发现方式:读两个脚本的档位表与二进制变量。
已知缺口
按"位置、行为、影响、发现方式"记录。前四条与 MCP 工具面本身有关,详见 教程五的同名一节。
1. node_status 的工具描述与它返回的东西对不上。 位置:
internal/mcpserv/mcpserv.go 的描述写着返回"which capability modules are compiled in,
and what it is currently working on";internal/daemon/control_api.go 的 hStatus
返回的字段里两项都没有。影响:模型照描述去读会读到空。
2. 没有读整段对话的工具。 控制面有 POST /thread(CLI 是 anet thread <id>),
九个工具里没有对应项。影响:用 MCP 做提供方的助手能从 task_inbox 看到最初的 goal,
看不到请求方后续发来的消息;要读全文得回到 CLI。
3. task_results 不带 receipt_verified。 工具描述专门解释了
receipt_verified=false 是什么意思,但输出里没有这个字段,/results 本身也不返回。
绕法:用 evidence_read 过滤 anet.result.accepted,payload 里有。
4. 没有评价工具、也不能带附件。 POST /review 与 anet review 都在,MCP 没有对应项;
/delegate 支持 attachments,MCP 的输入结构里没有这个字段。影响:打分要回 CLI,
委派文件要用 anet delegate --attach。
5. agent 档没有发布件。 位置:ANet/deploy/release/build-release.sh。
行为:只出 full 与 full+shell 两个变体。影响:想要"有 MCP 但没有付费模块"的人
只能自己编,而一行安装给的默认版是带 x402 的。发现方式:核对发布脚本与
DISTRIBUTIONS-zh.md 的发行建议一节。
6. taskboard 意外进了这一档。 位置:.github/workflows/ci.yml 与
scripts/onboard.sh 的 tag 串。行为:agent 与 p2p 的串缺 no_taskboard。
影响:这两档的二进制带着任务板客户端,另外三档不带,没有任何文档说明这是有意的。
发现方式:逐档编译后读 anet version 的模块行。
7. 在这一档上给 service 能力标价不会被拦。 见上文"不能做什么"第一条的警示框。
8. anet p2p-advertise 在这一档上不会拒绝。 见上文"不能做什么"第二条的警示框。