docs: 两份 toolcall 文档对齐实现与部署实况

## 契约文档:状态头从「尚未实现」改为「已实现并部署」

生产已注册 7 个 `seq_*` 工具,但文档仍写着"设计定稿,尚未实现" ——
实现者(和读者)会以为 seq 还不存在。

新增 §9.3「实现落点」:设计稿 §8 写的是**六个** `seq_*` 工具,实现时
多了一个 `seq_when_call`(跨序列条件调用独立成工具,否则模型要手写
"先 seq_list 再挑目标再 seq_call",多一次往返且容易挑错),并记下三项
设计之外的修正(`seq_create` O(n²)、`Store.List()` 误认任意 `.json`、
存储用 AST 而非原始文本)。

同时点明:设计条款**仍是契约**,实现与本文冲突时以本文为准并修实现。

## 修一处预先存在的失效引用

§7 末尾 `见 §4.5` —— §4 只到 4.4,该小节不存在。改为按标题名引用
(`§4「结果契约」的 ErrToolNotFound 哨兵`):将来增删小节时不会再次失效。

自查脚本第一版把 8 个**存在**的章节误报成失效引用 —— 标题格式是
`## 1. 背景`(编号后跟 `.`),而我的正则要求编号后是空格。判据自己错了,
改成 `(\d+(?:\.\d+)*)\.?\s` 后才得到真实结果。

## 并行计划文档:部署小节 + 白名单专节

- 原「⚠ 部署前置条件(未完成)」改为「✅ 部署(已完成)」,补实际验证数据
- 记下"实例自述没有编排工具"不是说谎:生产二进制构建于 06:36、seq 引入
  于 `da8841e`(更晚)⇒ `strings | grep -c internal/plugins/seq` 为 0。
  这类"实例自述与代码状态不一致"应先查二进制构建时间,别急着怀疑提示词
- 新增「设备命令白名单改为可配置」:起因、替换语义、daemon 路径的疏漏
- 明确写下**已知局限**:白名单只匹配命令名、不看参数,
  `find -delete` / `sed -i` / `sort -o` 仍放行 ⇒ **不要把它叫"只读白名单"**,
  那会让人以为写操作被挡住了
- 记 106 此前无 `online` 日志的成因(旧 waiter 落在未 bind 时收 ping 会断连的
  缺陷窗口),以及 `ssh` 吃掉 `read` 输入导致"喂了 yes 却说已取消"

删掉了初稿里一段"反引号内 `+=` 写进 heredoc 导致赋值落到子 shell"的说法 ——
脚本与 git 历史里都没有这种写法,属凭记忆误记,不能留。

文中数字均与现场核对:seq 工具 7、二进制 86784400 / 12691402、白名单 22 条。
This commit is contained in:
JianFeeeee
2026-09-27 20:00:33 +08:00
parent f693af3960
commit 554d93cc7e
2 changed files with 148 additions and 3 deletions

View File

@ -3,7 +3,15 @@
> **前置**:本文建立在《输入调度器设计》(`docs/zh/input-scheduler-design.md`)与
> 《驻留式子 Agent 设计》(`docs/zh/resident-subagent-design.md`)之上。
>
> **状态**:本文是**设计定稿**,尚未实现。实现顺序见 §9。
> **状态**:**已实现并部署**(2026-09-27)。
> - 内核线(批内并行 + `ParallelSafe`/`Serial` 声明 + 保序落消息)与
> 插件线 P1–P4(`seq` 插件 + 七个 `seq_*` 工具)均已完成,
> 生产实例已注册 7 个 `seq_*` 工具。
> - 实现过程中的实测结论(压测数据、踩坑、修法)见
> 《toolcall-parallel-execution-plan》文末「附:更新前后全面压测结果」,
> 实现落点见本文 §9.3。
> - 本文的**设计条款仍是契约**:若实现与本文冲突,以本文为准并修实现。
>
> 标记:**[已定]**= 明确拍板;**[默认]**= 可逆取值,实现时在提交信息标注;
> **[待定]**= 需决策后才动手。
@ -614,7 +622,7 @@ if ret, err := parent.ExecuteTool(name, args); err == nil {
(`toolcall.go:104`)——这是**约定**不是契约:插件错误文案若恰好含该子串
即被误判,并错误 fallback 到 io。
⇒ 引入 `ErrToolNotFound` 哨兵(`errors.Is` 判别),见 **D5**。
本次**内核侧一并实施**(见 §4.5)。
本次**内核侧一并实施**(见 §4「结果契约」的 `ErrToolNotFound` 哨兵)。
#### 规则 5:`target` 形态非法
@ -703,6 +711,31 @@ if ret, err := parent.ExecuteTool(name, args); err == nil {
**插件线可以复用内核并行面**,但**不要求内核新增任何接口**。
若日后发现必须由内核代做(如统一授权闸),那是一次**单独的 SDK 扩展讨论**,
不在本设计范围内。
### 9.3 实现落点(实际交付的七个工具)
设计稿 §8 写的是"六个 `seq_*` 工具",实现时**多了一个 `seq_when_call`** ——
因为跨序列的条件调用(§5)在实现中被独立成一个工具,否则模型要手写
"先 `seq_list` 再挑目标再 `seq_call`",多一次往返且容易挑错。
| 工具 | 作用 |
| --- | --- |
| `seq_create` | 保存序列(创建时即解析 + 静态校验 + 跨序列调用图环检测) |
| `seq_run` | 执行序列(组内并行、组间串行) |
| `seq_list` | 列出已存序列 |
| `seq_call` | 按名调用序列 |
| `seq_when_call` | 条件成立时才调用目标序列 |
| `seq_delete` | 删除序列 |
| `seq_help` | 写序列前的集中入口(示例均经真实解析器验证) |
实现期的三项**设计之外的修正**(都是判据跑出来的,不是拍脑袋):
1. **`seq_create` 的 O(n²)**:`CheckGraph` 原先每次都 `List()+Load()` 全部序列。
改为调用图缓存 + `Save`/`Delete` 增量维护。
★ 性能优化**不得**把校验挪到运行期 —— 目标存在性与环检测仍必须在保存时做。
2. **`Store.List()` 把任意 `.json` 当序列**:改用专属 `.seq.json` 后缀。
3. **存储用 AST 而非原始文本**:执行期不重新解析,避免解析器与执行器语义漂移。
## 10. 待定项
| 编号 | 问题 | 建议 |