私のagent.mdでLLM支援コードの品質を向上
Fabien Sanglard は agent.md で LLM に手書きに近いコードを生成させ、毎回のセッションで同じ code review の指摘を繰り返すのをやめた。
日本語
コピー
私の agent.md:LLM 支援コーディングの品質を上げる
LLM でコーディングを速めようと初めて試したのは2025年半ば。印象は良くなかった。当時取り組んでいたのは libadbmdns、Rust で書かれた mDNS 実装だ。生成されたコードはコンパイルすら通らなかった。
2026年1月に再挑戦した。今度はかなり良かった。複雑なインデックス付き二分ヒープのクラスを書き上げただけでなく、polling crate の中に Windows の IOCP 実装に起因する隠れたバグを見つけ出した。
だがコードの品質は目も当てられなかった。スパゲッティコードの山で、コメントも構造もない。面白いのは確かだが、速度向上で得た利益をコードをプロダクション品質まで掃除するのに全部使い果たすなら、LLM を使うのは現実的でない。
反復して、同じことを何度も繰り返す
2026年3月、Antigravity や VS Code の Claude Code 拡張のような agentic IDE を使い始めた。これで「ステージング」したコードを「反復」できるようになった。自分は忍耐強い計算機科学の学部2年生にコードレビューをしているようなものだと気づいた。出す意見は「マジックナンバーを使うな」「ここに短いコメントを1行入れて説明しろ」「関数名を短くしろ」といった程度だ。
コード品質は大幅に上がり、自分の「手書き」にかなり近づいたが、その過程が面倒だった。新しいセッションを開くたびに、同じことをまた言い直さなければならない。
agent.md が救う
コーディングセッションの開始時に、コーディングハーネスは agent.md というファイルを読み込んで prompt に注入する。ここはコーディングスタイルの好みを細かく調整するのにうってつけの場所だ。同じ改善提案をまた繰り返していると気づくたびに、そこに書き足していく。
以下が私の agent.md だ。必要なら出発点として使ってほしい。プロジェクトのルートに置けばいい。あるいは gemini.md/claude.md を agent.md にシンボリックリンクすれば、どこでも効くようになる。
# FAB's AGENT.MD
- When writing something intended for human consumption, (comment, commit message, reply to prompt) use as few words as possible. Pick every word meticulously to reduce the volume to a strict minimum. Be down to the point. Less is more.
- Avoid superlatives and praise. Stop telling me I am absolutely right. Give me the cold hard truth.
- Avoid magic numbers and strings by extracting recurring or meaningful values into descriptive constants (const) or enums. Keep self-explanatory, one-off values inline to avoid clutter. If a value comes from a spec (e.g. HTTP 200 OK), use a constant regardless.
- Reduce code indentation. Avoid Arrow Anti-Pattern. Leverage early return and continue.
- Keep function names short. Less than 30 characters.
- Use enums instead of booleans for function parameters.
- Let the reader of the code breathe. Add empty lines between logical blocks of code.
- Add a small, to the point, comment to explain *what* the block does and *why*. Use examples when possible. Propose ASCII drawings to explain complete systems.
- Treat member visibility changes as a breaking design shift. Keep all fields and functions private unless external access is strictly required by the design. Prompt the user for explicit approval before changing any access modifier from private to internal or public.
- Program to levels of abstraction. Lower-level mechanics (e.g., raw hardware I/O, sector parsing, direct socket streams) must be encapsulated in a dedicated driver/abstraction layer. Expose clean, high-level APIs to the rest of the application so calling code works with domain concepts, not raw implementation details.
- Don't touch blocks of code unrelated to the feature you implement. e.g. Don't add comments to a block of code if you did not create it or modify it. As much as possible try to minimize the number of changed lines when implementing a feature.
- Strictly adhere to the layered boundary hierarchy: each layer may only communicate with its immediate neighbor directly below it. Never "punch holes" through layers (e.g., controllers or UI components must never directly call database queries, raw hardware drivers, or low-level network clients; always route through the intermediate service/abstraction layer).
- Always use {}, even on a one-line "if" statement.
When you write a commit message, follow these 7 rules:
Rule 1: Separate the subject line from the body with a single blank line.
Rule 2: Limit the subject line to 50 characters (72 is the absolute hard limit).
Rule 3: Capitalize the first letter of the subject line.
Rule 4: Do not end the subject line with a period.
Rule 5: Use the imperative mood in the subject line (e.g., "Fix bug," "Add feature,"
not "Fixed" or "Adds"). Test formula: It must complete the sentence: "If applied,
this commit will [your subject line here]".
Rule 6: Wrap the body text manually at 72 characters to prevent Git formatting issues.
Rule 7: Use the body to explain what and why vs. how. Assume the code explains the how;
the message must explain the context and reasoning.
- If the prompt indicates that a bug is being fixed, don't write the fix right away. First write the test. Observe it failing. Then write the fix. And observe the test passing.
この「コツ」で生成されるコードは確かにかなり良くなったが、万能薬ではないし、コードを読む手間を省いてくれるわけでもない。LLM は幻覚を繰り返すし、信用できない。今も大量に検証と反復をするが、注目するポイントはたいていコードスタイルではなくアーキテクチャと設計になった。
コンテキスト希釈にどう対処するか
LLM には「コンテキスト希釈」あるいは「注意希釈」と呼ばれる厄介な現象がある。Lost in the Middle という論文がこれを説明している。コンテキストが長くなるにつれ、モデルはコンテキスト中段の指示への注意を徐々に減らし、冒頭と末尾の内容の方に注目するようになる。これを書いている時点で、この現象の原因はよく分かっていない。影響を軽減する方法は2つしか見つかっていない。
- コンテキストを短く保つ。つまり、機能ごとに新しいセッションを開く。
- ハーネスに agent.md を再読み込みさせる。コード品質が落ちたと気づいたら、「Reload agent.md」と言えば済む。
agent.md を自動更新する
新しいルールを追加したいときに毎回エディタを開く必要はない。今は agent に agent.md を更新させている。