내 근자감 넘치는 Claude Code 에이전트를 소크라테스한테 탈탈 털리게 해봤다
I let Socrates tear through my overconfident Claude Code agent
핵심 요약
Claude Code 에이전트의 멋대로인 코드 수정을 막기 위해 spec.md를 기준으로 행동을 검수하는 'Gadfly' 도구를 개발함.
- Gadfly 도구 — Claude Code 에이전트의 도구 호출을 실시간으로 검수하는 시스템임.
- 소크라테스 검수 — spec.md를 기준으로 에이전트의 의사결정을 비판적으로 검토함.
- 비용 효율성 — 규칙 기반 필터링으로 불필요한 모델 호출을 최소화함.
- 자동 학습 — 수동 수정 사항을 규칙으로 저장해 반복적인 실수를 방지함.
한동안 Claude Code로 이것저것 만들어봤는데, 제일 짜증 났던 건 버그가 아니었어. 3시간쯤 지나서야 에이전트가 지 맘대로 데이터 모델을 골랐거나 내가 신경 쓰던 부분을 멋대로 바꿔놨다는 걸 알게 되는 거였지. 나중에 diff를 확인해봐야 소용없어. 이미 잘못된 방향으로 1시간 넘게 코드가 쌓여버린 뒤고, 애초에 에이전트가 내리는 진짜 결정들은 diff만 봐서는 결정처럼 보이지도 않거든.
그래서 우리 좋은 친구 소크라테스를 불러서 Gadfly를 만들었어. 이건 Claude Code의 PreToolUse 이벤트에 연결돼서 모든 도구 호출을 실행 전에 검토해. 코드를 읽기만 하고 절대 건드리지는 않는 두 명의 독립적인 검토자가 서로 영향을 받지 않고 감시하는 구조야.
- 소크라테스, 아키텍트 (기본값은 Opus). 이 녀석이 핵심이야. 모든 동작을 spec.md와 대조해서 확인하고, 뭔가 이상하다 싶으면 에이전트한테 직접 물어봐. "이게 진짜 요청받은 거냐?", "방향이 틀어지는 거 아니냐?", "이거 생각보다 큰 결정 아니냐?" 같은 식으로 말이야. 대부분은 이 질문을 받은 에이전트가 알아서 정신 차리고 복구해. 결정이 중요한데 spec에 없는 내용이면, 소크라테스가 딱 멈추고 너한테 직접 결정하라고 물어봐.
- 코드 리뷰어 (기본값은 Sonnet). 그냥 코드 버그만 잡는 놈이야. 잘못된 로직, 예외 처리 안 된 부분, 없는 API 호출 같은 거 찾아내지.
규칙 기반의 1차 필터링을 거치면 읽기, 검색, 안전한 명령어들은 모델 호출 없이 바로 통과돼. 그래서 도구 호출 대부분은 비용이 안 들어 (내 로그 기준 5번 중 4번 정도). 진짜 중요한 것들만 제대로 검토하는 거지.
소크라테스가 얼마나 자주 너한테 물어볼지는 설정할 수 있어 (autonomous, balanced, collaborative). autonomous 모드면 거의 모든 걸 알아서 결정하고 기록해버리고, collaborative 모드면 중요한 결정은 대부분 너한테 물어봐. balanced는 그 중간이고. 어느 쪽이든 되돌릴 수 없는 작업은 무조건 멈추고 너한테 먼저 물어봐. 소크라테스가 내린 모든 결정은 decisions.md에 기록되니까, autonomous 모드라도 파일 열어보면 얘가 왜 그런 결정을 내렸는지 다 볼 수 있어.
Gadfly가 자기 자신을 빌드할 때의 후반부 수치는 이래:
| Outcome | What it does | Count |
|---|---|---|
| Allow | passes silently, the common case | 510 |
| Question | sends the agent a question so it reconsiders, mid-build | 166 |
| Block | stops the action | 39 |
| Ask you | stops and asks you to decide | 6 |
Claude Code의 auto 모드를 써봤다면 비슷하게 들릴 거야. 도구 호출할 때마다 실행 전에 검사하는 거니까. 차이점은 뭘 검사하느냐지. auto 모드는 "이거 위험한가?" 딱 하나만 물어봐서 안전한 단계만 통과시켜주거든. Gadfly도 그건 물어보지만, 코드가 실제로 맞는지도 확인하고 소크라테스가 "이 변경 사항이 네 spec에 맞는 거냐?"라고 묻게도 해.


