2025年年中,Fabien Sanglard 第一次让 LLM 写代码。任务是用 Rust 实现 mDNS,结果连编译都过不了,他当场判定"不能用"。

半年多后,2026年1月他又试了一次。模型这次写出了一个复杂的索引二叉堆,还揪出了 polling 库在 Windows IOCP 实现里的一个隐蔽 bug。能力明显上了一个台阶,但代码本身没结构、没注释,读起来很累。

真正让这套工作流跑起来的,不是模型又聪明了多少,而是他后来在项目根目录放的一份 agent.md——把自己反复念叨的编码规矩,写成一份每次开工前自动加载的清单。

三次尝试,变的是什么

时间发生了什么代码质量
2025年中用 Rust 写 mDNS编译不过,判定不能用
2026年1月写出索引二叉堆,揪出 polling 库隐蔽 bug能力够,但没结构没注释
2026年3月换用 Antigravity、VS Code 的 Claude Code 插件逐条迭代质量上台阶,但每个新会话都要重复提醒
加 agent.md 之后规则常驻,不用每次重新念叨风格问题大减,审查转向架构

这条时间线对个人开发者的意义很直接:模型能力涨了,不代表代码风格会自动变好。真正管用的是流程和约束,不是等模型自己开窍。

agent.md 管住了什么,又管不住什么

机制很简单:会话开始时,编码工具加载这份文件,注入到 prompt 里。放项目根目录就够用;想让 claude.md、gemini.md 也生效,软链接指向同一份文件即可。但这套加载机制因工具而异,不同 agentic IDE 的实现细节和版本可能不完全一致,目前也没有统一标准。

里面写的多是硬约束:

规则目的
少用魔法数字,减少嵌套缩进降低阅读成本
分层边界:上层只跟相邻一层说话,不许跨层直连底层 I/O防止架构被打散
改动尽量小,别顺手重构没关系的代码减少审查负担
修 bug 先写一个失败的测试,再动手改把回归风险摆到明面上
分层边界:只能跟下一层说话 UI / Controller Service / 抽象层 Driver / 硬件 I/O 越层调用(UI 直连 Driver)禁止

这些规则大多是他在 Rust、C++ 项目里磨出来的个人偏好。换一门语言、换一个团队,细节大概率要重新调,他自己也没把这份清单当成通用标准。

agent.md 不是模型训练,更不是 fine-tuning。它只是会话启动时塞进上下文的一份指令文件,模型的底子没变。生成的代码依然要逐行核实,幻觉不会因为一份文件消失。

省下来的是重复劳动,不是工程判断

以前每开一个新会话,都要把"别用魔法数字"这类话再讲一遍。现在规则常驻,他把精力挪到了架构和设计判断上——这是这份文件带来的直接收益,也是它唯一能保证的收益。

代码质量的天花板,还是压在审查这一步。agent.md 拉高了地板,没有动天花板。

上下文一长,模型对中间那部分指令会越来越不上心。这是 Lost in the Middle 那篇论文提过的现象:开头结尾记得清楚,中段容易被糊弄过去。目前能用的应对办法只有两条:按功能拆分会话,别把上下文堆成一锅粥;发现代码质量下滑,直接要求"重新加载 agent.md"。这两条本质都是人在盯着机器的注意力,不是机器学会了长期记忆。

个人开发者可以直接照搬这套清单,放进项目根目录试一试,成本很低。团队负责人要多想一层:如果让 agent 自己往 agent.md 里加新规则,省事是真的,但这份"规矩"会在不知不觉中被机器改写。个人项目隔段时间自己翻一遍就行,团队协作的话,谁来审批规则变更得先定下来——规则膨胀比代码风格混乱更难查。

从编译不过,到能定位 Windows IOCP 里的隐蔽 bug,LLM 写代码的能力确实在涨。但决定代码能不能进生产的,从来不是模型多聪明,是审查这道关卡有没有人真的把住。agent.md 顶多算把老师傅的经验写成了操作手册——新手照单子能干出八成,剩下那两成,还得有人拍板。