답변이 계속 장황하다. CLAUDE.md에 “간결하게”라고 몇 번을 써도 안 바뀐다. 그래서 모델을 바꿔본다. 그래도 비슷하다. 결국 “이 모델은 원래 이런가 보다”로 결론 낸다.

이 흐름 자체가 함정이다. 원인이 프롬프트나 모델이 아니라 그 위에 있는 설정 레이어에 있을 수 있어서다.


실제로 있었던 일

CLAUDE.md에 톤과 분량 지시를 세밀하게 적어뒀는데도 답변마다 불필요한 설명 블록이 계속 붙었다. 프롬프트를 아무리 고쳐도 소용없었다. 원인은 settings.json에 있었다.

{
  "outputStyle": "Explanatory"
}

이 한 줄이 매 응답마다 “교육적 설명을 덧붙여라”고 강제하고 있었다. CLAUDE.md는 시스템 프롬프트 레벨 지시고, outputStyle은 그보다 위에서 하네스가 주입하는 레이어다. 아래 레이어가 아무리 정교해도 위 레이어의 강제 설정을 못 이긴다. 이 한 줄을 지우자 문제가 그 자리에서 끝났다.

모델도 프롬프트도 잘못이 없었다. 스택 어딘가에 원인이 있었을 뿐이다.


AI 협업 도구는 레이어드 아키텍처다

Claude Code 같은 도구를 쓸 때 실제로 답변을 결정하는 힘은 한 곳에서 안 나온다. 대략 이런 순서로 쌓인다.

  1. 모델 자체 — Opus, Sonnet, Fable마다 기본 성향이 다르다
  2. effort 레벨 — 같은 모델도 사고 깊이와 도구 호출 방식이 통째로 바뀐다
  3. outputStyle / 하네스 설정settings.json 같은 곳에서 강제되는 응답 형식
  4. CLAUDE.md — 전역(~/.claude/CLAUDE.md)과 프로젝트별 지시
  5. 그때그때 프롬프트 — 지금 이 순간의 요청

위 레이어가 아래 레이어를 덮어쓴다. 3번에서 형식을 강제하고 있으면 4번, 5번을 아무리 다듬어도 못 이긴다. 반대로 1번 모델이 원인인데 4번 CLAUDE.md만 계속 고치는 것도 같은 실수다. 층을 안 가리고 아래에서만 원인을 찾으니 답이 안 나오는 거다.


진단 순서

이상한 답변을 받았을 때, 아래 순서로 역추적하면 대부분 원인이 나온다.

1. 설정 파일부터 감사한다 settings.json(전역 + 프로젝트)에 최근 건드린 옵션이 있는지 확인한다. outputStyle, 언어 설정, 권한 모드 같은 것들이 여기 있다. CLAUDE.md보다 우선순위가 높다는 걸 기억해야 한다.

2. effort 레벨을 의심한다 같은 모델도 effort에 따라 도구 호출 전에 계획을 설명하는지, 실행 후 요약을 얼마나 자세히 붙이는지가 달라진다. 장황함이 문제면 모델 교체보다 effort를 낮추는 쪽이 먼저다.

3. CLAUDE.md 우선순위 충돌을 확인한다 전역 CLAUDE.md와 프로젝트 CLAUDE.md가 서로 다른 톤을 요구하고 있진 않은지 본다. 두 지시가 충돌하면 어느 쪽이 이기는지 예측하기 어려워진다.

4. 그제서야 프롬프트를 고친다 위 세 가지가 다 정상인데도 안 바뀌면, 그때 프롬프트 표현을 손본다. 순서를 거꾸로 하면 실제 원인은 그대로 둔 채 증상만 프롬프트로 억누르게 된다.


왜 이 순서가 중요한가

프롬프트 레벨에서만 문제를 풀려고 하면, 매번 같은 증상이 재발하고 그때마다 프롬프트를 덧댄다. CLAUDE.md는 점점 “하지 마라” 목록으로 뒤덮이고, 정작 원인이었던 설정 한 줄은 계속 살아있다.

반대로 스택을 이해하고 있으면, 이상 행동 하나를 보고 “이게 어느 층에서 왔는가”를 먼저 묻게 된다. 프롬프트 엔지니어링보다 이쪽이 실제로 더 큰 차이를 만든다. 좋은 프롬프트 한 줄보다, 설정이 서로 충돌하지 않는 깨끗한 스택 하나가 훨씬 오래간다.


effort를 낮추면 답이 부실해진다는 건 반은 틀린 말이다

effort를 낮추면 품질이 통째로 깎인다고 생각하는 사람이 많다. 낮은 effort에서도 진짜 어려운 문제를 만나면 모델은 여전히 생각한다. 다만 high일 때보다 덜 생각할 뿐이다. 이건 능력을 깎는 스위치가 아니라 탐색 예산을 조절하는 다이얼이다.

그래서 나는 작업을 두 종류로 나눠서 본다. 정답이 하나로 정해진 작업 — 리네임, 포맷 통일, 이미 해본 패턴 반복 — 은 low를 줘도 결과가 거의 같다. 여기서 high를 쓰는 건 순수 낭비다. 반면 원인을 모르는 버그를 찾거나 구조를 새로 설계하는 작업은 다르다. 이런 작업은 정답을 찾는 과정 자체가 탐색과 검증이라서, low는 그 탐색을 덜 하고 딱 요청받은 선에서 답을 내고 만다. “능력이 떨어진다”가 아니라 “더 파고들지 않는다”가 정확한 표현이다. 이 구분을 하고 나면 언제 effort를 낮춰도 안전한지가 명확해진다.

매턴 바꾸지 않는다

프롬프트를 보낼 때마다 “이건 쉬우니 low, 이건 어려우니 high”로 스위치를 만지는 건 이 기능을 오해한 사용법이다. adaptive thinking이 effort를 천장으로 두고 턴마다 알아서 얼마나 생각할지 정하기 때문에, 매턴 개입은 애초에 필요가 크지 않다. 이 기능의 설계 의도 자체가 판단을 대신 해주는 쪽이다.

나는 역할과 국면 단위로 나눈다. 서브에이전트한테 파일 찾기나 반복 작업을 맡길 때는 처음부터 low로 박아둔다. 메인 세션은 기본값에 맡겨두고, 막힌 디버깅처럼 정말 필요한 순간에만 잠깐 올렸다가 원복한다. 판단이 애매할 땐 이 다섯 가지로 정리한다.

  • 정답이 하나로 정해져 있나, 접근법을 골라야 하나
  • 답을 찾기 전에 코드를 먼저 뒤져야 하나
  • 틀리면 바로 티가 나나, 조용히 넘어갈 수 있나
  • 이미 해본 패턴인가, 처음 다뤄보는 구조인가
  • 잘못됐을 때 되돌리기 쉬운가

애매하면 일단 높게 시작한다. 낮췄다가 틀리는 것보다 재작업 비용이 항상 크다.