开发者 Fabiensanglard 分享自研 agent.md 工作流:通过结构化指令让 LLM 产出更稳定、可维护的代码,并附实战经验。
第一次尝试用 LLM 提速编码是在 2025 年中。彼时我并不满意。当时我在做 libadbmdns,一个 Rust 里的 mDNS 实现。生成的代码甚至无法编译。
2026 年 1 月我重新审视了 LLM。这一次效果好了不少。它不仅写出了一个复杂的索引二叉堆类,还定位到了一个 polling crate 里因 Windows IOCP 实现导致的冷门 bug。
然而代码质量惨不忍睹。 spaghetti code,没有注释,没有结构。如果提效的收益被后期清理代码以达到生产级标准所抵消,那和 LLM 共事就不现实了。
2026 年 3 月,我尝试了 agentic IDE,比如 Antigravity 和 VS Code 的 Claude Code 插件。这时我可以对"分阶段"代码进行"迭代"了。我发现自己像在审阅一个耐心无限的 CS 专业实习生,会提一些建议比如"别用魔法数字"、"这里加个简短注释解释一下"或者"用短一点的函数名"。
代码质量显著提升了。很接近我"亲手"写出来的水平,但很繁琐。每次新会话里我都在重复同样的话。
当一个编码会话启动时,coding harness 会加载一个名为 agent.md 的文件并将其注入 prompt。这正好是超级微调编码风格偏好的最佳位置。当我发现自己在重复同样的建议来改进代码时,就把它加进去。
以下是我的 agent.md 版本,如果你需要可以拿去作为起点。放在项目根目录即可。另外也可以把 gemini.md / claude.md 符号链接到 agent.md,让它在任何地方生效。
# FAB's AGENT.MD
- 写给人看的东西(注释、commit message、回复 prompt),用词越少越好。精心挑选每个词,把篇幅压缩到最低限度。直击要点。少即是多。
- 避免 superlatives 和夸赞。别再告诉我我是绝对正确的。给我冰冷的事实。
- 通过把重复出现的或有意义的值提取成描述性常量(const)或枚举来避免魔法数字和魔法字符串。保持自解释的一次性值内联,避免冗余。如果某个值来自规范(比如 HTTP 200 OK),无论是否重复都使用常量。
- 减少代码缩进。避免 Arrow Anti-Pattern。善用 early return 和 continue。
- 函数名要短。少于 30 个字符。
- 函数参数用枚举替代布尔值。
- 让代码读者能喘口气。在逻辑代码块之间加空行。
- 加一个简洁、切中要点的注释解释这个块*做什么*以及*为什么*。可能的话使用示例。提议用 ASCII 图形来解释完整系统。
- 把成员可见性变更视为破坏性设计变更。除非外部访问是设计严格要求的,否则保持所有字段和函数 private。在将任何访问修饰符从 private 改为 internal 或 public 之前,需征得用户明确同意。
- 按抽象层级编程。底层机制(比如原始硬件 I/O、扇区解析、直接 socket 流)必须封装在专门的 driver/abstraction 层中。向应用其余部分暴露简洁、高层次的 API,让调用方用领域概念而非原始实现细节工作。
- 不要碰和当前功能无关的代码块。比如如果你没有创建或修改某段代码,就不要给它加注释。实现功能时尽可能减少改动的行数。
- 严格遵守分层边界层级:每一层只能与其正下方相邻层直接通信。永远不要在层之间"打洞"(比如控制器或 UI 组件绝不能直接调用数据库查询、原始硬件驱动或底层网络客户端;始终通过中间 service/abstraction 层路由)。
- 始终使用 {},即使是一行 if 语句。
写 commit message 时,遵循以下 7 条规则:
规则 1:用一行空行将 subject 行和 body 分隔开。
规则 2:subject 行限制在 50 个字符内(72 是绝对硬限制)。
规则 3:subject 行首字母大写。
规则 4:subject 行末尾不要加句号。
规则 5:subject 行使用祈使语气(如 "Fix bug"、"Add feature",而不是 "Fixed" 或 "Adds")。测试公式:它必须能完成这个句子:"If applied, this commit will [your subject line here]"。
规则 6:手动将 body 文本在 72 个字符处换行,以防止 Git 格式化问题。
规则 7:用 body 解释是什么和为什么,而非如何做。假设代码解释了如何做;message 必须解释上下文和推理过程。
- 如果 prompt 表明正在修复一个 bug,不要立刻写修复方案。先写测试。观察它失败。然后再写修复方案。观察测试通过。
虽然这个"技巧"显著提升了生成代码的质量,但它并非能让我免于阅读代码的神弹。LLM 不断产生幻觉,无法被信任。我仍然需要大量验证和迭代,但现在我通常专注于架构和设计,而非代码风格。
LLM 有一个恼人的现象,叫做"上下文稀释"或"注意力稀释",在 Lost in the Middle 论文中有概述。随着上下文增长,模型开始减少对上下文中段指令的关注,转而更看重开头和结尾的内容。写这句话时,这个现象的原因尚未被很好地理解。我只找到了两种最小化其影响的方法。
保持上下文简短。这意味着每个功能开一个新会话。
明确要求 harness 重新加载 agent.md。当我看到代码质量下降时,说"Reload agent.md"就够了。
你不需要每次想加新规则时都打开编辑器。我现在的做法是让 agent 来更新 agent.md。