Guardsman SKILL; 게으름에서 충성심으로: 내 AI 에이전트에게 승진이 필요했던 이유
요약
AI 에이전트의 과잉 엔지니어링을 방지하는 Ponytail과 코드의 안전성을 확보하는 Guardsman을 비교 분석합니다. 최소한의 코드를 작성하는 효율성과 예외 상황을 고려하는 안정성 사이의 균형이 중요함을 강조합니다.
핵심 포인트
- Ponytail은 코드 양을 줄여 비용과 속도를 개선하지만 안전성을 놓칠 수 있음
- Guardsman은 에이전트가 실패 경로와 예외 케이스를 고려하도록 유도함
- 효율적인 코드 작성과 견고한 로직 구현 사이의 트레이드오프 이해 필요
Ponytail은 내 에이전트를 게으르게 만들었습니다. Guardsman은 에이전트를 충성스럽게 만들었습니다. 그 차이는 모든 것을 결정합니다.
내가 Ponytail을 만난 날
6월의 어느 화요일이었습니다. 저는 Claude Code와 함께 FastAPI 프로젝트로 페어 프로그래밍(pair-programming)을 하고 있었는데, 실수로 데이트 피커(date picker)를 요청했습니다.
그 결과로 돌아온 것은 과잉 엔지니어링(over-engineering)의 정수였습니다: npm을 통해 설치된 flatpickr, React 래퍼 컴포넌트(wrapper component), CSS 임포트(import), 그리고 제가 묻지도 않은 시간대(timezone) 예외 케이스에 대한 세 단락 분량의 에세이까지 말이죠. 그것들을 모두 삭제할 때쯤, 저는 20분을 허비했고 AI 보조 코딩(AI-assisted coding)에 대한 신뢰도 꽤 많이 잃었습니다.
그때 한 동료가 저에게 Ponytail 링크를 DM으로 보내주었습니다.
README는 포니테일을 하고 타원형 안경을 쓴 남자의 그림으로 시작합니다. 슬로건은 다음과 같습니다: "당신의 AI 에이전트를 방 안에서 가장 게으른 시니어 개발자처럼 생각하게 만듭니다." 어떤 유형인지 아실 겁니다. 버전 관리 시스템(version control)보다 더 오래 이 회사에 있었던 그런 사람 말이죠. 당신이 50줄의 코드를 보여주면, 그는 그것을 쳐다보고는 아무 말 없이 단 한 줄로 바꿔버립니다.
저는 그것을 설치했습니다. 그리고 똑같은 데이트 피커를 요청했습니다.
<!-- ponytail: 브라우저에 이미 기능이 있음 -->
<input type="date">
그게 전부였습니다. 의존성(dependencies)도 없고, 래퍼(wrappers)도 없으며, 선언문(manifesto)도 없었습니다. 그저 HTML5 시절부터 그 자리에 있었던 플랫폼 기능일 뿐이었습니다.
저는 완전히 매료되었습니다. 벤치마크(benchmarks) 결과도 이를 뒷받침했습니다: 코드 약 54% 감소, 비용 약 20% 절감, 속도 약 27% 향상. 저는 팀원들에게 이 사실을 알렸습니다. 모든 리포지토리(repo)에 적용했습니다. 약 3주 동안, 저는 제가 성배(holy grail)를 찾았다고 생각했습니다.
환불 웹훅(Refund Webhook) 사건
문제는 조용히 나타났습니다.
저는 에이전트에게 환불 웹훅(refund webhooks)을 처리하기 위한 작은 유틸리티를 추가해달라고 요청했습니다. 파이썬(Python) 5줄. 우아했습니다. Ponytail이 승인할 만한 수준이었죠. 첫 번째 시도에 컴파일(compile)되었습니다. 데모도 깔끔했습니다. 저는 그것을 머지(merge)했습니다.
3일 후, 그 5줄의 코드에서 발생한 레이스 컨디션(race condition)으로 인해 고객에게 요금이 이중으로 청구되었습니다.
문제는 이렇습니다. 코드는 작았습니다. 해피 패스(happy path)를 처리한다는 관점에서는 정확했습니다. 하지만 동시에 위험했습니다. 돈을 다루고 있었고, 비동기 컨텍스트(async context)에서 실행되었으며, 실패 경로(failure-path)에 대한 커버리지가 전혀 없었습니다. Ponytail의 사다리는 에이전트가 최소한의 코드를 작성하도록 안내했습니다. 하지만 그 최소한이 _안전한지_를 묻도록 안내하지는 않았습니다.
저는 주말 내내 사후 분석(post-mortem) 문서를 작성하고 로직을 수정하며 시간을 보냈습니다. 그리고 궁금해지기 시작했습니다. 만약 "적게 쓰는 것"이 전부가 아니라면 어떻게 될까?
문 앞의 파수꾼
그때 Guardsman을 발견했습니다.
README의 시작부터 다릅니다. 포니테일도, 안경도 없습니다. 그저 곰 가죽을 쓴 파수꾼이 부츠를 단단히 고정하고 정면을 응시하고 있을 뿐입니다. 슬로건은 이렇습니다. "어떤 diff도 도전 없이 배포되지 않는다(No diff ships unchallenged)."
철학이 즉각적으로 와닿았습니다. Ponytail은 _"이걸 더 작게 만들 수 있을까?"_라고 묻습니다. Guardsman은 _"이게 틀리면 어떻게 되지?"_라고 묻습니다.
Ponytail이 당신의 추상화(abstraction)를 삭제해 버리는 게으른 시니어 개발자를 투영한다면, Guardsman은 코드베이스에 접근하는 것이 무엇이든—친구든 낯선 이든, 다섯 줄이든 오백 줄이든—도전하고 그것이 그곳에 속해 있다는 증거를 요구하는 근위병을 배치합니다.
저는 그것을 설치했습니다. 그리고 똑같은 환불 웹훅(webhook) 유틸리티를 요청했습니다.
에이전트가 잠시 멈췄습니다. 컨벤션 탐지(convention detection) 스크립트를 실행했습니다. 우리가 이미 웹훅을 어떻게 처리하고 있는지 코드베이스를 grep으로 검색했습니다. 그리고 해당 변경 사항에 위험 등급(risk tier)을 할당했습니다. 그러고 나서 다섯 줄 대신 여섯 줄을 작성했습니다. 그리고 동일한 턴 내에서 실행되어 결과가 표시되는, 실패 경로를 테스트하는 실행 가능한 체크(runnable check)를 포함했습니다.
[code]
→ skipped: async retry loop, add when volume > 100/min.
verified: failure-path test run, output below. tier: sensitive.
긴 설명도, 기능 투어도 없었습니다. 그저 코드, 그리고 책임감을 보여주는 세 줄의 결과가 있을 뿐이었습니다.
Guardsman이 Ponytail과 다르게 수행하는 세 가지
1. 먼저 상시 명령(Standing Orders)을 읽습니다
무엇인가를 작성하기 전에, Guardsman은 결정론적(deterministic) 스크립트를 실행하여 당신의 리포지토리(repo)의 실제 컨벤션을 탐지합니다. 언어 버전, 포맷터(Formatter), 린터(Linter), 실제 테스트 명령, 명명 규칙(Naming style), 에러 처리 패턴 등을 확인합니다.
그다음, Guardsman은 당신의 코드베이스가 이미 가장 유사한 문제를 어떻게 해결하고 있는지 grep(검색)합니다.
이는 들리는 것보다 훨씬 더 중요합니다. 우리 팀은 Prettier가 아닌 Biome을 사용합니다. pytest가 아닌 unittest를 사용합니다. Ponytail의 정적 규칙(Static rules)은 이를 전혀 알지 못했습니다. Guardsman의 상시 명령(Standing orders)은 에이전트가 자신의 기본값(Defaults)을 강요하는 대신, 마침내 해당 조직의 스타일(House style)을 존중하게 된다는 것을 의미합니다.
2. 코드 라인 수가 아닌 폭발 반경(Blast Radius)으로 위험도를 측정합니다
Guardsman의 핵심 통찰은 단순하고도 냉혹합니다. 결제 경로(Payment path)에 대한 5줄의 변경은, 한 번 실행되는 400줄짜리 내부 스크립트보다 더 위험합니다.
코드의 크기가 위험이 아닙니다. 폭발 반경(Blast radius)이 위험입니다.
따라서 단 한 줄의 코드가 작성되기 전에 모든 변경 사항은 티어(Tier)를 할당받습니다:
- Trivial (사소함) — 내부적인 일회성 작업, 다운스트림(Downstream) 영향 없음. 한 번의 수동 실행 및 결과 출력.
- Standard (표준) — 일상적인 기능 작업. 이번 턴에 작성 및 실행되는 하나의 실행 가능한 체크(Runnable check).
- Sensitive (민감함) — 폭발 반경 내에 돈, 인증(Auth), 또는 사용자 데이터가 포함됨. 실패 경로(Failure path)를 검증하는 실제 테스트와 커버리지(Coverage) 노트 포함.
- Critical (치명적) — 잘못될 경우 장애(Incident)로 이어짐. 전체 커버리지 확보, 또는 테스트 하네스(Harness)의 부재를 차단 요소(Blocker)로 노출.
두 가지 규칙이 이 티어 시스템의 정직함을 유지합니다. 신호가 서로 충돌할 경우, 더 높은 티어가 우선합니다. 그리고 에이전트는 코드가 단순해 보인다는 이유만으로 스스로 티어를 낮추는 추론을 절대 하지 않습니다. 자신감 있게 걷는다고 해서 그것이 암호(Countersign)는 아닙니다.
그 두 번째 규칙이 제 환불 웹훅(Refund webhook)을 살릴 수 있었던 규칙입니다. 돈을 건드리는 5줄의 코드? 그것은 최소한 Sensitive 티어입니다. 예외는 없습니다.
3. Diff가 전송되기 전에 검증이 실행됩니다
Ponytail에서 검증은 제안 사항에 불과했습니다. "사소하지 않은 로직은 하나의 실행 가능한 체크를 남긴다." 하지만 강제성은 없었습니다. 이번 턴에 실행해야 한다는 요구 사항도, 티어에 따른 확장성도 없었습니다.
Guardsman에서 검증은 게이트(Gate)입니다. 코드는 작성되었다고 해서 끝난 것이 아닙니다. 코드가 과제에 답했을 때, 즉 이번 턴에 에이전트에 의해 체크가 실제로 _실행_되고 그 결과가 표시되었을 때 비로소 완료됩니다. 미래의 당신에게 숙제로 남겨두는 것이 아닙니다.
출력 포맷은 이러한 규율을 강제합니다:
[code]
→ skipped: <X>, add when <Y>. verified: <how>. tier: <T>.
최대 3줄. 디자인 회고 금지. "내가 고려한 사항은 다음과 같다"와 같은 표현 금지. 오직 사실만 기술할 것.
빌드 오더(Build Orders) 비교
두 도구 모두 사다리(ladder) 구조를 사용합니다. 하지만 그 사다리는 서로 다른 성격을 가지고 있습니다.
Ponytail의 사다리는 순수한 미니멀리즘을 지향합니다:
1. 이것이 존재할 필요가 있는가? → YAGNI
2. 이미 이 코드베이스에 있는가? → 재사용(Reuse it)
3. 표준 라이브러리(Stdlib)가 수행하는가? → 사용(Use it)
...
Guardsman의 사다리는 책임감(accountability)을 추가합니다:
1. 이것이 존재할 필요가 있는가? → YAGNI
2. 이미 이 코드베이스에 있는가? → 재사용(Reuse it)
3. 표준 라이브러리(Stdlib)가 수행하는가? → 사용(Use it)
...
5단계(rung 5)를 주목하십시오. Guardsman은 단순히 유지보수 비용뿐만 아니라, 미래의 모든 독자—인간이든 에이전트든—를 위한 *온보딩 토큰 비용(onboarding-token cost)*을 고려합니다. 그리고 7단계는 솔루션을 리스크 계층(risk tier)에 맞춰 확장합니다. 최소한의 코드, 맞습니다. 하지만 최소한의 안전한(safe) 코드입니다.
SKILL.md 파일이 드러내는 것
아키텍처의 차이를 이해하고 싶다면, 요약된 규칙들을 읽어보십시오.
Ponytail의 성격:
당신은 게으른 시니어 개발자입니다. 게으름이란 효율적임을 의미하며, 부주의함을 의미하지 않습니다.
규칙:
...
Guardsman의 프로토콜(protocol):
## 엔지니어링 규칙 (Guardsman)
### 1. 구축하기 전에 읽을 것
...
Ponytail은 당신에게 성격(personality)을 부여합니다. Guardsman은 당신에게 *프로토콜(protocol)*을 부여합니다. 하나는 분위기(vibe)이고, 다른 하나는 계약(contract)입니다.
로그북(Logbook): "나중에"가 "지금"이 되는 곳
Guardsman은 GUARDSMAN-LOGBOOK.md라고 불리는 지속적인 로그를 함께 제공합니다. 모든 지름길, 모든 유예된 최적화, 모든 계층 결정은 # guardsman: 마커와 함께 기록됩니다.
Ponytail도 유사한 기능이 있습니다. /ponytail-debt는 ponytail: 주석을 수집하여 장부(ledger)로 만듭니다. 하지만 Guardsman의 로그북은 구조화되어 있습니다. 심각도, 비용 영향, 그리고 해당 지름길을 언제 다시 검토해야 하는지에 대한 조건을 추적합니다.
# GUARDSMAN-LOGBOOK.md
## 2026-07-15
...
기록되는 순간, "나중에"는 "결코 안 함"이 되지 않습니다.
내가 전환한 이유
나는 Ponytail을 삭제하지 않았습니다. 단지 강등시켰을 뿐입니다.
Ponytail은 여전히 나의 프로토타이핑 저장소(repos), 일회성 스크립트, 그리고 그린필드 실험(greenfield experiments)에서 실행되고 있습니다. 과도한 엔지니어링(over-engineering)을 방지하는 데 있어 진정으로 탁월합니다. 데이트 피커(date picker) 예시는 언제 봐도 만족스럽습니다.
하지만 내가 메인(main) 브랜치로 머지(merge)할 때—즉, 변경 사항(diff)이 돈, 인증(auth), 또는 사용자 데이터에 영향을 미칠 때—는 Guardsman이 배치됩니다. 왜냐하면 나는 정확성(correctness)과 크기(size)는 독립 변수라는 것을 배웠기 때문입니다. 운영 환경(production)을 망가뜨리는 최소한의 변경 사항은, 작동은 하지만 장황한 변경 사항보다 더 나쁩니다.
위험 등급(risk tier) 시스템은 AI 보조 코딩(AI-assisted coding)에 대한 나의 생각을 바꾸어 놓았습니다. 나는 더 이상 삭제된 코드 줄 수로 성공을 측정하지 않습니다. 대신 머지 시점의 확신(confidence)으로 측정합니다. 유틸리티 스크립트는 빠르게 실행됩니다. 결제 핸들러(payment handler)는 실패 경로 테스트(failure-path test)를 거칩니다. 단순히 "컴파일되었다"는 사실만으로는 아무것도 배포(ship)하지 않습니다.
그리고 상시 명령(standing orders) 감지는 마침내 디자인 시스템(design-system) 문제를 해결했습니다. 나의 에이전트는 우리가 unittest를 사용할 때 pytest를 제안하지 않습니다. 우리가 Biome을 사용할 때 Prettier를 제안하지도 않습니다. 먼저 저장소를 읽고, 그 다음에 작성합니다.
마치며
만약 당신의 가장 큰 고충이 2014년에 브라우저에 이미 포함되었던 기능을 수행하기 위해 npm 패키지를 설치하는 AI 에이전트라면, Ponytail부터 시작하십시오. 그것은 당신의 토큰(tokens), 시간, 그리고 정신 건강을 아껴줄 것입니다. "게으른 시니어 개발자(lazy senior dev)"라는 전형은 실재하며, Ponytail은 이를 완벽하게 포착해 냈습니다.
하지만 당신이 운영 코드(production code)를 배포하고 있다면—즉, 당신의 변경 사항이 실수를 저질렀을 때 장애(incident)로 이어질 수 있는 경로를 지나간다면—단순히 최소한의 것 그 이상이 필요합니다. 당신에게는 **책임감(accountable)**이 필요합니다.
Guardsman은 Ponytail의 어깨 위에 서 있습니다. 그것은 YAGNI(You Ain't Gonna Need It) 반사 신경, 표준 라이브러리 우선(stdlib-first) 본능, 그리고 한 줄 선호(one-line preference)를 유지합니다. 그러고 나서 누락된 조각을 추가합니다. 바로 코드의 크기가 아니라 위험도에 따라 확장되는 검증 시스템(verification system)입니다.
속도를 위해서는 Ponytail을 사용하십시오. 신뢰를 위해서는 Guardsman을 사용하십시오.
왜냐하면 최고의 코드란 단순히 당신이 작성하지 않은 코드가 아니기 때문입니다.
그 코드가 그 자리에 있어야 함을 증명하는 코드입니다.
Guardsman: github.com/hedimanai-pro/guardsman
Ponytail: github.com/DietrichGebert/ponytail
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기