哪些内容可以信任
手册中哪些部分是解析得到的事实,哪些是模型输出,哪些数据会离开你的机器,以及这个工具拒绝做哪些事。
简短版本
| 断言 | 来源 | 会出错吗? |
|---|---|---|
| 这个文件存在于这个路径 | 解析器 | 不会 |
| 这个函数位于第 88–104 行 | 解析器 | 不会 |
这个签名是 send(self, url, data) | 解析器 | 不会 |
| 这个函数调用了那个函数 | 解析器 | 完整层级不会;通用层级为尽力而为 |
| 这些调用无法被解析 | 解析器 | 不会 —— 它们被如实列出,而非猜测 |
| 这些文件无法被读取或解析 | 解析器 | 不会 —— 它们被如实列出,而非算作已覆盖 |
| 这个文件属于这个阶段 | LLM,经机械化校验 | 判断上可能出错;结构上不会 |
| 这个文件的用途是“…” | LLM | 会 —— 这是描述性文字 |
| 这个子系统的工作方式是“…” | LLM | 会 —— 这是描述性文字 |
| 这份状态流经这几个阶段 | LLM,基于真实阶段 id | 会,不过阶段 id 是真实的 |
**整个设计遵循的规则是:**智能体依据表格的上半部分进行路由,并在行动之前阅读真实源码。SKILL 包在第一行就写明了这一点,其路由协议以这样一句话收尾:“在提出或做出任何修改之前,对每个被引用的路径执行 read_file,阅读实际源码。”
哪些数据会离开你的机器
**Phase 1 —— 什么都不会。**静态分析完全在本地进行,不发起任何网络调用。
Phase 2 和 Phase 3 会把源文件内容发送到你配置的端点。它可以是运行在你自己机器上的模型(vLLM、Ollama、LiteLLM)。Handbooks 没有遥测、没有统计分析,除 OpenAI 之外也没有其他默认端点——而 OpenAI 的密钥必须由你自己提供。
--max-chars-per-file <n> 限定任何单个文件最多会被发送多少内容。
渲染、打包和校验从不接触网络,apply 和 rollback 也一样。
规划器在本地读取你的源码,并把读到内容的节选发送到端点,与生成阶段相同。
哪些事被刻意拒绝
拒绝正是这个工具的承重结构。按优先级排列:
补丁器(patcher)
- 锚点匹配到零次 → 拒绝。代码已经变了。
- 锚点匹配到两次或以上 → 拒绝。它有歧义。
- 绝不“取第一个匹配”。补丁就是这样落进错误函数的。
- 只要有一处失败,就在写入任何一个字节之前中止整个补丁应用。
- 逃出源码根目录的路径会被拒绝——包括当文件尚不存在时、经由符号链接的父目录逃逸的情况。
- 回滚会拒绝处理任何在打补丁之后又被改动过的文件,除非你传入
--force。
规划器(planner)
- 不存在写入工具。不是被禁用了——是根本没有实现。
- 凭空捏造
## Tool result小节的回复会被直接整体拒绝,连同其末尾附带的任何计划——因为那个计划是从虚构中推导出来的。 - 已经放弃的运行会以非零码退出,而不是把一段道歉写进
plan.md。 - 灾难性正则(
(a+)+、(.*)*)会在拖垮运行之前就被拒绝。
流水线
- 分析器无法解析的调用会进入
dropped-calls.json,绝不靠猜。 - 分析器读不了或解析不了的文件会带着原因进入
scan-coverage.json,并被挡在scannedFiles之外,绝不会被当成一个空文件来描述。只解析出一部分的文件会留下,但同样会被列出来——它的事实是真的,只是不完整,而你应该知道哪些页面是建立在这些事实之上的。 - 卡片生成失败的文件会得到一个空描述,绝不会得到编造的描述,并被列入
_coverage.json。 - doctor 循环提出的结构性修改,若引用了不存在的阶段、或会让文件成为孤儿,就会在触及骨架之前被拒绝。
- 评审者的回复解析失败时,按
REJECT计。
配置
- 密钥从来不是命令行标志,出现在配置文件里则会被拒绝——因为配置文件是要提交进版本库的。有两个设置属于密钥:
llmApiKey/OPENAI_API_KEY,以及llmExtraBody/OPENAI_EXTRA_BODY——后者内容完全自由,会被合并进每一个请求体,而网关确实接受写在那里的鉴权信息,所以没有任何办法分辨其中哪个是调参字段、哪个是凭据。 llmBaseUrl则刻意不被一概当作密钥:团队让所有本地检出都指向同一个共享网关,是有正当理由把它提交进去的。只有内嵌了凭据的 URL(https://user:pass@host/v1)会在配置文件里被拒绝。- 提供了但无效的值绝不会悄悄落回默认值。写错就是错误。
- 空值按未设置处理,因此
HANDBOOK_TITLE=不可能产出一本没有标题的手册。
检测漂移
SKILL 包中的 coverage.json 携带打包时捕获的每个文件的内容哈希。
handbook validate --skill skills/myrepo --source ~/code/myrepo会对当前源码重新计算哈希,并报告自那以后内容发生变化的每一个文件。智能体正是这样在依据过期断言行动之前得知*“这一页可能已落后于代码”*的——这也是给 handbook skill 传入 --work 和 --source 值得的原因。
纠错通道
当手册中的断言与真实源码相矛盾时,使用手册的智能体会向技能根目录下的 corrections.jsonl 追加一行 JSON:
{
"file": "src/engine.py",
"page": "references/stages/stage-2.md",
"claim": "spin() is defined in src/main.py",
"actual": "spin() is defined in src/engine.py"
}随后 handbook resync --corrections <file> 会恰好刷新其中点名的那些文件——即使它们的字节从未变过,因为一条被源码推翻的断言,本身就足以成为重新描述该文件的理由。
这个文件位于技能根目录,绝不放在 references/ 之下,因为规划器会以只读方式挂载那棵目录树。重建时,尚未处理的纠错记录会在清理过程中被保留下来。
Studio 的安全态势
Studio 是一个本地工具,也不假装自己不是。
- 默认绑定
127.0.0.1。 - CSRF 防护检查的是
Host请求头而不是套接字,因此只有回环主机名能通过。 POST要求application/json,从而挡住经典的跨源表单攻击。- 源码与手册文件的伺服被沙箱限制在已注册的根目录之内。
在容器中它必须绑定 0.0.0.0,否则发布出去的端口根本无法访问;但这并不会放宽谁能与它对话:请求里写局域网 IP 或容器主机名的仍然会得到 403。远程访问是一项刻意未实现的独立特性——它需要一份显式的允许列表。
Handbook 不声称知道的事
调用图无法告诉你一个决定为什么这样做、产品是拿来干什么的,或者你们团队的约定是什么。Handbooks 不去推断这些,也不假装能推断。它记录结构与行为;意图仍然要由你自己写下来。