ponytail 뜯어보기 — LLM 호출 없이 룰셋만 주입해 에이전트를 게으르게 만드는 스킬

MCP·에이전트 만들기 2026-07-23 16:45:30 ponytailmcpclaude code스킬yagni

글 목록 →

AI 코딩 에이전트에게 “캐시 좀 붙여줘”라고 하면, 열에 아홉은 TTL과 만료 정책과 인터페이스를 갖춘 캐시 클래스를 새로 짓는다. 정작 필요한 건 @lru_cache 한 줄이었는데. 이런 과잉엔지니어링을 막겠다고 나온 오픈소스가 ponytail이다. 이름값은 “50줄을 한 줄로 바꾸는, 세상 게으른 시니어 개발자”라는 캐릭터에서 온다.

기능 소개 글은 이미 많으니, 여기서는 조금 다른 각도로 본다. ponytail은 LLM을 단 한 번도 호출하지 않는다. 이게 이 블로그를 만들며 붙잡고 있는 원칙 — “MCP 서버는 모델을 부르지 않는다(무료 원칙)” — 과 정확히 같은 구조라서, 뜯어볼 가치가 있다.

결정 사다리라는 ‘룰’의 정체

ponytail이 하는 일은 단순하다. 에이전트가 코드를 쓰기 직전에 결정 사다리(decision ladder) 라는 체크리스트를 먼저 밟게 한다. 첫 번째로 걸리는 칸에서 멈춘다:

  1. 이게 존재할 필요가 있나? 투기적 필요면 건너뛴다 (YAGNI)
  2. 이 코드베이스에 이미 있나? 있으면 재사용한다
  3. 표준 라이브러리로 되나? 그걸 쓴다
  4. 플랫폼 네이티브 기능으로 되나? (<input type="date"> vs 달력 라이브러리)
  5. 이미 깔린 의존성으로 되나? 새로 추가하지 않는다
  6. 한 줄로 되나? 한 줄로
  7. 그제서야: 동작하는 최소한의 코드

핵심은 이 사다리 전체가 그냥 텍스트라는 것이다. 모델을 추론시켜 만들어낸 게 아니라, 사람이 써 둔 규칙 문서다. ponytail은 이 문서를 매 요청의 컨텍스트에 끼워넣을 뿐이고, 실제로 사다리를 밟는 판단은 원래 있던 에이전트(Claude Code 같은)가 한다. 새 지능을 더하는 게 아니라, 이미 있는 지능의 기본값을 바꾸는 얇은 레이어다.

같은 룰, 세 가지 끼우는 자리

그럼 이 룰셋을 에이전트에게 어떻게 먹이느냐 — ponytail은 세 가지 형태로 같은 텍스트를 배포한다.

  • skill: SKILL.md 한 장. 에이전트가 관련 작업을 인식하거나 사용자가 /ponytail로 부르면 그 순간 룰이 로드된다. 필요할 때만 켜진다.
  • hook: pre_llm_call 같은 훅에 물려, 모델을 부르기 직전 매번 룰을 자동 주입한다. always-on. 사람이 부를 필요가 없는 대신 항상 켜져 있다.
  • MCP 서버: 룰셋을 MCP primitive로 노출해, MCP를 지원하는 아무 호스트에나 붙일 수 있게 한다.

셋은 “무엇을(같은 룰)“이 아니라 “어디에 끼우느냐”만 다르다. 이 분리가 깔끔한 이유는, 룰의 단일 출처를 하나 두고 배포 형태만 갈아끼우면 되기 때문이다. ponytail 코드도 실제로 하나의 룰 생성 함수를 skill·hook·MCP가 공유한다.

MCP는 왜 prompt와 tool 양쪽으로 노출하나

MCP 형태가 특히 재미있다. ponytail-mcp는 같은 룰셋을 prompt와 tool 두 primitive로 동시에 내보낸다. 왜 하나로 안 하고 둘 다일까? MCP의 3대 primitive를 떠올리면 답이 나온다 — 소비 주체가 다르다.

  • prompt ponytail: 사람이 슬래시 명령처럼 골라 부르는 재사용 대화 템플릿이다. lite/full/ultra 모드를 인자로 받아 룰을 사용자 메시지로 꽂아준다. 사람이 능동적으로 켜는 통로.
  • tool ponytail_instructions: 에이전트나 코드가 컨텍스트를 끌어올 때 부르는 통로다. 같은 텍스트에 더해 { mode, instructions } 구조화 데이터까지 돌려줘, 프로그램이 파싱하기 좋다.

같은 내용을 사람이 부르는 문과 기계가 부르는 문, 두 개로 낸 것이다. MCP Prompt로 워크플로를 패키징하던 것과 같은 발상인데, 여기서는 “워크플로” 자리에 “행동 규칙”이 들어갔다. LLM 호출이 없으니 이 서버를 굴리는 비용은 사실상 0이다. 룰 텍스트를 골라 되돌려주는 게 전부다.

그래서 나는 무엇을 붙였나

이 블로그 레포에 실제로 ponytail을 붙일 때, 나는 MCP도 hook도 아닌 skill 한 장만 골랐다. .claude/skills/ponytail/SKILL.md 파일 하나 복사가 끝이었다.

이유는 ponytail 자신의 사다리를 그대로 적용한 결과다. MCP 서버로 붙이면 프로세스를 하나 더 띄워야 하고(사다리 5번: 새 의존성), hook으로 붙이면 매 응답에 강제 주입되는 설정 변경이 필요하다(사다리 1번: 정말 항상 켜져 있어야 하나?). 반면 skill은 파일 한 장이고, 필요할 때 /ponytail로 부르면 된다. “안 만들어도 되는 프로세스는 안 띄운다” — 도구를 붙이는 방식 자체를 그 도구의 철학으로 결정한 셈이다.

ponytail이 알려주는 건 결국 이거다. 에이전트의 행동을 바꾸는 데 꼭 더 똑똑한 모델이나 더 무거운 인프라가 필요한 건 아니다. 잘 쓰인 룰 텍스트 한 장을, 알맞은 자리에 끼워넣는 것으로 충분할 때가 많다. 그리고 그 “끼워넣는 자리”를 표준화한 게 MCP의 prompt와 tool이다.

댓글

이 글에 대한 의견은 아래 댓글로 남겨주세요 (GitHub 계정 필요). 로그인 없이 남기고 싶다면