Files
Hermit/docs/eval_tool_cst.md
T
WHC 2fde898da0
ci / linux (clang) (push) Canceled after 0s
ci / linux (gcc) (push) Canceled after 0s
ci / sanitizers (push) Canceled after 0s
ci / musl (push) Canceled after 0s
ci / macos (push) Canceled after 0s
Usability pass: tool registry, TUI polish, saved keys and settings
Tools
- Table-driven tool registry with permission classes and default/minimal
  profiles; new tools: edit_file, list_dir, glob, grep, delete_file,
  move_file, todo_write, web_fetch, ask_user (plus read_file paging).
- Built-in Myers diff; write tools return unified diffs.
- Persistent permission rules (.agent/permissions.json), per-turn undo
  snapshots (.agent/undo), AGENTS.md project notes, auto-compact at 80%
  of the model context, cancellable run_shell with process-group kill.

TUI
- Table-driven slash commands: /provider /key /effort /status /tools
  /permissions /yolo /undo /retry /diff /export /copy /rename /delete
  /init /max-steps /todo, with / and @ completion.
- Permission modal with diff and prefix rules, ask_user modal, todo
  panel, header with model/effort/context, bracketed paste, line editing,
  wide-char cursor, NO_COLOR and ASCII fallback; Esc never quits.

Startup and configuration
- API keys are entered in the TUI (hidden) and saved per provider in
  <config>/credentials (0600); env variables are only a fallback.
- Last provider, per-provider model and reasoning effort are remembered
  in <config>/settings.json; --effort/-e and /effort send
  reasoning_effort (low|medium|high|max) to models that accept it.
- DeepSeek preset uses deepseek-flash / deepseek-v4-pro.
- Session flags --new/--continue/--resume/--list-sessions, --yolo,
  --confirm.

Compatibility and tests
- ncurses detection, macOS/Homebrew support, make install, XDG config
  dir, POSIX cleanups; Gitea CI (gcc/clang/asan/musl/macOS).
- Unit tests for diff, fs tools, registry, undo/perms and config;
  e2e fixtures multi_file_refactor and ask_or_todo; vendored cJSON.
2026-10-05 01:47:01 +08:00

8.8 KiB
Raw Blame History

Tool-loop CST 评测笔记(反哺论文素材)

本文是 CST-Agent 侧的评测/案例记录,供写入 SD 主论文附录或独立 TR 时粘贴。
不替代 SD/paper/sections/eval_zh.tex 中 Markdown→HTML 主实验。

理论锚点见 theory_tool_cst.md。

命题分工

层 主张 主变量 非主张
论文 CST (O_{\mathrm{conf}}) 有界确认 → HTML (\mathcal{L}_0) vs 引用式链接等 —
Tool-loop CST 同构到工具帧 CTL vs JSON-buffer 截断;确认即执行 网关空答率、模型智商
工程载体 五种协议同一 agent 循环 端到端通过率、步数、token、时延 不算进 CST 正确性定理

实验 A — 饥饿 / 截断(合成样例,已自动化)

make check     # 关注 tests/test_replay_starvation
指标 CTL JSON-buffer
完整输入可执行 yes yes
截断点上过早执行次数 0 n/a(截断即失败)
安全截断样本(本机 make check) 3 3 次 trunc failure

对应理论:裸 JSON ∉ (\mathcal{L}_0^{\mathrm{tool}});CTL 长度前缀使参数体字节可确认,pending 有界。 定界写法另有 tests/test_ctl_heredoc:对一个含 TAB、空行、end/call/围栏行和缩进 TAG 的体, 在每一个字节前缀上都不产生 CALL_READY,完整流上体逐字节还原。

实验 B — mini_calc 端到端案例(不可逆发射)

协议见 fixtures/mini_calc/ 与 scripts/e2e_fixture.sh。

./scripts/e2e_mini_calc.sh --baseline-only             # 无 key:证明 fixture 初始 RED
./scripts/e2e_mini_calc.sh --provider deepseek         # 有 key:agent 修 bug → make test

验收口径

每个夹具有 TASK.md(任务书)和 check.sh(判定脚本)。基线在一份临时副本上先跑 check.sh,必须失败。

outcome 含义
pass agent 结束后 check.sh 通过
fail agent 正常结束但 check.sh 失败
agent_error agent 非零退出(如连续契约错误、API 错误)
timeout 超过 E2E_TIMEOUT(默认 900 秒)
unexpected_green_fixture 夹具一开始就通过(夹具坏了)

论文可引用的叙事

  1. Session JSONL 中顺序:assistant 调用 → 工具结果 → 最终文本;只追加。
  2. 工具仅在确认(CTL end、原生参数完整)后执行;CTL 饥饿实验仍是形式主证据。
  3. 案例展示「确认后不可撤回的磁盘副作用」与 transcript 只追加。

稳定性(M1,DeepSeek deepseek-chat,ASAN + UBSan 构建)

日期 (UTC) 场景 结果
2026-09-07 mini_calc,MiniMax-M2.7 pass(旧版本,out/result-20260907T131300Z.txt)
2026-10-04 mini_calc 连续 10 次,native-eos 10/10 pass,ASAN/LSan 无报告
2026-10-04 makefile_tab(写含 TAB 的 Makefile;旧版本此处 HTTP 400) pass
2026-10-04 big_file(写 5000 字节文件;旧版本长内容被截断) pass
2026-10-04 test_fix_test(先跑测试→修→再跑;旧版本第二次 make test 被错误去重) pass,make test 实际执行 2 次
2026-10-04 mini_calc,ctl / ctl-heredoc / native-inc / xml 各 1 次(ASAN) 4/4 pass

实验 C — 真实模型流上的逐字节截断

make check     # 关注 tests/test_replay_real

数据:tests/fixtures/sse/deepseek-*/NNNN.sse,是 CST_RECORD_SSE 录下的 DeepSeek 原始 SSE 流(同一任务分别用三种协议)。 测试把每条助手消息还原成运行时看到的逻辑流,在每一个字节处截断:CTL 流喂给 CTL 解析器;原生流把各调用拼成 [{"name","arguments"},…],分别按 json-whole(整体可解析才执行,即 native-eos)和 json-object(每个对象可解析即执行,即 native-inc)计数。

全部前缀上 S1/S2/S3 成立(未完整调用不可执行;执行过的调用与完整流一致;可执行数单调)。可执行调用数随前缀比例变化:

消息 协议 字节 调用 25% 50% 75% 90% 100% 首个调用可执行于
heredoc #0 ctl-heredoc 193 3 0 1 2 2 3 45%
heredoc #1 ctl-heredoc 223 2 0 0 0 1 2 85%
ctl #0 ctl 74 2 0 0 1 1 2 51%
native #0 json-whole 100 2 0 0 0 0 2 100%
native #0 json-object 100 2 0 0 1 1 2 —
native #1 json-whole 108 2 0 0 0 0 2 100%
native #1 json-object 108 2 0 1 1 1 2 —

读法:json-whole 在流结束前一个调用都不能执行;CTL 与 json-object 都是前缀单调的,确认点落在每个调用结束处。 CTL 的区别在于 pending 有界((\le L_{\mathrm{line}})),json-object 的 pending 是整个参数对象。 另外 ctl 目录里 #1–#4 是四次长度前缀写错的消息(三次 patch 字节数写大、一次 content 写小,见实验 D),解析器在这些消息的任何前缀上一次也没有执行。

tests/test_sse_decode 还验证:录制流按 1 字节和 4096 字节分块回放,解码出的文本、调用和参数完全相同(网络分块不影响确认结果)。

实验 D — 协议对照矩阵(M3)

scripts/run_matrix.sh -p "native-eos native-inc ctl ctl-heredoc xml" \
  -m "deepseek:deepseek-flash" -f "mini_calc makefile_tab big_file test_fix_test" -n 3 -r
# → out/matrix-*/results.csv(每次运行一行)与 summary.md

2026-10-04,DeepSeek deepseek-chat,5 协议 × 4 夹具 × 3 次 = 60 次(out/matrix-m3/):

协议 n 通过率 步数 墙钟 s 模型时间 s 工具时间 s wait_ms 契约错误/次 输入 token 输出 token
native-eos 12 100% 4.2 5.38 5.11 0.24 30 0 9900 1058
native-inc 12 100% 4.7 5.90 5.82 0.26 0 0 10615 1084
ctl 12 58% 5.8 7.26 7.09 0.16 0 2.33 10574 1336
ctl-heredoc 12 100% 3.7 4.48 4.27 0.24 0 0 5728 756
xml 12 92% 5.7 7.09 6.84 0.19 53 1.75 10468 1398

wait_ms = 调用确认到开始执行的平均间隔。eager 协议恒为 0;流结束后执行的协议要等到整条消息结束。

契约错误分解(全部 12 次运行合计):

协议 参数写法使用次数 契约错误
ctl 长度前缀 33、行内 73 unexpected_line(数少了)20、body_eof(数多了)8
ctl-heredoc 定界 30、行内 29、长度前缀 0 0
xml — 标签写坏(如 <minimax:tool_call">)21

结论(可写入论文):

  1. 长度前缀对真实模型不可靠。模型几乎从不数对多行参数的字节数(33 次长度前缀参数里 28 次契约错误), ctl 只有 58% 通过,失败的运行都是连续契约错误后放弃。CST 的安全性仍然成立——错误帧从未被执行——但可用性差。
  2. 定界写法消除了计数负担,保留同样的确认前沿与有界 pending:ctl-heredoc 100% 通过、0 契约错误, 且步数、墙钟、token 都是五种协议里最少的(输入 token 比 native-eos 少 42%:不发 tools[] schema,参数也不需要 JSON 转义)。
  3. eager 执行在这些任务上的时延收益很小:确认到执行的等待从几十毫秒降到 0;墙钟差异主要来自步数和 token,而非执行时机。 原因是模型通常把耗时工具(make、测试)放在一条消息的最后一个调用,确认之后流几乎立即结束。
  4. 反馈让文本协议可恢复:xml 在加入“标签写坏→契约错误→要求重发”之前为 58%(out/matrix-m3-old-xml/),之后为 92%(重复一组为 83%,out/matrix-m3-xml-replicate/)。

注意事项:

  • 执行在 SSE 回调内同步进行,执行期间客户端暂停读流,所以客户端测得的“流结束”包含了工具时间。 summary.md 里的 overlap_s 因此是上界(native-inc 下恒等于工具时间),不能当作节省的时间引用。
  • 每格只有 3 次,模型输出有随机性;引用通过率时请同时给出 n。

与主论文的衔接建议

  • 附录 / 扩展节标题示例:「Tool-loop CST:确认前沿到工具调用」
  • 粘贴:theory 表(theory_tool_cst.md)+ 实验 A/C 表 + 实验 D 主表与结论 1–2。
  • 明确声明:主 fan-out / (\mathcal{A}=0) 数字仍来自 Sashidown;本笔记只提供 同构第二实例。

明确不写进定理的内容

  • 商业 API 空回复、权限 UX、TUI 观感
  • 「已达生产 coding agent」类宣称
  • 实验 D 的时延数字(受网络与服务端负载影响)