☰
只用你拥有的文件约束编码智能体:四个杠杆的对照实验
2026/10/16 6:34:53 网站建设 项目流程

只用你拥有的文件约束编码智能体:四个杠杆的对照实验

原文:Tessl Blog《How to constrain a coding agent using only files you own》(https://tessl.io/blog/how-to-constrain-a-coding-agent-using-only-files-you-own)

一个只过了一分的实验

作者给自己的编码智能体一个工单,但没有给它任何规范文件。这个仓库有三代历史:一个 2026 年写对一切的领域层,被一个 2023 年的巨型文件和 2021 年被冻结、谁都不许碰的模块,以十比一的数量压过去。智能体从头到尾没打开正确的代码:它去改了那个巨型文件,用 random.randint 掷骰子且完全不设随机种子,还两次伸手进冻结模块。

评分器有八项检查,结果只过了一项。仓库本身没坏,智能体只是照着眼前的代码抄了一遍——所有本来能拦住它的东西,都是作者当时还没写的文件。

「写个 CLAUDE.md」只是四个杠杆中的一个

写规范文件的建议到处都是,这建议本身没错,但那个文件只是四个杠杆之一,另外三个就躺在同一个仓库里、同样属于你。作者把「约束」拆成四种文件:

杠杆位置作用
指令 InstructionCLAUDE.md用现在时描述这个仓库是什么
约束 Constraint.claude/rules/按路径生效的规则,每条都带上引发它的那次事故的日期
能力 Capability.claude/commands/、.claude/skills/、.claude/agents/、.claude/settings.json、.mcp.json智能体能够到什么、被允许运行什么
检查 Check.claude/hooks/什么会拒绝它

能力杠杆上还有四级台阶:一条命令、一个技能、一个子智能体、一个 MCP server。怎么判断某个东西属于哪一级?作者给了一个很实用的判别法:把它拿走,如果智能体能力变弱,它就是能力;如果它干同样的活、只是干得更差,那你写的其实是一条规则,只不过被包装成了技能。

先做一个自检:

# 看看你的仓库里到底写了几种杠杆ls-R.claude/

如果输出只有一个 settings 文件,那你拥有四个杠杆,却只发了一个。

两个杠杆靠说服,一个靠拒绝

指令会被读,路径规则也会被读。凡是被读的东西都可以被辩论——当周围的代码和规则互相矛盾时,智能体会把自己说服过去。能力杠杆不参与辩论,因为它改变的是「能够到什么」,而不是「相信什么」。

hook 根本不被读。它是回合内执行的一个谓词,直接返回一个拒绝,没有谈判空间。作者的实现大约四十行 Python:一头挂在 PreToolUse 钩子上,在写入发生之前拦截;另一头是 make gate,也就是 CI 跑的那条命令。同一个谓词,两个挂载点,逻辑不重复。

# 示意写法:一个谓词,两个挂载点(非官方实现,字段以官方文档为准)ALLOWED_PREFIX="src/features/"defin_scope(path:str)->bool:"""这次写入是否落在本工单允许的范围内。"""returnpath.startswith(ALLOWED_PREFIX)defpre_tool_use(tool_name:str,args:dict):# PreToolUse 在工具执行前调用;返回 block 即拒绝iftool_name=="Write"andnotin_scope(args.get("file_path","")):return{"decision":"block","reason":"改动超出本工单范围"}returnNone

这段只是用来说明「同一个谓词挂在两处」这个形状。钩子的具体字段名与返回结构随版本演进,以官方文档为准。

规则要和代码「有分歧」才有价值

一条你的代码库本来就遵守的规则,约束不了任何东西。智能体照着模仿也能得到相同答案,你无法判断到底是规则起了作用,还是模仿起了作用。所以规则要写在「规则和代码互相矛盾」的地方。

工作坊仓库里就有一组矛盾:一个模块从会话中推导请求权限,另一个模块直接从请求体里读权限。两种写法都在线上跑、都能用。规范文件必须做出选择——它的职责就是告诉智能体照哪一个抄。这也是绝大多数「事后补规范」的实际工作内容。

机械可判定,与无法判定

九项检查里,八项程序能给出结论:改动是否留在范围内?每次掷骰子是否都设了种子?日志是追加还是重写?其余几项都是同一类问题,一个脚本就能不带任何意见地给出答案。

第九项叫 authority.semantic,问的是「这次权限检查对这个功能是否正确」。没有谓词能判定它,所以评分器只能打印一个问号,然后等人。

在那次八项全绿的运行里,一个审查子智能体读了 diff,填上了第九列,给出三个真实缺陷,其中一个是权限 bug:处理器用会话里的地牢主持人身份做判断,于是玩家读取自己角色存档的请求被拒了,而验收标准第 4 条要求放行。

评分全绿不等于改动正确,它只意味着「没有机械可发现的错」。这段距离,就是人工审查注意力该放的地方。

怎么把这套方法用在自己的仓库上

作者的复现路径很短:拿一个工单,先在完全没有规范文件的仓库上跑一遍,用你事先写好的检查项打分——这一遍就是「事故」,之后每写一条规则,都要能指回它;接着一次只加一个杠杆,重跑同一个工单,并说清楚是哪个杠杆推动了哪一项检查。

他自己在同一张工单上跑出的对照是:裸跑改动 3 个文件、新增 49 行、八项过一项;加上规范文件后改动 3 个文件、新增 102 行、八项全过。改动更大的那一版才是更好的那一版——这一点值得先说清楚,免得有人开始优化「改动行数」。

跑完你大概会发现两件事:有些规则什么也没约束住,因为代码本来就同意它们;以及至少有一条你真正在乎的规则,任何机器都判定不了——那正是最值得占用人力的一条。

约束编码智能体的一切,最终都是你拥有的文件。唯一的问题是:这四个杠杆,你到底写了几个。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询