thinking을 껐다

요약 잡 출력 토큰의 85.8%가 thinking이었다. 환경변수 하나로 끄니 출력 −85%, 처리 시간 4.5배, 스키마 10/10, 요약엔 오히려 숫자가 늘었다. 그리고 끄는 코드 한 줄이 세 프로젝트 인증을 동시에 죽일 수 있었던 이유

공유 큐는 세 프로젝트의 LLM 호출을 한 줄로 세워 구독 쿼터를 나눠 쓰게 만든 물건이다. 세우고 나서 공시 50건으로 첫 실측을 돌렸는데 출력 토큰이 예측의 네 배를 넘겼다. effort는 이미 낮춰 둔 상태였고, 그 초과분이 어디서 나오는지부터 갈라야 했다.

하려던 것

공유 큐를 세운 뒤 첫 실측이었다. 공시 요약 서비스의 실제 공시 50건을 큐에 넣고 구독 CLI로 돌렸다. 모델은 Haiku 4.5, effort는 low. 50건 전부 성공했는데 숫자가 이상했다. 출력 평균이 3,705토큰이었다. 에이전트가 예측한 값은 800이었다. 4.6배다.

큐는 건별로 thinking 토큰을 따로 기록하게 만들어 뒀다. CLI의 JSON 출력에 그 필드가 있다. 집계하니 thinking 평균 3,178, 실제 출력 527. 출력의 85.8%가 thinking이었다. effort를 이미 low로 걸어 둔 상태에서 그랬다.

이 실측은 8월 28일이었고 실제로 손댄 건 사흘 뒤다.

어떻게 시켰나

내가 시킨 건 아니다. 28일에 Claude Code 사용량 리포트를 세션에 붙여 넣었더니 에이전트가 “근거 없이 결론을 냈다”며 자기 예측을 정정했고, thinking을 끄는 A/B를 제안했다. 추출 작업이라 품질 위험이 낮고 주간 25%를 아낄 수 있다는 근거였다. 31일에 이어서 하라고 한 세션에서 그 실험이 돌아갔다.

끄는 방법부터 찾아야 했다. --help에는 --effort뿐이고 thinking 전용 플래그가 없다. CLI 바이너리를 strings로 뒤져 환경변수 후보 넷을 찾았다. 단건으로 비교하니 MAX_THINKING_TOKENS=0이 577토큰, CLAUDE_CODE_DISABLE_THINKING=1이 1,015토큰, 현행이 6,697토큰이었다. 셋 다 스키마는 통과했다. 짧은 쪽을 골랐다.

어디서 막혔나

첫 A/B는 실패했다. 세션 사이에 스크래치패드가 정리돼 결과가 사라졌다. 다시 짰다. 50건을 본문 길이순으로 정렬해 1,220자부터 24,016자까지 10건을 고르고, 같은 시스템 프롬프트, 같은 스키마, 같은 모델과 effort로 로컬에서 재실행했다.

현행thinking 0
출력 합계 (10건)39,9845,865 (−85.3%)
스키마 통과10/1010/10
처리 시간 (prod, 건당)37.2초8.2초

처리 시간은 예상 못 한 보너스였다. 4.5배다. 프로덕션에서 같은 10건을 다시 넣으니 48초 만에 전부 끝났다.

품질은 앞 5쌍의 요약 문장을 나란히 놓고 봤다. 어느 시멘트 회사 건은 현행이 “잔금 수령 완료로 예정일자 8월 7일로 정정”이었고 끈 쪽이 “2024년 4월 계약 후 2026년 8월 7일 잔금 수령 완료”였다. 다른 건은 끈 쪽만 주식 수와 지분율을 병기했다. 생각을 덜 했는데 요약이 더 구체적이었다. 정직하게 적자면 이건 정량 지표가 아니라 5쌍 육안 비교이고, 판정한 것도 에이전트다.

어떻게 풀었나

적용은 러너의 한 줄이다. 서브프로세스 환경변수로 MAX_THINKING_TOKENS=0을 무조건 주입한다. 그런데 이 한 줄이 함정이었다.

Go의 exec.Cmd는 Env가 nil이면 부모 환경을 상속하지만, Env에 값을 넣는 순간 그 슬라이스만 자식에게 간다. 환경변수 하나만 넣으면 배포 플랫폼에서 들어온 OAuth 토큰이 자식 claude 프로세스에 도달하지 않는다. 이 큐는 세 프로젝트가 공유하고 인증 수단은 그 토큰 하나뿐이다. 그 경우 세 프로젝트의 AI가 동시에, 조용히 멈춘다.

이번엔 당하지 않았다. 사흘 전 설계 때 “토큰이 만료되면 전 프로젝트가 조용히 멈춘다”를 위험 항목으로 적어 뒀고, 그 인식이 코드까지 이어졌다. 처음부터 append(os.Environ(), ...)로 썼고, 주석과 문서에 “통째로 덮으면 죽는다”를 경고로 남겼다. 배포 직후 프로덕션 10건은 실패 0이었다.

주간 예측은 35.8M에서 27.3M 토큰으로, 일일 처리 시간은 77분에서 18분으로 내려갔다. 쿼터 게이트도 그에 맞춰 조였다. 나중에 잡별로 모델과 effort를 고를 수 있게 열었지만 thinking은 그대로 0이다. 85% 절감이라는 근거가 있는 결정이라 되돌리지 않았다.

배운 점