用Git钩子治AI漂移:Geoffrey Huntley的Agent强制纠偏术

与其反复写prompt纠偏Agent,不如用pre-commit钩子把规范变成不可绕过的门禁。
文章引述 Geoffrey Huntley 的观点,指出用不断更新 AGENTS.md 来纠正编码 Agent 行为存在根本缺陷:规则与行为之间永远有 delta,并会随代码库演化持续漂移。Huntley 的替代方案是把规范从指导性文档变成强制性关卡——写一个 pre-commit hook,扫描 git diff,一旦发现绕过 diagnostics 统一入口、直接调用底层 observability 模块的代码,就让 commit 失败,同时向 Agent 注入 prompt 告知正确做法。这一机制的精妙在于它不是建议而是阻断,Agent 撞上墙时墙上正好贴着答案。作者进一步指出,这本质上是把纠偏点从概率性的模型理解转移到确定性的代码门禁,属于 agentic engineering 的典型思路,并可迁移到任何能被静态检查表达的约束场景。
AI编程Agent越来越像"不听话的新员工":明明给了规范,它偏要用自己那套。Geoffrey Huntley在《nobody should type code by hand anymore. here's what's left.》里给出的解法不是反复写prompt,而是把规则钉死在Git钩子上。

频繁纠偏为何注定失败
Huntley描述了一个几乎所有重度使用代码Agent的人都会遇到的场景:他有一个"diagnostics library"(诊断库),希望Agent所有观测相关调用都走这个统一入口。但Agent并不总是照做——它可能直接调用底层的observability模块,绕开了他的封装层。
面对这个问题,Huntley说他可以"introspect and update AGENTS.md"——也就是去观察Agent的行为,然后不断把新规则写进AGENTS.md这个配置文件里。但这个做法有一个根本缺陷:"there's still a delta, and it'll drift"。规则文档和Agent实际行为之间永远存在偏差,而且这个偏差会随着代码库演化持续扩大。你补一条规则,Agent绕过它的方式就多一种。
这本质上是用一个无限维护的文本文件,去追赶一个持续变化的执行体。在传统工程里,我们早就知道靠文档约束行为是不可靠的——真正可靠的是编译器、linter、CI流水线。
把约束下沉到pre-commit钩子
Huntley的方案是把规范从"指导性文档"变成"强制性关卡":写一个pre-commit hook,扫描git diff,检查是否存在对observability模块的直接调用——也就是那些绕过diagnostics模块的调用。
一旦检测到违规,commit直接失败,并向Agent注入prompt,告知它应当使用diagnostics库。
这个机制的精妙之处在于:它不是一个建议,而是一个阻断。Agent在执行流程中会撞上一堵墙,而墙上贴着的正是它需要的正确做法。Huntley对此的评价非常直接:"All of a sudden it's ten out of ten."——一下子就是满分表现。
pre-commit hook 是 Git 提供的一种客户端钩子机制:在 .git/hooks/ 目录下放置一个名为 pre-commit 的脚本,每当执行 git commit 时,Git 会在真正创建提交对象之前调用它。如果脚本以非零状态码退出,提交就会被中止,暂存区里的内容不会被写入版本历史。这使得 pre-commit 成为一个天然的"门禁点"——它既发生在代码进入仓库之前(成本最低、回滚代价最小),又能直接拿到本次提交的 diff 内容做静态分析。实践中常用 pre-commit 框架(如 Python 的 pre-commit 包或 Husky)来统一管理这些脚本,方便在团队内分发和版本化。理解这一机制是理解本文方案的前提:Huntley 正是把"规范应该长什么样"这件事,从一份可被忽略的 Markdown 文档,变成了一个必然执行、无法绕过的脚本。
为什么这比改AGENTS.md更聪明
传统的Agent纠偏思路是在"输入端"加信息:更长的system prompt、更细的AGENTS.md、更多的示例。这些做法有两个问题:一是Agent并不保证阅读或遵守;二是随着代码库变化,规则很快过时。
Huntley的做法把纠偏点挪到了"执行出口":不管Agent读到什么、想到什么,只要它产生的diff违反规则,就立刻被拦截。这里的关键差异是——拦截点是确定性的代码检查,而不是概率性的模型理解。
这个思路和"agentic engineering"这个领域的核心命题高度一致:与其期望模型每次都做对,不如用工程化的门禁来保证错误无法进入主干。pre-commit hook的位置也选得恰到好处——它在代码进入版本库之前,是成本最低的拦截点。
AGENTS.md 是近年来随着编码 Agent 普及而流行起来的一种约定文件:它以 Markdown 形式放在仓库根目录(或子目录),用来向 Agent 描述项目结构、编码规范、常用命令和禁忌事项。不同工具对它的读取方式不同,但本质都是"在上下文窗口里塞一段说明"。它的问题与 system prompt 同源——模型可能不读、读了可能忘、忘了可能仍按训练时的默认习惯行事,而且它的生效是概率性的。Huntley 的观点并非否定 AGENTS.md 的价值(作为背景说明它仍然有用),而是指出它不该被当作"约束"来用。约束需要确定性,说明可以模糊;把两者混在一份文档里,就会出现"规则写了、Agent 还是绕过"的经典困境。区分"上下文"与"门禁",是把工程纪律引入 Agent 工作流的第一步。
一个可迁移的模式
这套打法的适用范围远不止diagnostics库。凡是"我希望Agent总是走统一入口、禁止绕路"的场景,都可以用同样方式落地:强制使用公司封装的日志模块、禁止直接读环境变量而要走config层、禁止在特定目录引入某类依赖……只要这个约束能被写成静态检查,就能被写成pre-commit钩子。
Huntley的这段话之所以值得引述,是因为它示范了一种从"prompt工程师"到"Agent流程工程师"的思维转变:与其和模型对话,不如为模型搭建结构。AGENTS.md可以被忽略,但失败的commit跑不过去。
agentic engineering 是与 prompt engineering 相对的一个提法:后者的核心工作是打磨输入文本,希望模型在下一次生成时更听话;前者的核心工作则是设计模型所处的环境——工具、权限、反馈回路、失败边界。它借鉴的是传统软件工程对"不可靠组件"的处理哲学:不指望每个模块永远正确,而是用接口契约、类型系统、CI 门禁把错误限定在可控范围内。在 agentic engineering 视角下,模型是一个高方差但高产出的执行者,工程的任务是给它搭建跑道和护栏,而不是反复劝说它别越线。Huntley 的 pre-commit 方案正是这一思路的具体化:与其试图消除 Agent 的"不听话",不如让不听话在物理上无法落地。
相关推荐

CSS锚点定位:告别JavaScript的UI定位新方案
深入解析CSS锚点定位:从anchor-name、position-anchor到anchor()函数、position-area简写、position-try-fallbacks回退机制,以及anchor-size和即将到来的anchor queries。了解这一替代JavaScript定位方案的核心能力与当前限制。

AI图表交互新玩法:在对话中连续追问与可视化
探索AI对话中连续生成图表的新交互方式,通过/visualize命令在同一聊天窗口追问并可视化答案,提升数据分析效率。

Cursor并入X订阅:付费计划共享额度,Grok模型编程用量翻倍
Cursor正式并入The X Subscription,付费计划共享统一用量池,Grok模型编程用量翻倍,第三方模型转为API定价。现有Cursor用户可保留原计划或迁移,Premium、Super、Ultra额外包含Grok Bot。