메뉴
HN
Hacker News • 33일 전

LLM 코딩 품질을 높이는 나의 agent.md

IMP
6/10
핵심 요약

개발자 파비앙 상라르(Fabien Sanglard)가 LLM 기반 코딩 에이전트의 코드 품질 문제를 해결하기 위해 agent.md 파일에 코딩 스타일 규칙을 누적 기록하는 방법을 소개했습니다. 세션이 시작될 때 코딩 하네스가 agent.md를 프롬프트에 주입하므로, 매번 반복하던 피드백을 자동화할 수 있어 실무에서 LLM 활용 효율이 크게 향상됩니다.

번역된 본문

LLM 코딩 품질을 높이기 위한 나의 agent.md 활용법

LLM으로 코딩을 가속화하려는 첫 시도는 2025년 중반이었다. 당시에는 인상적이지 않았다. 나는 당시 Rust로 작성된 mDNS 구현체인 libadbmdns를 개발하고 있었는데, LLM이 생성한 코드는 컴파일조차 되지 않았다.

2026년 1월에 LLM을 다시 시도했다. 이번에는 더 잘 작동했다. 복잡한 인덱스 기반 이진 힙(binary heap) 클래스를 작성했을 뿐만 아니라, Windows IOCP 구현 때문에 발생한 polling 크레이트의 잘 알려지지 않은 버그까지 정확히 찾아냈다. 하지만 코드 품질은 형편없었다. 주석도 없고 구조도 없는 스파게티 코드였다. 멋있긴 했지만, 속도 이득이 프로덕션 수준의 기준을 충족시키기 위해 코드를 정리하는 데 다 소모된다면 LLM과 함께 작업하는 것은 현실적이지 않았다.

반복적인 피드백의 지루함

2026년 3월, Antigravity나 VS Code의 Claude Code 플러그인 같은 에이전틱(agentic) IDE를 사용해보았다. 이제 '단계적으로 작성된(staged)' 코드를 반복(iterate)하며 개선할 수 있었다. 나는 무한히 인내심 많은 컴퓨터공학과 신입 사원의 코드를 리뷰하는 듯한 경험을 했다. "매직 넘버를 쓰지 마라", "여기에 짧은 주석을 달아 설명해라", "함수 이름을 짧게 써라" 같은 피드백을 주면서 말이다. 코드 품질은 극적으로 향상되었고, 내가 직접 작성했을 결과물과 매우 가까워졌다. 하지만 지루한 작업이었다. 새 세션을 시작할 때마다 같은 지적을 반복하게 되었다.

agent.md가 해결사로 등장하다

코딩 세션이 시작되면 코딩 하네스는 agent.md라는 파일을 로드해 프롬프트에 주입한다. 이것이 코딩 스타일 선호도를 세밀하게 튜닝하기에 완벽한 장소다. 코드 개선을 위해 같은 지적을 반복하게 될 때마다 그 내용을 이 파일에 추가했다. 필요하다면 시작점으로 삼을 수 있도록 내 버전의 agent.md를 공유한다. 프로젝트 루트에 배치하는 것만으로 충분하다. 또는 gemini.md/claude.md를 agent.md로 심볼릭 링크하면 어디서든 활성화할 수 있다.

FAB의 AGENT.MD

  • 사람이 읽을 콘텐츠(주석, 커밋 메시지, 프롬프트 응답)를 작성할 때는 가능한 한 적은 단어를 사용하라. 볼륨을 최소한으로 줄이도록 모든 단어를 꼼꼼히 골라라. 핵심만 간결하게. 덜을수록 더다.
  • 과장 표현과 칭찬을 피하라. 내가 절대적으로 옳다고 말하지 마라. 차갑고 냉정한 진실을 말하라.
  • 반복되거나 의미 있는 값을 설명적인 상수(const)나 enum으로 추출해 매직 넘버와 매직 문자열을 피하라. 자명한 일회성 값은 코드를 어지럽히지 않도록 인라인으로 유지하라. 값이 스펙에서 온 것이라면(예: HTTP 200 OK) 일회성이어도 반드시 상수를 사용하라.
  • 코드 들여쓰기를 줄여라. 화살표 안티패턴(Arrow Anti-Pattern)을 피하라. 조기 반환(early return)과 continue를 활용하라.
  • 함수 이름을 짧게 유지하라. 30자 미만으로.
  • 함수 매개변수에 불리언 대신 enum을 사용하라.
  • 코드를 읽는 사람이 숨 쉴 공간을 줘라. 논리적 코드 블록 사이에 빈 줄을 추가하라.
  • 해당 블록이 무엇을 하는지(what) 왜 하는지(why)를 설명하는 짧고 핵심적인 주석을 달아라. 가능하면 예시를 사용하라. 전체 시스템을 설명할 때는 ASCII 다이어그램을 제안하라.
  • 멤버 접근성 변경을 파괴적인 설계 변화로 간주하라. 설계상 외부 접근이 반드시 필요한 경우가 아니면 모든 필드와 함수를 private으로 유지하라. 접근 제어자를 private에서 internal 또는 public으로 변경하기 전에는 사용자에게 명시적인 승인을 요청하라.
  • 추상화 계층에 맞춰 프로그래밍하라. 저수준 메커니즘(예: 원시 하드웨어 I/O, 섹터 파싱, 직접 소켓 스트림)은 전용 드라이버/추상화 계층에 캡슐화해야 한다. 나머지 애플리케이션에는 깔끔한 고수준 API를 노출해 호출 코드가 원시 구현 세부사항이 아닌 도메인 개념으로 작업하게 하라.
  • 구현하는 기능과 무관한 코드 블록은 건드리지 마라. 예를 들어 직접 만들거나 수정하지 않은 코드 블록에 주석을 추가하지 마라. 기능 구현 시 변경되는 줄 수를 최소화하도록 노력하라.
  • 계층 경계 위계를 엄격히 준수하라: 각 계층은 바로 아래 인접 계층과만 직접 통신할 수 있다. 계층을 "뚫고" 내려가지 마라(예: 컨트롤러나 UI 컴포넌트가... [원문 여기서 잘림])
원문 보기
원문 보기 (영어)
My agent.md to improve LLM-assisted code quality Fabien Sanglard - WEBSITE Aug 21, 2026 My agent.md to improve LLM-assisted code quality The first time I tried to use an LLM to speed up coding was in mid-2025. I was not impressed. I was working on libadbmdns back then, an mDNS implementation in Rust. The code produced would not even compile. I revisited LLMs in January 2026. This time it worked better. Not only did it write a complex indexed-binary heap class, it was able to pinpoint an obscure bug in the polling crate due to the Windows IOCP implementation. However, the code quality was abysmal. It was spaghetti code with no comments and no structure. It was cool but not realistic to work with LLMs if the speed gain was lost to cleaning up the code until it met the production-level bar. Iterating and repeating myself over and over again In March 2026, I tried to use agentic IDEs like Antigravity and VS Code's Claude Code plugin. I was now able to "iterate" over the "staged" code. I found myself reviewing the code of an infinitely patient junior CS major with suggestions like "don't use magic numbers", "add a short comment here to explain yourself", or "use short function names". The code quality improved dramatically. It was very close to what I would have produced "by hand" but it was tedious. I ended up repeating myself over and over again in each new session. Agent.md to the rescue When a coding session starts, the coding harness loads a file named agent.md and injects it into the prompt. This is the perfect location to super fine-tune coding style preferences. When I found myself repeating the same suggestion to improve the code, I added it in there. Here is my version of agent.md as a starting point if you need one. Placing it in the root of a project should be enough. Alternatively, gemini.md/claude.md can be symlinked toward an agent.md to have it active anywhere. # 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. While this "trick" has considerably improved the code generated, this is not a magic bullet that lets me avoid reading the code. LLMs constantly hallucinate and cannot be trusted. I still have to verify and iterate a lot but now I usually focus on architecture and design instead of code style. How to deal with dilutions There is an annoying phenomenon with LLMs called "context dilution" or "attention dilution" that was outlined in the Lost in the Middle paper. As the context grows, a model starts paying less attention to instructions in the middle of the context in favor of what is at the beginning and the end. The reasons why this happens are not well understood at the time I am typing this. I have found only two ways to minimize the impact. Keep the context short. This means starting a new session per feature. Explicitly ask the harness to reload agent.md . "Reload agent.md" is enough when I see code quality dropping. Auto-update agent.md You don't need to open an editor every time you want to add a new rule. What I do now is ask the agent to update agent.md. *