设计初衷:为什么这么设计
🤖 本页要点已收录进 llms.txt——AI 代理可直接读取。
这个仓不是「先设计 API 再找场景」的产物,而是从一个真实宿主产品里拆出来的: 多智能体编排里那些与领域无关、又必须跨宿主一致的判定语义,被一层层沉淀成机制。 下面每一条设计决定,背后都有具体的失败形态。
编排是代码,LLM 只做单环节
左:流程交给概率模型,三个问题每次答案都不同;右:流程是代码,LLM 只在环节内发挥。
所以本仓的立场是:
- 编排是确定性代码——环节状态怎么流转、工具怎么被判定、产出怎么被结构化, 全部是可测试、可门禁、可重演的 Go 代码;
- LLM 只做单环节——在环节内部发挥,出了环节由契约接管;
- 「编排是代码」的必然推论是编排过程可被重演——既然可重演,恢复方式就该是 可机械判定的纯函数,而不是宿主在崩溃那一刻的临场决定(临场决定必然选最坏的那个: 要么盲目全量重跑、要么盲目跳过)。
内核不该知道自己在给谁干活
拆分做完后最现实的风险不是拆不动,而是业务代码一年年渗回内核, 等发现时 harness 已经退化成「换了个名字的 monolith」。
判定口诀一张图就够:
一句口诀当判据:要改的代码属于宿主,不需要改的才有资格进内核。
落到三条可执行约定:
- 判定语义归内核,判定依据归宿主。 例:「这是引导式直答还是诊断报告」是机制(内核), 「哪条算引导」是命名(宿主)——所以内核给结构化字段 + 注册表,不硬编码名字。
- 展示文案归宿主。 标题、兜底、品牌词一律走
RenderOptions注入,内核只留中性默认值。 - 测试夹具用合成数据。 夹具是契约示例,示例带领域味等于把契约钉死在某个领域上。
而这条边界不写在散文里——写成正则规则表 + go/ast 结构判定(清单见门禁体系,机器生成), 挂在 make check 上。散文不是门禁:真有人往门面包里塞一份实现,散文不响, 结果是与上游并存的第二份实现。
判定语义必须跨宿主一致
失败分类、隔离档位、提交闸的判定若各宿主各写一套,必然漂移到没人发现为止。 「什么算可重试」「隔离的哪一档算够」「这次提交算不算终态」——这些是语义, 不是实现细节:各判一套的那天起,同一个错误在两个宿主里就有了两种处置。
因此:
- 组合逻辑归内核,判定归各自机制包;
- 门禁执行体是可导入包(
archcheck/):宿主复用同一份判据,不必各写一遍—— 各写一遍的结局就是各判一套。
内部一致优于外部通用
同一件事的多个维度分列而非合并,因为合并会丢信息:
toolfail:重发安全与重试价值是两个正交维度——超时值得重试, 但服务端可能已执行,原样重发就是重复施加副作用;budget:毛移除量(扣摘要之前的量)与净移除量(扣掉摘要回填后的量)分开;guardset:多条拒绝合成一条时,可重试取「全部可重试才算」,不是「任一」—— 取保守侧。
失败形态必须是变红,不是变绿
这是本仓工程文化的核心。规则的失败形态若是变绿,规则就等于不存在:
上:每条规则都配的反向验证;下:只测好实现的假绿形态。
- 改任何判定逻辑,必须同时给「坏实现会红」的用例——只测「好实现能过」的用例, 一个把数字比较写成字符串比较的错实现照样全过;
- 「从没见过它触发的规则」等于没有规则——每条规则都做过反向验证(注入违规 → 门禁报错 + 退出码 1);
- 门禁自己也要能被检查:测试文件被整体跳过、import 规则漏形态、例外到期不失效…… 这些「静默失效」都实测发生过,修法都配了反向用例;
- 结构性的判定走
go/ast,不走逐行正则——import 声明有六种以上书写形态, 逐行正则必然漏,且漏得毫无声响。
fail-closed 是默认姿势
toolfail:不可归类一律不可重试;sandbox:兑不住声明档位的后端建不出即拒绝执行,登记簿里不会被选中;protocol:超限输入判非报告而不是截断后继续解析(截断曾让 3.4 MB 输入 以confidence=high解析成功——上限等于没有);netguard:放行面具名且零值即严——不配置 = 全拒绝。
派生状态只能有一个真相
派生状态只留一个真相;要全局视图就用投影,绝不开第二个计数器。
**手抄一遍就等于多一份会静默失真的真相**,所以本站数字全部生成(见 [包清单与机器事实](../reference/packages.md))。每个机制都有事故出处
这个仓的文档风格是「纪律 + 事故来源」——不是仪式感,是因为只有记住形态, 才认得出下一次。举三个代表:
| 机制 | 它防的事故 |
|---|---|
commitgate 放闸凭令牌 | 靠 (状态,分支,序号) 内容比对认人:同名分支的输家能删掉赢家的闸,ABA 场景迟到的释放会放掉新持有者——实测 8 路同名并发出现 4 个赢家 |
protocol 证据编号唯一 | 自动编号与模型自报编号撞号时「歧义静默」——同号引用查不出错,比缺失更难查 |
netguard 代次单一真相 | 两个独立计数器记录同一代次,非原子读改写下 64 次并发交换只推进 54 代——「换过没有」给不出答案 |
想看完整的形态库,见仓内 AGENTS.md 与 docs/USAGE.md 的坑速查表。