싼 모델로 비싼 모델급 결과를 내는 하네스 구조
AI로 코딩을 하다 보면 이런 순간이 옵니다. 분명 아까 말한 규칙인데 또 어기고, 테스트도 안 돌려놓고 “완료했습니다”라고 하고, 설계부터 하자고 했는데 바로 코드를 쏟아냅니다. 저는 한동안 그럴 때마다 프롬프트를 고쳤습니다. “반드시”, “절대”, “꼭” 같은 단어를 늘려가면서요.
지금은 그걸 안 합니다. 모델에게 더 잘하라고 말하는 대신, 못 어기는 레일을 깔았습니다. 이 글은 그 레일을 어떻게 깔았는지에 대한 기록입니다.
결론부터
- AI의 실수는 대부분 모델이 부족해서가 아니라 구조가 없어서 생깁니다.
- 프롬프트를 강하게 쓰는 건 확률을 높이는 일입니다. 훅으로 막는 건 결정적으로 차단하는 일입니다.
- 상위 모델이 “알아서 하는 것”을 바깥으로 꺼내면, 싼 모델로도 비슷한 수준의 결과가 나옵니다.
- 가장 효과가 컸던 건 생성과 검토를 다른 에이전트로 분리하는 것이었습니다.
왜 구조로 해결되는가
비싼 모델과 싼 모델의 차이를 뜯어보면 실은 네 가지로 좁혀집니다. 그리고 네 개 전부 바깥에서 대신해줄 수 있는 것이었습니다.
| 상위 모델이 알아서 하는 것 | 싼 모델의 실패 양상 | 바깥에서 대신할 장치 |
|---|---|---|
| 스스로 의심하고 다시 본다 | 한 번 만들고 “완료” 선언 | 검토자를 따로 둔다 |
| 앞에서 말한 규칙을 계속 기억한다 | 긴 세션에서 규칙을 잊는다 | 규칙을 작업 지점 근처에 놓는다 |
| 설계하고 나서 구현한다 | 바로 코드부터 쓴다 | 문서 없으면 못 넘어가는 문을 만든다 |
| 모르면 모른다고 한다 | 안 한 걸 한 것처럼 보고한다 | 기계가 검사하게 한다 |
핵심 전환은 한 문장입니다. “모델을 믿는다”에서 “구조를 믿는다”로. 지능을 프롬프트에 욱여넣으려 하지 말고, 판단이 필요 없는 길을 깔아두는 겁니다.
1층 — 규칙을 잊지 못하게 한다
많은 분들이 프로젝트 규칙 파일(CLAUDE.md 같은 것)에 규칙을 계속 추가합니다. 저도 그랬습니다. 300줄, 400줄까지 갔습니다.
결과는 반대였습니다. 길어질수록 안 지켜집니다. 특히 싼 모델일수록 심합니다. 항상 읽히는 문서가 길면, 읽되 무시합니다.
지금은 사다리를 만들어 둡니다.
- 헌법 (200줄 미만) — 항상 읽힘. 정말 중요한 것만
- 규칙 파일 — 해당 영역을 작업할 때만 읽힘
- 절차 문서 — 그 작업을 호출할 때만 읽힘
- 서브에이전트 — 완전히 격리된 채로 읽힘
규칙을 지우는 게 아니라 필요한 순간에만 나타나게 배치하는 겁니다. 폴더가 커지면 그 폴더 안에 규칙 파일을 따로 두는 것도 같은 원리입니다. 규칙이 작업 지점 가까이 있을수록 지켜집니다.
2층 — 부탁하지 말고 막는다
이게 가장 빨리 체감되는 층입니다. 지침은 어기면 그만이지만, 훅은 못 어깁니다.
예를 들어 “.env 파일은 절대 건드리지 마세요”라고 아무리 써놔도 언젠가는 건드립니다. 확률의 문제니까요. 그래서 설정으로 아예 막습니다.
{
"permissions": {
"deny": [
"Read(./.env)",
"Edit(./.env)",
"Write(./.env)",
"Edit(./docs/archive/**)"
]
}
}
한 걸음 더 나가면, 파일을 수정하기 전에 검사해서 차단하는 스크립트를 붙일 수 있습니다. 제가 실제로 쓰는 것의 핵심 부분입니다.
$protected = @(
'\.env', # 시크릿
'docs[\\/]archive[\\/]', # 완료된 기록 (수정 불가)
'docs[\\/]SESSION-.*\.md$' # 세션 로그는 추가만 허용
)
foreach ($pattern in $protected) {
if ($path -match $pattern) {
[Console]::Error.WriteLine("BLOCKED: 보호된 경로입니다.")
exit 2 # 2로 끝내면 차단되고, 그 이유가 AI에게 전달된다
}
}
중요한 건 코드 자체가 아니라 판단을 없앴다는 점입니다. 여기서는 모델이 똑똑하든 말든 결과가 같습니다. 그게 목적입니다.
3층 — 만든 사람이 채점하지 않게 한다
다섯 층 중에 효과가 가장 컸던 게 이겁니다.
같은 대화창에서 “방금 네가 쓴 코드 검토해봐”라고 하면 거의 항상 괜찮다고 합니다. 자기 결과물에는 관대해지거든요. 사람도 똑같습니다.
그래서 검토를 별도 서브에이전트로 분리했습니다. 그랬더니 재미있는 일이 생겼습니다.
- 코드를 쓰는 건 싼 모델이 해도 됩니다
- 대신 검토하는 쪽만 좋은 모델로 돌립니다
- 최종 품질은 검토하는 쪽이 결정합니다
게다가 검토는 생성보다 쌉니다. 읽고 판정만 하면 되니까요. 약한 생성자 + 강한 검토자가, 강한 생성자 하나보다 결과는 좋으면서 돈은 덜 듭니다.
대신 규칙을 하나 걸어뒀습니다. 검토자가 세 번 연속 반려하면 멈추고 저를 부릅니다. 세 번 고쳐서 안 되는 건 코드 문제가 아니라 설계가 잘못된 거라서요.
4층 — 기계가 할 수 있으면 기계에게
문법 검사, 타입 체크, 빌드, 테스트. 이건 모델이 똑똑하든 말든 같은 답이 나옵니다.
그래서 원칙이 하나 생겼습니다. AI 판단을 기계 검사로 바꿀 수 있으면 무조건 바꾼다. 이게 품질의 바닥을 만들어 줍니다. 아무리 못해도 이 밑으로는 안 내려갑니다.
실무적으로는 프로젝트 규칙 파일에 실행할 명령어를 그대로 적어두는 것만으로 충분했습니다. 그러면 AI가 스스로 돌립니다. “검증해”라고 말할 필요도 없어집니다.
5층 — 대화가 끊겨도 이어지게
바이브코딩을 하다 보면 대화창이 길어져서 앞의 내용이 날아갑니다. 새 창을 열면 처음부터 다시 설명해야 하고요.
해결은 단순했습니다. 얇은 상태 문서를 하나 두고, 매 세션 시작할 때 그것만 읽게 하는 것.
- 진입점 문서 — 지금 어디까지 왔는지 (매번 갱신)
- 세션 로그 — 추가만 하고 수정은 안 함
- 에이전트별 기억 — 같은 함정에 또 빠지면 여기에 적어둠
이 구조로 한 프로젝트를 세션 61회 동안 이어서 운영했습니다. 매번 처음부터 설명한 게 아니라, 문서 하나를 읽히는 걸로 시작했습니다.
제가 오래 붙잡고 있던 착각
“더 좋은 모델을 쓰면 해결된다.”
결과가 안 나오면 모델을 올렸습니다. 그래도 안 되면 프롬프트에 강조 표현을 늘렸습니다. 돈은 더 나가는데 같은 실수는 계속 났습니다.
지금 보면 병목이 아닌 곳을 계속 손보고 있었습니다. 모델이 규칙을 어기는 건 멍청해서가 아니라, 그 규칙이 그 순간 눈앞에 없었기 때문이었거든요. 그건 모델을 바꿔도 안 고쳐집니다.
하면 안 되는 것
- 규칙 파일에 규칙 무한 추가 — 200줄 넘어가면 없는 것과 같습니다
- 좋은 모델에 단계별 지시를 잔뜩 — 과잉 지시는 오히려 성능을 깎습니다. 목표와 제약, 검증 기준만 주는 쪽이 낫습니다
- 같은 창에서 만들고 같은 창에서 채점 — 무조건 통과합니다
- “더 잘해줘”라는 프롬프트 보강 — 구조가 아니면 안 고쳐집니다
- 안 쓰는 규칙 방치 — 주기적으로 지워야 남은 규칙이 지켜집니다
오늘 당장 할 수 있는 것
다섯 층을 다 만들 필요는 없습니다. 효과 대비 품이 적은 순서로 적어둡니다.
- 규칙 파일을 200줄 아래로 줄인다 — 지우는 게 아니라 다른 파일로 내린다 (10분)
- .env 같은 건 설정에서 막는다 — 부탁이 아니라 차단으로 (5분)
- 검증 명령어를 규칙 파일에 적어둔다 — 빌드·테스트 명령 그대로 (5분)
- 진입점 문서를 하나 만든다 — “지금 어디까지 왔는지” 한 장 (20분)
- 검토를 별도 에이전트로 분리한다 — 효과가 가장 크지만 손이 제일 많이 갑니다
1번부터 3번까지만 해도 체감이 옵니다. 저는 5번을 제일 늦게 했는데, 지금 돌아보면 제일 먼저 했어야 했습니다.
구조는 계속 자랍니다
한 번 만들고 끝나는 게 아니라, 작업하다 뭔가 발견될 때마다 한 칸씩 승격시킵니다.
- 같은 실수가 반복된다 → 규칙 한 줄 추가
- 같은 절차를 두 번 이상 했다 → 절차 문서로
- 절대 어기면 안 되는 게 생겼다 → 훅으로 승격 (부탁 → 강제)
- 에이전트가 같은 함정에 또 빠졌다 → 그 에이전트 기억에 기록
그리고 가끔, 개별 프로젝트에서 검증된 것들을 템플릿 쪽으로 거꾸로 올립니다. 그러면 다음에 시작하는 프로젝트가 그걸 처음부터 갖고 시작합니다. 제가 프로젝트를 25개쯤 만들면서 유일하게 계속 쌓인 게 이 부분이었습니다.
서비스는 만들다 접기도 하고 안 되기도 했는데, 구조는 접어도 남았습니다. 다음 프로젝트로 그대로 들고 갈 수 있으니까요.
정리
AI에게 “더 잘해줘”라고 말하는 건 사실 운에 맡기는 것과 크게 다르지 않았습니다. 될 때도 있고 안 될 때도 있으니까요.
지금은 이렇게 생각합니다. 모델이 잊어도 시스템이 기억하게 만들어두면, 모델이 뭐가 됐든 결과가 유지됩니다. 모델은 계속 바뀌고 더 좋아지겠지만, 그때마다 제 작업 방식을 처음부터 다시 짤 수는 없으니까요.
혹시 지금 프롬프트를 계속 고치고 계신다면, 그 시간에 규칙 파일을 반으로 줄여보시는 걸 권합니다. 저는 그게 시작이었습니다.
이 글에서 소개한 구조는 2026년 9월 17일 기준 제가 실제로 운영 중인 설정이며, 인용한 코드는 그중 일부를 그대로 옮긴 것입니다.
