选一个发行版
六档减法构建加一个正交开关,按你要做什么选
同一份代码可以编出多种 anet。区别不是配置,是二进制里有没有那段代码 ——
一个用 -tags no_x402 编出来的节点里没有付费模块的任何一行,go tool nm 数得出来。
判据与机制见 可插拔;这一页只回答一个问题:你该装哪一个。
先给答案
| 你要做什么 | 选哪档 |
|---|---|
| 只想让自己的 agent 接入网络、找人、把任务委派出去 | min |
| 把已有的 HTTP 服务挂上网络,免费给别人调用 | standard |
| 靠提供能力收 credit,要标价、报价、结算、对账 | paid |
| 让 Claude Code / Cursor 这类助手自己会找 agent、会委派 | agent |
| 同一内网的一组节点,委派载荷不想经过第三方服务器 | p2p |
| 开发、联调、演示;或确实要用共脑 / 组织凭证 / 内容寻址存储 / 设备能力 | full |
| 需要从网络另一端在这台机器上执行运营者批准的命令 | 上面任意一档 + shell |
拿不定主意就装默认版。一行安装脚本给的就是它,装错了重跑一次即可,身份和数据不受影响 (见本页最后一节)。
六档对照
体积与依赖数引自 发行版总览 的实测总表:2026-09-03 重测,
go 1.26.7,linux/amd64,CGO_ENABLED=0,-trimpath -ldflags "-s -w",依赖数含 main 包本身。
本页没有重测这张表,数字以那一页为准。
"公开监听口"指这个进程会不会接受来自本机回环之外的连接 —— 回环控制面每一档都有,
不算在内。
| 档 | 二进制里有的模块 | 体积 | 依赖包数 | 公开监听口 |
|---|---|---|---|---|
min | (无) | 12,100 K | 265 | 无 |
standard | service | 12,124 K | 266 | 无 |
paid | service x402 | 12,240 K | 267 | 配了 voucher_addr + voucher_url 才开 |
agent | service taskboard + mcp northbound | 14,048 K | 301 | 无(MCP 走 stdio) |
p2p | service p2p taskboard | 12,176 K | 268 | 由 anetpeer 进程开,不在 anet 里 |
full | 八个减法模块全在 + mcp northbound | 14,320 K | 308 | 同 paid + 同 p2p |
各档能做什么、不能做什么:
| 档 | 能做 | 不能做 |
|---|---|---|
min | 注册到 hub、find、delegate、收结果、验收据、评价;证据链完整。收得到别人委派的自由文本任务,可由内置自动回复作答 | 以能力 id 对外提供服务;收费或付费;点对点直连 |
standard | min 的全部,加上把本机 HTTP 服务注册成能力、签发收据、上证据链 | 收费。标价的能力在这个构建上答 UNAVAILABLE 并说明原因,不会免费替人干活 |
paid | standard 的全部,加上标价、报价、结算、开凭证、兑付、审计 hub 发放链、对账 | 点对点直连;MCP |
agent | standard 的全部,加上 anet mcp 提供的 9 个 MCP 工具,以及 taskboard(领 hub 共享任务板上的活) | 收费;点对点直连 |
p2p | standard 的全部,加上直连投递(连不上时自动回落到 hub 中继)与 taskboard | 收费;MCP;脱离 hub 做发现 |
full | 全部,在 agent + p2p 之上再加 blackboard(共脑)、org(组织成员凭证)、cas(内容寻址存储)、anetlink(设备能力) | —— |
p2p 档不能脱离 hub。发现与密钥历史仍然走 hub:节点用 anet p2p-advertise 把自己的
直连地址签名发布上去,对端查到之后才能直连。发布是自愿的,不发布就不在目录里,仍然经 hub 收活。
代价是 hub 因此持有一份地址表 —— 所以这份目录本身是公开的,付出这个代价的人看得见它装了什么。
载荷、证据、结果不经过 hub。
另外,对等进程 anetpeer 是单独一个二进制,一行安装脚本不带它,要自己
go build ./tools/anetpeer。它目前没有 NAT 穿透、没有中继,发现只有 rendezvous 一种。
六档的 tag 怎么拼
九个减法 tag 默认全在,规则是"要保留哪几个,就把剩下的写进 -tags":
五条减法串逐字取自 .github/workflows/ci.yml 的 pluggable 矩阵,每次提交都被编译并跑测试;
full 是不加任何 tag 的默认构建。前三条同时也是 scripts/onboard.sh 里 PROFILE 的定义。
agent 与 p2p 两条串里没有 no_taskboard,min / standard / paid 三条有 ——
所以这两档的二进制带着 hub 共享任务板的客户端,多约 24 K 和一个依赖,并且这两档的节点
可以领 hub 任务板上的活。这不是一句设计意图,是矩阵里六个串之间的实际差异:
ANet/docs/DISTRIBUTIONS-zh.md 给出的六档 tag 串一个 no_taskboard 都没有,
ci.yml 与 onboard.sh 只给前三档补上了。要不要统一,未决 ——
见 发行版总览 的"已知缺口"第 2 条。
+shell:一个正交的开关,不是第七档
shell 的 tag 方向与其余九个相反:默认不在,-tags shell 才编进去。
所以每一档都有一对孪生版 —— 同一档、同一 commit,一个能在宿主机上执行命令,
一个连这段代码都没有。
shell 是加在某一档的减法 tag 之上的,不是替代它们。只写 -tags shell 得到的是
full+shell,不是别的档:
方向为什么反过来,理由不是审美,是两种写错的代价不对称:减法 tag 漏了,后果是 某人想去掉的模块没去掉;加法 tag 漏了,后果是命令执行能力进了所有没要过它的构建。 需要靠"记得去掉"来保护的人,恰好是没听说过这个 tag 的人。
三个孪生版的实测代价:
| 构建 | 体积 | 依赖包数 |
|---|---|---|
standard+shell | 12,176 K | 267 |
agent+shell | 14,080 K | 302 |
full+shell | 14,356 K | 309 |
比对应的基础档多 32–56 K、多 1 个依赖。它值得单独一个 tag 的理由与体积无关,是它能做什么。
编进去不等于开着。 带 shell 的构建在没有 modules.shell 配置块时不注册任何能力;
配了但 allow / allow_file 名单为空时,拒绝所有远程调用 —— 空名单是拒绝所有,不是放行所有。
三道闸门分别由发布方、机器运营者、运营者的名单文件把守,契约见
shell 发行变体。
不装 shell 变体,不等于这台机器不会执行远程来的意图。
内核里的自动回复(anet autoreply set --backend exec --agent claude)会拉起一个本地编码助手
来作答,那个助手本身可以跑命令、读写文件。两者的区别在于谁决定跑什么:shell 模块跑的是
运营者在配置里逐条写死的命令,自动回复跑的是助手自己决定的动作。选发行版解决不了后一个问题,
要看你有没有开自动回复的 exec 后端。
按体积分档站不住
裁剪的直觉理由通常是"省体积"。实测数据不支持这个理由 —— 单独去掉每一个模块能省多少:
| tag | 省下 | 占可省总量 | 依赖减少 |
|---|---|---|---|
no_mcp | 1,896 K | 85% | 34 |
no_x402 | 116 K | 5% | 1 |
no_cas | 52 K | 2% | 1 |
no_blackboard | 36 K | 2% | 1 |
no_org | 28 K | 1% | 1 |
no_p2p | 28 K | 1% | 1 |
no_taskboard | 24 K | 1% | 1 |
no_anetlink | 12 K | 小于 1% | 2 |
no_service | 12 K | 小于 1% | 1 |
九个减法 tag 全用上,14,320 K 降到 12,100 K,省 15%。其中 85% 来自 no_mcp 一个
(MCP SDK 及其 jsonschema 依赖,依赖数 308 → 274)。剩下的十几兆是 Go 运行时、
net/http、加密库和纯 Go 的 SQLite 驱动(modernc.org/sqlite),与模块无关。
结论:除 MCP 外,没有一个模块对体积有实质影响。 min 到 paid 之间只差 140 K 和 2 个依赖。
真正值得分档的维度是另外三个:
- 攻击面 —— 这个构建会打开什么、接受什么
- 可被要求做什么 —— 一个没有
x402的节点不可能被诱导付款,这是一句关于文件的陈述 - 运维复杂度 —— 要配几个块、有几种失败模式
按攻击面看,九个减法 tag 管的东西里(八个模块加 MCP northbound)只有两个会让节点 接受外部连接:
| 模块 | 打开的入口 | 出站行为 |
|---|---|---|
x402 | 公开 HTTP 监听口(配了 voucher_addr + voucher_url 时) | 向 hub 发结算、拉发放链 |
p2p | 入站对等连接(在 anetpeer 进程里) | 主动连对等节点 |
mcp | stdio,由本机进程启动 | 无 |
service | 无 | 向本机 HTTP 服务发请求 |
anetlink | 无 | 连 ANetLink 的 unix socket |
taskboard | 无 | 向 hub 的任务板发签名请求 |
cas / blackboard / org | 无 | 无 |
shell | 无(请求经 hub 或 p2p 到达) | 在宿主机上执行命令 |
今天实际能下载到的是哪一档
要如实说明:一行安装脚本目前只提供两种二进制,不是六种。
deploy/release/build-release.sh 为四个平台(linux / darwin × amd64 / arm64)各编两个变体,
共八个产物:anet-<os>-<arch> 与 anet-shell-<os>-<arch>。两者都不带任何减法 tag ——
也就是说,你从 install.sh 装到的默认版是 full 档,--shell 装到的是 full+shell。
min / standard / paid / agent / p2p 五档目前是自建配方,不是发布产物:
它们在 CI 的 tag 矩阵里每次提交都编译并跑测试(所以不会悄悄编不过),
scripts/onboard.sh 还会实际构建 min / standard / paid 三档,并逐条核对
docs/DISTRIBUTIONS-zh.md 对这三档写下的行为承诺,但没有对应的下载。
要用这五档就照上面的 go build 自己编。发行版设计文档 docs/DISTRIBUTIONS-zh.md
自己也标着"设计稿,未发布"。
发布的二进制用 -ldflags "-w" 而不用 -s:保留符号表,是为了让下游能在自己手上的
文件上重新数一遍符号,而不是只能相信文件名。代价是比上表大约 1.4 MB
(full 14,320 K → 15,760 K)。仓库里 v0.1.7 的 dist/anet-linux-amd64.gz 实测
6,058 K,解开后 15,761 K —— 这是本地构建产物的大小,没有从站点重新下载核对。
怎么确认手里的二进制是哪一档
问它自己:
上面这份输出取自一个 go build 直接编出来的二进制,所以 commit / built 是 unknown。
deploy/release/build-release.sh 和 scripts/onboard.sh 都用 -ldflags -X 把这两个值打进去,
从 install.sh 装到的文件这里会是真实的 commit 和构建时间。
第二行读的是模块注册表,不是构建时打进去的字符串 —— 一个模块出现在列表里,
是因为它的 init() 跑了,而 init() 跑了是因为链接器留下了它。两个名字需要单独说明:
mcp不是module.Module,它是anet mcp这个 northbound,代码在internal/mcpserv,不进模块注册表 —— 但它仍然出现在这一行里:cmd/anet/module_mcp_declare.go带着同一个//go:build !no_mcp, 里面只有一句module.DeclareCompiled("mcp")。no_mcp的构建里这个名字消失, 而anet mcp这条命令仍然存在,回答"这个构建是用-tags no_mcp编的"。shell默认就不在。带-tags shell之后它会出现在同一行里。
不信任 anet version 的输出,就自己数符号 —— 发布的二进制保留了符号表,这条命令对下载件同样有效:
默认版必须答 0,--shell 变体必须大于 0。
默认版那个 0 要先排除一种情况。 如果这个文件被 strip 过(-ldflags "-s"),go tool nm 会在 stderr 上
报没有符号表,管道末端的 grep -c 照样打印 0 —— 看上去和通过一模一样。先确认
有输出,再看计数。build-release.sh 在发版时先做的就是这一步。同样的方法适用于任何一个
减法模块,把 module/shell 换成 module/x402 即可。
daemon 启动时也把同一份清单写进日志:
compiled in 与 started 是两个数:前者是二进制里有什么,后者是本机配置里启用了几个。
装错了怎么换
重跑一次安装脚本就行。安装是原子替换 $PREFIX/anet 这一个文件,身份、密钥历史、
证据链、配置都在 ~/.anet(可用 ANET_DATA_DIR / ANET_HOME 改),不受影响。
换完之后 AID 不变,hub 上的注册不变,已经收到的收据仍然验得过。
有一个例外要先处理:配置里写了、新构建里没有的模块会让 daemon 直接起不来, 而不是被静默忽略。
这是有意的 —— 读到 "p2p": {...} 之后默默跳过,会留下一个操作者对着"为什么没有在对等"发呆。
换到更窄的一档之前,把 ~/.anet/config.json 里 modules 下对应的块删掉 ——
这台机器上跑了几个身份的话,每一个都要改:命名身份的配置在
~/.anet/ids/<名字>/config.json。
反过来,如果你配了 modules.shell 而装的是默认版,错误信息会告诉你它需要 -tags shell
而默认构建不用这个 tag,不会让你去找一个从来不存在的 no_shell。
逐档说明
min
只是接入。不提供服务、不收钱、不监听任何公开端口。
standard
接入 + 把本机 HTTP 服务挂成能力。标价的活会明确拒绝而不是白干。
paid
接入 + 服务 + 收费。第一个需要认真读文档的档:公开端口、余额托管、跨 hub 结算。
agent
给 Claude Code / Cursor 这类助手用。多 9 个 MCP 工具,也是唯一一处体积理由成立的裁剪。
p2p
委派载荷直连投递。发现与密钥历史仍走 hub,另需 anetpeer 进程。
full
全部模块。一行安装脚本的默认版就是这一档。
+shell
正交开关。任意一档的孪生版,能执行运营者逐条写死的命令。
怎么核对
在你自己手上的文件上,把这一页的每一条说法数一遍。