에이전트 컨텍스트(Agent contexts) - 코딩 에이전트에게 정보를 제공하는 도구
요약
다양한 AI 코딩 에이전트(Claude Code, Cursor 등)가 프로젝트의 규칙과 컨벤션을 자동으로 파악할 수 있도록 돕는 CLI 도구 'agent-contexts'를 소개합니다. 무분별하게 큰 컨텍스트를 제공하는 대신, 작업 목적에 맞는 최적화된 컨텍스트를 관리하는 방법론을 다룹니다.
핵심 포인트
- 에이전트마다 요구하는 설정 파일 형식이 달라 관리가 번거로움
- 컨텍스트의 크기가 무조건 크다고 성능이 좋아지는 것은 아님
- 작업 목적(기능 구현 vs 리팩터링)에 따른 맞춤형 컨텍스트 제공 필요
- agent-contexts CLI를 통한 효율적인 에이전트 컨텍스트 관리
AI 시대에는 재미있는 현상이 일어나고 있습니다. ~/code/wishful-thinking/ 디렉토리에 먼지만 쌓여가던 사이드 프로젝트들이 다시 먼지를 털고 일어나고 있습니다. 갑자기 GitHub에 있던 "언젠가 이걸 써야지"라고 생각했던 저장소(repo)에 제대로 된 README가 생기고, 작동하는 CI가 구축되며, 실제로 해결하고 싶은 세 개의 오픈 이슈(open issues)가 생겨납니다.
왜일까요? AI는 불평하지 않기 때문입니다. 지루해하지도 않습니다. 아이들이 잠든 밤, 스스로를 대견하게 여기며 "지금이야말로 개인 프로젝트를 실현할 시간이야"라고 생각하는 밤 11시에, "그런데 X가 있는데 왜 이게 필요해?"라고 묻지도 않습니다.
따라서 담론이 당신을 LLM(Large Language Models)으로 대체하는 것에 몰두하는 동안, 당신은 당신을 대신해 자리 잡았던 미루는 습관(procrastination)을 대체하기 위해 조용히 LLM을 사용하고 있는 것입니다.
이 포스트는 그러한 순간들 중 하나, 즉 AI 이전 시대였다면 "노트북을 켜기엔 너무 늦었어"라는 생각 뒤로 잊혔을 법한 밤에 태어난 아이디어 중 하나에 관한 것입니다. 바로 제가 40개의 서로 다른 저장소에 걸쳐 40개의 AGENTS.md 탭을 열어두는 것에 질려 직접 작성한 agent-contexts라는 작은 CLI(Command Line Interface) 도구입니다.
"컨텍스트(Context)"란 무엇이며 왜 중요할까요?
Claude Code, Cursor, Gemini CLI 또는 다른 에이전트 도구(agentic tools)를 사용할 때, 이들은 당신의 마음을 읽지 못합니다. 무언가를 말해줘야 합니다. 그중 일부는 채팅을 통해 전달할 수 있습니다. 하지만 중요한 사항들 — 프로젝트 컨벤션(conventions), "여기서는 이렇게 하지 마세요"라는 규칙, "우리는 스페이스 대신 탭을 사용합니다, 반박 시 당신 말이 맞습니다"와 같은 것들 — 은 저장소 자체에 존재해야 하며, 그래야 모든 에이전트(그리고 모든 팀원)가 이를 자동으로 파악할 수 있습니다.
에이전트마다 정보를 찾는 방식(conventions)이 다릅니다:
- Claude Code는
CLAUDE.md를 찾습니다 (Anthropic은 속이 좁지 않기에AGENTS.md도 찾습니다). - Gemini CLI는
GEMINI.md를 찾습니다. - GitHub Copilot, OpenAI Codex, Cursor 및 그 친구들은
AGENTS.md를 사용합니다. - 많은 도구들이
.cursorrules및 유사한 파일들도 지원합니다.
따라서 만약 여러분이 다국어 에이전트 설정 (polyglot agent setup, 요즘 이런 설정을 안 하는 사람이 어디 있겠습니까)을 운영하고 있다면, 프로젝트당 여러 개의 파일을 유지 관리해야 합니다. 이는 코드 한 줄을 쓰기도 전에 짜증 나는 일입니다.
컨텍스트는 뷔페가 아니라 다이어트입니다
제가 고생하며 배운 사실은 다음과 같습니다: 더 큰 컨텍스트가 반드시 더 나은 컨텍스트를 의미하지는 않는다는 점입니다.
2019년부터 오늘날까지의 모든 아키텍처 결정 사항을 담은 4,000줄짜리 AGENTS.md를 에이전트에게 입력하면, 두 가지 현상이 발생합니다:
- 모델이 느려지고 비용이 더 많이 듭니다.
- 모델의 성능이 저하됩니다. 상충하는 지침, 더 이상 관련이 없는 오래된 컨텍스트, 작년에 삭제된 코드 경로의 예외 케이스(edge cases) 등이 모두 "지금 당장 무엇을 해야 하는가"에 대한 버퍼(buffer)를 오염시킵니다.
동일한 프로젝트라도 모든 작업에 대해 동일한 컨텍스트를 원하는 경우는 드뭅니다:
- 새로운 기능을 구축할 때? 아키텍처 개요, 기존 패턴, 컨벤션 (conventions)이 필요합니다.
- 기존 코드를 리팩터링할 때? 제약 조건, 의존성(dependencies), "이 부분은 하중을 지탱하고 있으니 건드리지 마시오"와 같은 주의 사항이 필요합니다.
- 버그를 추적할 때? 진단 플레이북(diagnostics playbook), 로깅 컨벤션, 테스트 스캐폴딩 (test scaffolding)이 필요합니다.
- 새로운 개발자(사람 또는 AI)를 온보딩할 때? 실행 방법, 가장 먼저 살펴볼 곳, 변경해도 안전한 부분 등이 담긴 오리엔테이션 가이드가 필요합니다.
동일한 저장소(repo) 내에 네 개의 서로 다른 AGENTS.md 파일이 있는 셈입니다. (게다가 src/payments/ 폴더는 그 자체의 컨텍스트를 가질 자격이 충분하므로, 하위 폴더를 위한 중첩된 파일들도 포함됩니다.)
초기에 생각난 "당연한" 해결책은 루트(root)에 하나의 거대한 모놀리식 (monolithic) AGENTS.md를 두는 것이었습니다... 하지만 곧 그 방식이 얼마나 비효율적인지 깨닫게 됩니다. 현재 또 다른 "당연한" 해결책은 모든 폴더에 수동으로 관리되는 중첩된 AGENTS.md 파일 트리(tree)를 만드는 것입니다. 이 방식은 품질 면에서는 승리하지만 유지 관리 면에서는 패배합니다. 누군가 루트 컨벤션을 업데이트하는 날, 그 내용을 전파해야 한다는 사실을 기억해야 합니다. 그리고 아무도 기억하지 못하죠.
등장: Vercel의 Skills
Vercel 팀도 얼마 전에 비슷한 갈증을 느꼈고, 이를 agent skills로 해결했습니다. 그들은 "에이전트가 업무를 수행하는 데 필요한 것들" (지침(instructions), 스크립트(scripts), 참조(references))의 번들을 하나의 패키지로 취급했습니다. 그래서 이를 설치 가능하게 만들었습니다. npx skills add <source>를 실행하면, 도구가 적절한 파일을 가져와 올바른 위치에 배치하고, 무엇이 설치되었는지 lockfile에 기록합니다. 결정론적(Deterministic)이고, 버전이 관리되며, 번거로움이 없습니다.
하지만 skills는 _역량(capabilities)_에 관한 것입니다: "내 CI를 실행하는 방법은 이렇다", "배포하는 방법은 이렇다", "DB를 시딩(seed)하는 스크립트는 이것이다"와 같은 것들 말이죠. 이는 동작(behavior)이 아니라 컨텍스트(context)를 배포하고자 하는 AGENTS.md 사용 사례를 제대로 다루지 못합니다.
그래서 저는 같은 맥락에서, 하지만 컨텍스트 파일로 범위를 한정한 무언가를 만들었습니다.
agent-contexts: AGENTS.md를 위한 npm
agent-contexts는 CLI입니다. 다음과 같이 생각하면 쉽습니다:
중앙 git 리포지토리에서 에이전트 컨텍스트를 한 번 큐레이션(Curate)합니다. 이를 모든 소비자 프로젝트(consumer project)에 설치합니다. 버전이 관리되며, 결정론적이고, 재현 가능합니다.
작동 방식
컨텍스트 리포지토리의 루트에 contexts.yml을 작성합니다:
version: "1"
name: engineering-contexts
...
각 매핑(mapping)은 소비자 프로젝트의 폴더를 컨텍스트 리포지토리의 프로필 파일로 연결합니다. 그 후 agent-contexts add는 다음을 수행합니다:
- 컨텍스트 리포지토리를 git-ignored 캐시인
.contexts/cache/<slug>/에 실체화(Materializes)합니다. - 모든 대상 경로에 상대적(relative) 심볼릭 링크(symlink)를 생성합니다. (네, 상대적입니다. 그래야 프로젝트를 이동한 후에도 여전히 작동하니까요.)
- 각 소스를 커밋 SHA(commit SHA)에, 각 파일을 SHA-256 해시(hash)에 고정(pinning)하는
contexts.lock을 작성합니다.
agent-contexts install은 컨텍스트계의 npm ci입니다. 매니페스트(manifest)를 읽지 않고 오직 contexts.lock만 읽기 때문에, CI가 매니페스트를 가져오거나 상위 저장소의 가용성을 추측할 필요가 없습니다. 매번 동일한 lock, 동일한 파일을 보장합니다.
agent-contexts status는 디스크에서 실제 상태를 다시 계산하며, 무언가 깨졌거나, 누락되었거나, 수동으로 수정된 경우 0이 아닌 종료 코드(non-zero exit code)를 반환하며 종료합니다. CI 게이트(gate)로 활용하기 쉽습니다.
태그(Tags): 다른 컨텍스트, 동일한 폴더
수행 중인 작업에 따라 동일한 폴더에 대해 서로 다른 컨텍스트(context)가 필요할 때가 있습니다.
예를 들어, 저장소(repo)에 기본 톤(default tone)이 설정되어 있다고 가정해 봅시다. 차분하고 전문적이며 프로덕션 코드베이스(production codebase)에 집중하는 톤입니다. 하지만 오늘은 리팩터링(refactoring)을 하고 있어서, "이것을 변경하기 전에 다음을 고려하세요..."와 같은 추가적인 교육적(pedagogical) 톤을 원할 수 있습니다. 또는 주니어 개발자를 온보딩(onboarding) 중이라 프로젝트 전용 용어집(glossary)을 전면에 배치하고 싶을 수도 있습니다.
이러한 것들을 **태그(tag)**로 작성합니다:
mappings:
".":
context_source: ./agents/root/AGENTS.md
...
플래그(flag)를 사용하여 전환합니다:
npx agent-contexts add your-org/your-contexts --tag onboarding
# 또는
npx agent-contexts update --tag refactor
유효한 집합은 root ∪ tag (충돌 시 tag가 우선함)이므로, 차이점만 작성하면 됩니다. 락(lock) 파일은 각 항목이 어떤 태그에 있는지 기록하므로, install 명령은 이를 재현하고 update 명령은 해당 상태를 유지합니다.
작은 엔드 투 엔드(end-to-end) 예시
NestJS 마이크로서비스(microservice)가 있습니다. src/products 폴더에 스타워즈(Star-Wars) 톤의 AGENTS.md를 적용하고 싶다고 가정해 봅시다. 그냥 재미 삼아서 말이죠.
# contexts repo
mkdir -p agents/star-wars
...
사용자 프로젝트(consumer project)에서는:
npx agent-contexts add ../your-contexts --tag star-wars --force -y
# src/products/AGENTS.md는 이제 캐시된 파일로 연결되는 상대 심볼릭 링크(relative symlink)가 됩니다.
# contexts.lock은 tag=star-wars와 파일의 SHA를 기록합니다.
...
이것이 전체 루프(loop)입니다. 심볼릭 링크로 삽입되고, 버전 관리되며, 전환 가능하고, 재현 가능합니다.
실제(그리고 덜 농담 같은) 조합: CI에서의 코드 리뷰
태그는 제가 계속 마주치는 특정 시나리오에 딱 맞는 도구임이 드러났습니다. 바로 모든 PR(Pull Request)마다 코드 리뷰 에이전트(code-review agent)를 실행하는 CI 작업입니다. 해당 에이전트가 개발 시간(dev-time) 세션에서 사용하는 것과 동일한 AGENTS.md 파일들을 읽기를 원치 않을 것입니다. 대신 에이전트가 리뷰 체크리스트에 집중하고 회의적인 시각을 유지하며, "새 엔드포인트(endpoint)를 추가하는 방법" 문서가 아닌 리뷰 항목을 지적하기를 원할 것입니다.
따라서 기본 태그와 함께 ci-code-review 태그를 배포합니다:
mappings:
".":
context_source: ./agents/root/AGENTS.md
...
그런 다음 CI 작업은 에이전트를 호출하기 전에 교체(swap)를 수행합니다:
캐시가 활성화(hot)되도록 락(lock)을 복구합니다
npx agent-contexts install
...
동일한 프로젝트, 동일한 락(lock), 하지만 타겟마다 완전히 다른 AGENTS.md 콘텐츠를 가집니다. 개발자는 CI 버전을 볼 일이 없고, CI는 개발자 버전을 볼 일이 없습니다. 둘 다 동일한 저장소(repo)에 존재하며, 둘 다 버전 관리(versioned)가 되고, 어느 쪽을 대상으로 하든 PR(Pull Request)은 일반적인 git 워크플로우와 동일합니다.
명령어 치트 시트 (Commands cheat sheet)
| 명령어 | 기능 |
|---|---|
agent-contexts add <source> | 가져오기(Fetch), 매핑 선택, 연결(link), 락(lock) 작성. |
| ... |
모든 명령어는 --json, -y, --dry-run, --verbose 옵션을 지원합니다. 어떤 명령어도 TTY가 필요하지 않으므로, 문제없이 CI에 통합됩니다.
전체 문서와 소스 코드는 다음에서 확인할 수 있습니다:
github.com/gadz82/contexts.
장점, 단점, 그리고 솔직한 면책 조항
장점 (Pros)
- 결정론적 (Deterministic). 동일한
contexts.lock, 동일한 파일이 노트북, CI, 동료의 컴퓨터 등 어디에서나 동일하게 작동합니다. - 버전 관리 (Versioned). SHA에 고정(Pin)할 수 있습니다. 락(lock) 파일의 한 줄을 변경함으로써 롤백(Roll back)할 수 있습니다.
- 조합 가능 (Composable). 태그(Tags)를 사용하면 프로젝트당 N개의 포크(fork)가 아닌, 하나의 컨텍스트 저장소만 배포하면 됩니다.
- 친숙함 (Familiar).
npm,cargo, 또는pip를 사용해 본 사람이라면 누구나 바로 이해할 수 있습니다. - 이식성 (Portable). 심볼릭 링크(Symlinks)가 상대 경로로 설정되어 있어, 프로젝트를 이동하거나 다시 클론(re-clone)한 후에도 계속 작동합니다.
- 도구 간 호환성 (Cross-tool).
AGENTS.md,CLAUDE.md,GEMINI.md등 이번 주의 에이전트가 무엇을 원하든 대응 가능합니다. - 스크립트 작성 가능 (Scriptable). 모든 곳에서
--json을 지원하고, 결정론적인 종료 코드(exit codes)를 제공하며, TTY가 필요하지 않습니다. 예를 들어, 리뷰어 에이전트를 실행하기 전에ci-cr태그로 교체하는 CI 작업에 연결해 두고 자리를 비울 수 있습니다.
단점 (Cons) (공정하게 말하자면)
- 로컬 경로 소스(Local-path sources)는 락(lock) 파일에 절대 경로를 저장합니다. 해당 락 파일을 커밋하여 다른 머신으로 전송하면
install시 가져올 수 있는 것을 찾지 못하게 됩니다. 그 이유는 문서에 나와 있습니다 (요약하자면: git URL만이 어디서나 동일한 문자열입니다). 공유/CI 환경에서는 git을 사용하고, 로컬은 개인 실험용으로 사용하세요. - 개발자 모드(Developer Mode)가 설정되지 않은 Windows에서는 파일 복사 방식으로 대체됩니다. 여전히 작동은 하지만, 업데이트 시 다시 실행해야 합니다.
- 스키마(Schema)는 독자적인 방식(opinionated)을 따릅니다 — POSIX 경로,
..이스케이프 불가, 소문자 16진수 해시 등과 같은 규칙들입니다. 명세(spec)를 한 번 읽고 나면 더 이상 씨름할 일이 없을 것입니다. - 이것은 v0.x 버전입니다. 락 파일(lockfile) 형식이 하위 호환성을 깨뜨리며 변경되지 않을 것이라고 약속하지는 않습니다.
agent-contexts버전을 고정(Pin)하여 사용하세요.
마무리하며
수많은 리포지토리(repos)에 걸쳐 AGENTS.md 파일을 유지 관리하는 고통을 느껴본 적이 있거나, 혹은 그 파일들이 서로 동기화되지 않고 어긋나는 것을 지켜본 적이 있다면, agent-contexts를 사용해 보세요. README는 짧고, 설치는 명령어 하나로 끝나며, 최악의 경우에도 .contexts/ 폴더와 contexts.lock 파일을 rm으로 삭제하면 그만입니다.
버그를 발견하셨나요? 이슈(issue)를 생성해 주세요. 기능 아이디어가 있나요? PR(Pull Request)을 보내주세요. 이름에 대해 저에게 소리치고 싶으신가요 (이름은 agent-context여야 하고 바이너리는 contexts여야 한다는 거, 저도 압니다, 압니다)? 그것을 위한 이슈 트래커도 준비되어 있습니다.
그리고 Vercel Skills 팀원들에게 진심으로 감사드립니다. 이 모든 것의 형태는 그들의 것이며, AGENTS 형태의 비틀기는 저의 것입니다.
이상입니다. 이제 무언가를 배포(ship)하러 가세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기