happy_various AI 실전 기록

LLM 중계기 개발기 4부 · 15편 / 전체 33편

2026년 10월 1일 기준

이 글에는 제휴 링크가 없고 어떤 AI 서비스와도 관계가 없습니다. 제가 직접 만든 중계기의 개발 기록을 바탕으로 썼습니다. 삽화는 GPT 이미지 생성, 도식은 직접 제작했습니다.

생각만 하다 답을 못 한 AI — 연료를 예열에 다 써 버린 자동차 (LLM 중계기 개발기)

추운 겨울 아침, 시동을 걸고 엔진을 데운다고 해 볼게요. 그런데 예열이 끝나지 않습니다. 계속 데우다 보니 연료 바늘이 바닥까지 내려갔어요. 엔진은 따끈해졌는데 차는 차고 문턱을 한 번도 넘지 못했습니다. 기름은 다 썼는데 달린 거리는 0km예요.

시험장에서도 비슷한 장면을 떠올릴 수 있어요. 시험 시간 내내 연습장에 풀이만 빼곡히 쓰다가, 종이 울리고 보니 답안지는 텅 비어 있는 학생이요. 생각은 누구보다 많이 했는데 점수는 0점이죠.

제가 만든 LLM 중계기에서 실제로 이런 일이 있었습니다. 생각형 AI 하나가 생각만 33,748자를 쓰고, 정작 답은 한 글자도 내놓지 못했어요.

이 글은 LLM 중계기 개발기의 15편이자, 4부 ‘AI가 이상하게 굴 때’의 첫 편입니다. 지난 14편 「‘저는 Claude예요’라고 말한 다른 AI」에서는 서로 다른 프로그램의 대화가 섞여 버린 사고로 3부 ‘교통정리’를 마무리했어요. 4부에서는 AI의 답이 비거나, 잘리거나, 성공처럼 보였는데 실패였던 일들을 하나씩 다룹니다. 첫 이야기는 9편에서 스펙 카드의 ‘생각 여유분’ 줄을 소개하며 미뤄 둔 바로 그 사연이에요.

차고 안에서 엔진만 뜨겁게 달아오른 채 연료 바늘이 바닥에 닿은 작은 자동차 로봇 (GPT 이미지 생성)

결론 요약

🧮 1. 토큰과 답 예산 — AI의 ‘글자 예산’

먼저 낱말 두 개만 짚고 갈게요.

토큰(token)은 AI가 글을 세는 단위예요. 글자 하나가 토큰 하나인 건 아니고, 낱말 조각 단위로 셉니다. 같은 내용이라도 언어에 따라 토큰 수가 달라지는데, 이 이야기는 4부의 마지막 19편에서 따로 할게요. 여기서는 “AI가 쓰는 글의 양을 재는 자” 정도로 보면 충분해요.

답 예산(max_tokens)은 프로그램이 AI에게 질문을 보낼 때 “답은 이만큼까지만 써 줘” 하고 함께 적어 보내는 상한이에요. 3편에서 ‘답 길이 제한’이라고 잠깐 나온 설정 칸입니다. AI는 이 예산에 닿으면 쓰던 걸 멈추고, 끝난 이유 칸에 잘림(length)이라고 적어 보내요. 할 말을 다 해서 멈췄으면 다 했음(stop)이고요.

여기까지는 단순합니다. 문제는 답하기 전에 속으로 먼저 생각하는 생각형 AI예요. 흔히 추론 모델이라고 부르죠. 이런 AI는 생각을 따로 받은 예산으로 하는 게 아니라 답 예산에서 꺼내 씁니다. 시험지로 치면 연습장과 답안지가 한 묶음에 붙어 있는 셈이에요. 연습장에 많이 쓸수록 답안지로 쓸 장이 줄어들어요. 자동차로 치면 예열에 쓰는 연료와 달리는 데 쓰는 연료가 같은 연료통에서 나오는 거고요.

3편에서 이 생각이 답과 따로 생각 칸(reasoning_content)에 담겨 오고, 중계기가 개발 둘째 날부터 그 칸을 그대로 전하면서 생각에 쓴 분량을 기록에 경고로 남겼다고 했어요. 그 경고가 크게 울린 날이 왔습니다.

⛽ 2. 증상 — 생각 33,748자, 답 0자

8월 11일 오전, 문제 기록이 하나 올라왔어요. 중계기를 쓰던 코드 검토 도구가 생각형 AI 하나에게 코드 검토를 맡겼는데, 검토 결과가 텅 빈 채로 돌아온다는 내용이었습니다. 기록의 제목도 AI가 검토하다가 죽는다는 뜻이었어요.

함께 붙어 있던 중계기 기록 한 줄이 모든 걸 말해 줬습니다. 풀어 쓰면 이래요.

  • 답 예산 — 8,192토큰
  • AI가 쓴 분량 — 8,192토큰, 예산을 꽉 채움
  • 생각 — 33,748자, ‘출력 예산 소비’ 경고
  • 끝난 이유 — 잘림(length), ‘출력 잘림’ 경고

답 예산 8,192토큰을 생각이 처음부터 끝까지 다 썼고, 답이 들어갈 자리는 남지 않았어요. 연료를 예열에 다 쓰고 차고를 못 나간 자동차, 연습장만 채우고 답안지를 비운 학생 그대로였죠.

눈여겨볼 점이 하나 더 있었습니다. 이 AI는 생각에 쓴 토큰 수를 따로 알려 주지 않았어요. 기록의 생각 토큰 칸은 0이었고 글자 수만 남아 있었습니다. 생각을 얼마나 했는지 재려면 글자 수로 어림할 수밖에 없다는 뜻이에요. 이 사실은 4절에서 다시 쓰입니다.

산더미 같은 연습장 뒤에서 텅 빈 답안지를 앞에 두고 당황한 학생 로봇 (GPT 이미지 생성)

🔍 3. 원인 — 연료통은 왜 작았고, 예열은 왜 길었나

원인은 두 갈래였어요.

첫째, 연료통이 작았습니다. 8,192토큰은 코드 검토 도구가 고른 값이었는데, 도구가 그렇게 작게 잡은 데는 이유가 있었어요. 9편의 스펙 카드 기억나시죠? 도구는 카드를 보고 예산을 계획하는데, 그때 이 AI의 카드에는 읽을 수 있는 분량 말고는 줄이 거의 없었습니다. 권장 방식도, 생각에 관한 줄도 없었죠. 정보가 없으니 도구는 가장 조심스러운 기본값, 작은 예산으로 물러섰어요. 그날 고친 기록은 이걸 근본 원인으로 적었습니다. 9편에서 “모르면 조심스럽게 움직인다”는 건 옳은 선택이라고 했는데, 생각형 AI 앞에서는 그 조심이 거꾸로 답을 굶긴 셈이에요.

둘째, 예열이 얼마나 길지 미리 알 수 없었어요. 생각을 얼마나 하는지는 AI마다, 질문마다 다릅니다. 짧은 질문엔 금방 답하다가도 긴 코드를 받으면 한참을 생각하죠. “이 모델은 생각에 얼마쯤 쓴다”는 값을 미리 표로 적어 둘 수도 있지만, 표는 표에 없는 모델 앞에서 무력해요. 실제로 이 사고와 그 무렵의 비슷한 사고 모두, 기록에 남은 원인은 ‘표에 없던 모델이나 표보다 큰 양’이었습니다.

그날 고친 순서도 흥미로워요.

정오 무렵의 첫 수정은 최소 예산이었습니다. 이 AI에 오는 요청의 답 예산이 16,384토큰보다 작으면 16,384로 올려서 보내는 거죠. 동시에 이 AI의 카드에 빠져 있던 줄도 채웠어요.

그런데 두 시간쯤 뒤에 이 방식을 바꿨습니다. 최소 예산으로는 두 가지가 풀리지 않았거든요.

시험으로 치면 “답안지 묶음은 최소 세 장”이라고 정하는 것과 “답안지 몫은 그대로 두고 연습장을 따로 더 얹어 준다”는 것의 차이예요. 앞의 방법은 답안지 몫이 정해지지 않고, 뒤의 방법은 생각이 예상한 만큼에서 끝나면 답 몫이 고스란히 남습니다. 중계기는 뒤의 방법으로 갔어요. 예상보다 생각이 길어지는 경우까지 받아 내도록 겹겹이 쌓은 것이 아래의 4겹 방어입니다.

🛡️ 4. 4겹 방어

① 배운다 — 실제로 얼마나 생각하는지 잰다

중계기는 모든 AI의 답이 돌아올 때마다 생각에 쓴 분량을 잽니다. AI가 생각 토큰 수를 알려 주면 그 값을 쓰고, 2절의 AI처럼 알려 주지 않으면 글자 수를 3으로 나눠 토큰으로 어림해요. 일부러 크게 어림하는 쪽입니다. 2절의 사고만 봐도 실제로는 토큰 하나에 4글자 남짓이었으니까요. 여유분을 정하는 데 쓰는 값이라, 모자라게 재는 것보다 넉넉하게 재는 편이 안전합니다.

생각만 하다 잘린 경우는 따로 셈해요. 실제로 필요했던 양이 쓴 양보다 크다는 뜻이니, 쓴 분량의 1.5배를 “적어도 이만큼은 필요했다”로 적어 둡니다.

이렇게 모델마다 지금까지 본 가장 큰 생각 분량(관찰한 최고치)을 기억해요. 미리 적은 표에 없던 모델도 생각하는 모습이 처음 보이는 순간부터 기억이 쌓입니다. 이 기억은 중계기 안에만 있어서 다시 켜면 처음부터 다시 배워요.

② 얹는다 — 답 몫 위에 생각 여유분을 더한다

쓰는 쪽이 정한 답 예산은 답 몫으로 보고, 그 위에 생각 여유분을 더해서 AI에게 보냅니다. 여유분은 둘 중 큰 값이에요.

예를 들어 쓰는 쪽이 답 예산을 8,192토큰으로 정했다면, AI에게는 8,192 + 16,384 = 24,576토큰을 보내요. 그 모델이 감당할 수 있는 최대치는 넘지 않게 자르고요. 연료통은 그대로 두고 예열용 연료를 한 통 더 달아 주는 셈입니다.

이 방어는 사고가 난 그 AI의 길에 달았어요. 다른 AI는 생각하는 모습이 보이면 스펙 카드에 생각 여유분을 적어 두고, 쓰는 쪽이 “원하는 답 분량 + 생각 여유분”으로 직접 계획하도록 설명서에 안내합니다.

로봇 정비공이 자동차 로봇의 연료통은 그대로 둔 채 옆에 예비 연료통을 하나 더 달아 주고 있다 (GPT 이미지 생성)

③ 한 번 더 — 그래도 답이 0자면 예산을 두 배로

여유분을 얹어도 생각이 그보다 길어질 수 있어요. 중계기를 막 다시 켜서 아직 배운 게 없을 때도 있고요. 그래서 끝난 이유가 잘림인데 답이 0자면, 예산을 두 배로(적어도 16,384토큰) 늘려 딱 한 번 다시 보냅니다. 24,576토큰이었다면 49,152토큰으로요. 이 방어도 ②와 같은 길에 달았어요.

여기에는 선을 몇 개 그었어요.

④ 정리한다 — 답에 섞여 온 생각 꼬리표를 떼어 낸다

3편에서 본 것처럼, 어떤 AI는 생각을 생각 칸에 따로 담지 않고 답 본문 맨 앞에 <think> 꼬리표로 감싸 섞어 보내요. 평소에는 생각이 끝나는 자리에 닫는 꼬리표가 붙지만, 생각하다 예산이 끝나면 닫는 꼬리표가 오지 않습니다. 그러면 중계기 눈에는 생각 조각이 답처럼 보여요. 답이 0자가 아니니 ③도 움직이지 않고, 쓰는 쪽은 생각하다 끊긴 문장을 답으로 받게 되죠.

그래서 답의 첫머리가 이 꼬리표로 시작할 때만 그 부분을 떼어 생각 칸으로 옮깁니다. 답 중간에 우연히 나온 같은 글자는 건드리지 않아요. 닫는 꼬리표 없이 끝나면 남은 것도 전부 생각으로 봅니다. 이제 생각하다 잘린 답은 정확히 ‘답 0자’로 보여요. 사고가 난 AI의 길에서는 ③이 제대로 움직이고, 다른 AI를 쓰는 프로그램도 “생각하다 잘렸구나”를 알아볼 수 있습니다. 이 정리는 OpenAI 호환 모양으로 답하는 AI 모두에 적용돼요.

답 예산 막대 — 전에는 생각이 예산을 다 채워 답 0자, 후에는 답 몫 위에 생각 여유분을 얹어 보낸다. 아래에 4겹 방어 (직접 제작)

📋 5. 조용히 고치지 않는다 — 그리고 다음 날

쓰는 쪽이 보낸 값을 중계기가 바꿨다면, 바꿨다는 사실은 남아야 합니다. 그래야 “왜 생각보다 오래 걸렸지?” 같은 의문이 생겼을 때 따라갈 수 있어요. 코드에 남긴 메모에도 “투명하게 남긴다”고 적어 뒀습니다. 그래서 중계기가 손댄 건 모두 보이게 했어요.

이 4겹 방어는 그다음 날 아침 새 버전에 실렸습니다. 그리고 같은 날 오후, 중계기 자기 화면에서도 같은 버릇을 찾았어요. 중계기에는 질문 하나를 여러 AI에 동시에 던져 답을 나란히 보는 채팅 화면이 있는데(6부에서 다룰게요), 이 화면은 답 예산을 4,096토큰으로 고정해 보내고 있었습니다. 생각형 AI가 생각을 길게 하면 답이 잘릴 수밖에 없는 값이죠. 16,384토큰으로 올리고, 잘린 답은 그냥 ‘완료’가 아니라 ‘완료 · 출력 잘림’으로 표시하게 바꿨어요. 잘린 답이 정상 완료인 척하지 않도록요.

이 사고에서 남긴 규칙은 넷입니다.

① 쓰는 쪽이 정한 답 예산은 답 몫으로 지킨다 — 생각 몫은 그 위에 따로 얹어요

② 미리 적은 표보다 실제로 본 값 — 표는 출발점이고, 실제로 본 값이 더 크면 그 값을 따라요

③ 고치면 고쳤다고 알린다 — 예산을 바꾸거나 다시 시도한 사실을 기록·머리글·카드에 남겨요

④ 빈 답이나 잘린 답을 정상인 척 넘기지 않는다 — 잘렸으면 잘렸다고 표시해요

정리

① 생각형 AI는 생각도 답 예산에서 꺼내 써요. 예산이 작으면 생각만 하다 답 0자로 끝날 수 있어요 — 생각 33,748자, 답 0자였던 날처럼요 ② 원인은 정보가 없어 작게 잡힌 예산과, 미리 알 수 없는 생각의 길이였어요. 그래서 실제 생각 분량을 배우고, 답 몫 위에 여유분을 얹고, 그래도 비면 두 배로 한 번 더 보내고, 섞여 온 생각 꼬리표를 떼어 내는 4겹 방어를 넣었어요 ③ 중계기가 예산을 바꾸거나 다시 시도하면 그 사실을 기록·답장 머리글·스펙 카드로 알려요. 잘린 답은 정상 완료인 척하지 않게요

다음 16편은 “‘다 했어요’라더니 잘린 답”이에요. 이번 편에서 ‘잘림’이라는 끝난 이유가 여러 번 나왔죠. 다음 편에서는 반대로, 잘렸는데도 ‘다 했음’이라고 적혀 온 답과 끝난 이유를 어디까지 믿을 수 있는지를 다룹니다.


2026년 10월 1일 기준입니다. 제가 만든 중계기의 개발 기록을 바탕으로 썼고, 특정 기업·서비스의 공식 입장이 아닙니다.