LLM 코드 품질을 끌어올린 agent.md 실전 사례
출처: Fabien Sanglard (fabiensanglard.net) / GeekNews(news.hada.io) 소개
원문: https://fabiensanglard.net/agent.md/index.html (GeekNews: https://news.hada.io/topic?id=32833)
작성자: 팔복소프트-김팔복
한눈에 보기
- LLM의 코드 생성 능력은 2025년 "컴파일도 안 되는 수준"에서 2026년 "복잡한 자료구조 구현과 서드파티 크레이트 버그 분석"까지 발전했다.
- 문제는 기능이 아니라 품질이다. 주석 없고 구조 없는 스파게티 코드를 정리하는 시간이 생산성 향상분을 상쇄했다.
- 저자는 세션마다 반복하던 리뷰 지침을
agent.md파일에 모아 프롬프트에 자동 주입되게 했고, 결과물이 직접 쓴 코드에 가까워졌다. gemini.md,claude.md를agent.md로 심볼릭 링크하면 여러 에이전트 환경에서 파일 하나를 공유할 수 있다.- 한계도 명확하다. 컨텍스트가 길어지면 중간 지침을 흘리는 문맥 희석(context dilution)이 생기므로, 기능 단위로 새 세션을 열거나
Reload agent.md로 지침을 다시 읽혀야 한다. - agent.md는 코드 리뷰를 없애주지 않는다. 스타일 지적 부담이 줄어 아키텍처·설계 리뷰에 집중할 수 있게 해줄 뿐이다.
배경
AGENTS.md(또는 agent.md, CLAUDE.md, GEMINI.md)는 코딩 에이전트가 세션 시작 시 자동으로 읽어 시스템 프롬프트에 주입하는 프로젝트 지침 파일입니다. Claude Code, Gemini CLI, Codex, Cursor 등 주요 도구가 각자의 파일명을 지원하며, 이를 통합하려는 AGENTS.md 표준화 움직임도 진행 중입니다. 이 글은 그 파일에 "무엇을 담아야 효과가 있는가"에 대한 한 베테랑 개발자의 실전 답안입니다.
주요 내용
능력의 문제가 아니라 습관의 문제
저자는 Rust 기반 mDNS 구현체 libadbmdns 개발에 LLM을 써왔습니다. 2026년 초에는 indexed-binary heap 같은 까다로운 클래스를 구현하고, Windows IOCP와 얽힌 polling 크레이트의 희귀 버그까지 찾아냈습니다. 그런데 결과물은 매직 넘버가 널려 있고 주석과 계층 구조가 없는 코드였습니다.
그래서 Antigravity, VS Code의 Claude Code 플러그인 등에서 staged 코드를 놓고 "매직 넘버 쓰지 마라", "의도를 설명하는 짧은 주석을 달아라" 같은 지시를 반복했고, 몇 차례 왕복하면 품질이 올라왔습니다. 문제는 새 세션마다 처음부터 다시 시켜야 한다는 것. 이 반복 지시를 파일로 굳힌 것이 agent.md입니다.
FAB의 AGENT.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.
규칙의 성격별 분류
원문에는 없는 형태로, 위 규칙을 성격별로 정리하면 이렇습니다.
| 분류 | 해당 규칙 | 린터로 대체 가능? |
|---|---|---|
| 기계적 스타일 | {} 강제, 함수명 30자 미만, 들여쓰기 축소 |
대부분 가능 (clippy, ESLint 등) |
| 설계 원칙 | 계층 경계 준수, private 기본, 추상화 계층 캡슐화 | 부분적 (아키텍처 린트 도구 필요) |
| 작업 범위 통제 | 무관한 코드 미변경, 변경 라인 최소화 | 불가능, agent.md가 유일한 수단 |
| 프로세스 | 버그 수정 시 실패하는 테스트 먼저, 커밋 7규칙 | 불가능 |
실제로 Hacker News 반응에서도 "기계적 규칙은 린터로 강제해야 사람도 같은 피드백을 받는다"는 지적이 많았습니다. 반대로 "변경 라인 최소화" 규칙은 린터로 잡을 방법이 없어 agent.md의 가치가 가장 큰 영역이라는 데 공감이 모였습니다.
문맥 희석이라는 함정
저자가 강조하는 운영상 주의점이 하나 있습니다. 컨텍스트가 길어지면 모델이 앞뒤 내용에 비해 중간에 주입된 지침을 덜 따르는 현상(논문 "Lost in the Middle"에서 다룬 문제)이 생깁니다. 대응책은 두 가지입니다. 기능 하나가 끝나면 세션을 새로 열어 컨텍스트를 짧게 유지하고, 세션 중 품질이 떨어지면 Reload agent.md라고 요청해 지침을 다시 읽히는 것입니다.
팔복소프트 관점
- 국내에서도 Claude Code, Cursor 도입이 팀 단위로 빠르게 늘고 있는데, 대부분
/init으로 자동 생성한 파일을 그대로 쓰거나 프로젝트 구조 설명만 넣는 데 그칩니다. 이 글의 핵심은 파일의 용도를 "프로젝트 소개"가 아니라 "반복되는 리뷰 피드백의 축적"으로 재정의했다는 점입니다. 이 관점 전환이 실무 가치의 대부분입니다. - 위 원본을 그대로 복사해 쓰는 것은 권하지 않습니다. HN 반응에서도 나왔듯 "짧은 함수명" 규칙이 억지 축약어를 유발하거나, "무엇을 하는지 주석" 규칙이 diff 잡음을 늘린다는 반론이 실제 경험에 기반해 제기됐습니다. 자기 팀이 에이전트에게 반복적으로 지적하는 항목부터 한 줄씩 쌓아가는 것이 맞는 접근입니다.
- 린터·포매터로 강제 가능한 규칙(clippy, ESLint, ktlint, Spotless)은 그쪽으로 옮기는 편이 낫습니다. 결정적으로 검증되는 도구가 있는데 비결정적인 LLM에게 부탁하는 것은 토큰 낭비이고, 컨텍스트가 길수록 지켜지지 않습니다. agent.md에는 "변경 범위 통제", "테스트 우선 버그 수정"처럼 도구로 강제할 수 없는 규칙을 남기는 게 효율적입니다.
- 규칙이 늘수록 컨텍스트를 잡아먹고 문맥 희석도 심해집니다. 팀 공용 파일을 만들 때는 규칙 수 상한을 정해두고, 상세 코딩 컨벤션은 별도 문서로 분리해 필요할 때만 참조시키는 구성을 검토할 만합니다.
정리
agent.md의 본질은 "코드 리뷰에서 같은 말을 두 번 하지 않기 위한 파일"입니다. 남의 파일을 통째로 가져오기보다, 에이전트에게 반복 지적한 내용이 생길 때마다 한 줄씩 추가하고, 린터로 옮길 수 있는 것은 옮기는 방식으로 운영하면 됩니다. 그리고 파일이 있어도 생성 코드 검증 책임은 여전히 사람에게 있다는 저자의 결론은 기억해둘 필요가 있습니다.
- agents.md
- Claude Code
- 코딩 에이전트
- 프롬프트 엔지니어링
- 코드 품질
아직 댓글이 없습니다.