추론 모델을 붙이고 나서 청구서를 열어 보면 출력 토큰이 생각보다 몇 배 많은 경우가 흔해요. 화면에 찍힌 답은 몇 줄인데, 모델이 답을 쓰기 전에 낸 사고 토큰이 출력 단가로 따로 청구되기 때문이에요. 결론부터 말하면 분류·추출·짧은 변환은 사고를 끄거나 low 로 두고, 여러 단계를 거치는 코드·계획·분석만 medium~high 로 올리세요. 사고 4,000토큰은 답 400토큰짜리 요청의 비용을 6배, 대기 시간을 11배로 늘려요.
이 글은 사고 토큰이 왜 정답률을 올리는지 같은 내부 원리는 짧게만 다루고, 실제로 켤 때 정해야 하는 것에 집중해요. 어느 방식을 쓸지, effort 를 몇으로 둘지, 한 달에 얼마가 나오고 사용자가 몇 초를 기다리는지를 2026년 10월 28일 기준 공식 가격표와 문서로 직접 계산했어요.
추론 모델 쓰는 방식 네 가지 — 개발자가 고르는 손잡이
같은 "생각하는 모델"이어도 어디서 돌리느냐에 따라 만질 수 있는 설정이 달라요.
| 방식 | 켜고 끄는 법 | 길이 조절 | 비용 구조 |
|---|---|---|---|
| Claude API (4.7 이후 모델) | 적응형 사고(thinking: {type: "adaptive"}) 기본 | output_config.effort low~max | 사고는 출력 단가, 이전 턴 사고는 입력 단가 |
| OpenAI API (추론 모델) | reasoning.effort 값으로 | none·minimal·low·medium·high·xhigh·max 중 모델이 지원하는 값 | 추론 토큰은 출력 단가, 원문은 안 보이고 요약만 |
| 직접 서빙 오픈 모델(Qwen3 등) | 채팅 템플릿 enable_thinking, /no_think | max_tokens, 필요하면 budget forcing | 요금은 없고 GPU 시간·KV 캐시 메모리로 냄 |
| 일반 모델 + 여러 번 샘플링 | 사고 없이 N번 호출 | 샘플 수 N | 비용 N배, 지연은 한 번 호출과 비슷 |
Claude 적응형 사고 문서에 따르면 Claude 는 요청마다 생각할지, 얼마나 생각할지를 스스로 정하고 effort 는 그 판단을 미는 "부드러운 신호"예요. 그래서 effort 를 high 로 둬도 쉬운 질문에는 사고 블록이 아예 없을 수 있어요. 응답을 처리하는 코드가 "모든 답이 사고 블록으로 시작한다"고 가정하면 안 되는 이유예요.
Claude 4.7 이후 모델(Opus 5.5, Sonnet 5.5, Fable 5.1, Haiku 5.5 등)은 예전의 budget_tokens 방식을 받지 않고 400 오류를 돌려줘요. Claude 확장 사고 문서는 budget_tokens 를 지우고 effort 로 옮기라고 안내해요. 토큰 예산을 숫자로 박던 코드를 그대로 새 모델에 옮기면 바로 깨지니, 모델을 바꿀 때 가장 먼저 확인할 곳이에요.
사고 토큰 과금 규칙 — 보이는 것과 청구되는 것이 달라요
과금에서 놓치기 쉬운 규칙은 세 가지예요.
- 사고는 출력 단가예요. OpenAI 추론 모델 가이드는 추론 토큰이 API 로 보이지 않지만 컨텍스트 창을 차지하고 출력 토큰으로 청구된다고 적어요. Claude 도 같아요.
- 요약만 보여도 전체가 청구돼요. Claude 문서의 과금 표를 보면
display를summarized로 두든omitted로 두든 청구되는 출력은 "내부에서 생성한 사고 토큰 전체"예요. 응답에 찍힌 글자 수로 비용을 어림하면 실제보다 크게 낮게 나와요. 실제 사고 양은usage.output_tokens_details.thinking_tokens(Claude),usage.output_tokens_details.reasoning_tokens(OpenAI)로 확인해요. - 이전 턴 사고가 다시 청구될 수 있어요. Claude 4.6 이후 모델은 지난 턴의 사고 블록을 기본으로 컨텍스트에 남기고, 그만큼을 입력 단가로 청구해요. 반대로 Qwen3 모델 카드는 히스토리에 최종 답만 남기라고 권하고, 공식 채팅 템플릿이 사고를 자동으로 빼 줘요.
세 번째 규칙이 대화형 서비스에서 얼마나 큰지 계산해 볼게요. 턴마다 사고 3,000토큰을 쓰는 10턴 대화라면, k번째 턴 입력에는 앞선 사고 3,000 × (k−1)토큰이 붙어요. 10턴을 더하면 3,000 × 45 = 13만 5천 토큰이에요. Sonnet 5.5 입력 단가(100만 토큰당 2달러)로 대화 하나에 0.27달러인데, 사고 자체의 출력비(3만 토큰 × 10달러 = 0.30달러)와 거의 같아요. 캐시를 쓰면 같은 13만 5천 토큰이 읽기 단가(0.10달러)로 계산돼 약 0.014달러까지 내려가니, 긴 대화에 사고를 켠다면 프롬프트 캐싱 비용 계산 글의 설정을 함께 보세요.
2026년 10월 단가로 계산한 effort별 요청 비용
Claude 가격표와 OpenAI 가격표의 표준 요금(100만 토큰당 달러)이에요.
| 모델 | 입력 | 출력(사고 포함) | 출력 ÷ 입력 |
|---|---|---|---|
| Claude Fable 5.1 | 10 | 50 | 5배 |
| Claude Opus 5.5 | 4 | 20 | 5배 |
| Claude Sonnet 5.5 | 2 | 10 | 5배 |
| Claude Haiku 5.5 (프롬프트 10만 토큰 이하) | 0.10 | 0.50 | 5배 |
| gpt-6-astra | 10 | 50 | 5배 |
| gpt-6.1-sol | 2 | 10 | 5배 |
| gpt-6.1-terra | 1 | 5 | 5배 |
| gpt-6-luna | 0.10 | 0.50 | 5배 |
모든 모델에서 출력이 입력의 5배라서, 사고 1,000토큰은 입력 5,000토큰과 값이 같아요. 아래는 입력 2,000·답 400토큰인 요청에 사고 토큰만 바꿔 붙였을 때 1,000건 비용이에요. 사고 토큰 수는 effort 단계별 실측값이 아니라 계산용 예시예요. 같은 effort 여도 문제 난이도에 따라 0부터 수만까지 흔들려요.
Sonnet 5.5 로 풀면 입력 2,000 × 2달러 = 0.004달러, 답 400 × 10달러 = 0.004달러라 사고가 없으면 건당 0.008달러예요. 사고 4,000토큰이 붙으면 0.04달러가 더해져 0.048달러, 6배가 돼요. 사고가 길어지면 입력비는 사실상 무시해도 되는 수준이 되고 비용은 거의 사고 토큰 수로 정해져요.
눈여겨볼 비교가 하나 있어요. 사고를 1만 6천 토큰이나 쓰는 Haiku 5.5(8.4달러)와 사고 없는 Sonnet 5.5(8달러)가 비슷해요. 작은 모델에 생각을 많이 시키는 선택지와 큰 모델에 바로 답하게 하는 선택지가 같은 값이라는 뜻이에요. Snell 등의 테스트 시간 계산 연구는 계산량(FLOPs)을 맞춘 비교에서, 작은 모델이 어느 정도 맞히는 문제라면 추론 계산을 더 주는 편이 14배 큰 모델보다 나을 수 있다고 보고했어요. 단, 작은 모델이 거의 못 푸는 문제에서는 그렇지 않았다는 조건이 붙어요. 어느 쪽이 나은지는 자기 평가셋으로 두 조합을 같은 비용에 놓고 재 봐야 해요.
비동기로 돌려도 되는 작업이면 Claude·OpenAI 모두 배치 처리 요금이 입출력 50% 할인이라, 위 금액이 그대로 절반이 돼요.
사고 토큰이 늘면 사용자는 몇 초를 기다리나
API 회사들은 모델별 초당 생성 토큰 수를 약속하지 않아요. 그래서 생성 속도를 초당 50·100·200토큰 세 가지로 가정하고, 사고와 답을 모두 쓰는 데 걸리는 시간을 계산했어요. 첫 토큰까지의 시간(입력 처리)은 빼고 순수 생성 시간만이에요.
사고는 한 토큰씩 직렬로 생성돼서, GPU 를 늘려도 한 요청의 대기 시간은 줄지 않아요
표로 보기
| 구분 | 초당 50토큰 | 초당 100토큰 | 초당 200토큰 |
|---|---|---|---|
| 사고 0 | 8 | 4 | 2 |
| 사고 1천 | 28 | 14 | 7 |
| 사고 4천 | 88 | 44 | 22 |
| 사고 1만6천 | 328 | 164 | 82 |
초당 100토큰이면 사고 4,000토큰에 44초예요. 사고를 끈 4초와 비교하면 11배예요. 사고 구간은 앞 토큰을 읽고 다음 토큰을 만드는 직렬 과정이라 병렬화로 줄일 수 없어요. 사람이 화면 앞에서 기다리는 채팅·자동완성에는 이 시간이 그대로 체감 지연이 돼요.
그래서 대화형 화면에서는 effort 를 낮춰 사고 양을 줄이고, 스트리밍으로 진행 상태를 먼저 보여 줘요. 길게 생각하는 요청은 백그라운드 작업으로 돌리고 완료 알림을 주는 편이 나은 경우도 많아요.
Claude 확장 사고 문서는 사고 예산을 3만 2천 토큰 넘게 잡는 요청은 연결이 오래 열려 타임아웃에 걸릴 수 있으니 배치 처리를 쓰라고 권해요. 게이트웨이·로드밸런서의 유휴 타임아웃이 60초로 잡혀 있다면, 위 표의 초당 50토큰 기준으로 사고 2,600토큰 남짓에서 이미 걸려요. 추론 모델을 붙이기 전에 프록시 타임아웃부터 확인하세요.
직렬로 오래 생각할까, 병렬로 여러 번 물을까
계산을 더 쓰는 방법은 한 줄을 길게 쓰는 직렬 방식(사고 토큰)과 여러 답을 뽑아 고르는 병렬 방식(다수결, best-of-N)으로 나뉘어요. 개발자 입장에서 둘의 차이는 비용보다 지연과 적용 범위예요.
| 비교 | 사고 4,000토큰 1회 | 사고 없이 5회 샘플 후 다수결 |
|---|---|---|
| Sonnet 5.5 건당 비용 | 0.048달러 | 0.040달러 (입력 5번·답 5번) |
| 생성 시간(초당 100토큰) | 44초 | 약 4초 (5개를 동시에 호출) |
| 쓸 수 있는 문제 | 거의 모든 문제 | 답이 숫자·선택지처럼 짧게 정해지는 문제 |
| 틀렸을 때 고칠 기회 | 사고 안에서 스스로 되돌아감 | 샘플끼리 서로 못 봄 |
비용은 비슷한데 지연이 10배 넘게 차이 나요. 그래서 정답이 짧은 값으로 정해지고 기계로 맞춰 볼 수 있는 문제(분류 라벨, 숫자 계산, 객관식)라면 병렬 다수결이 지연 면에서 유리해요. 자기 일관성 논문은 풀이를 여러 번 뽑아 다수결을 하는 것만으로 생각의 사슬 프롬프팅보다 GSM8K 정답률이 17.9%p 올랐다고 보고했어요. 반면 코드 작성·글 요약처럼 답이 긴 문제는 "가장 많이 나온 답"을 정의하기 어려워 다수결을 쓸 수 없어요. 반복되는 입력은 캐시로 줄일 수 있지만, 모델에 따라 한 요청으로 여러 답을 받는 옵션이 없을 수 있으니 호출 수 제한도 계산에 넣어요.
샘플링 설정에 따라 다수결 효과가 달라지는 부분은 LLM temperature 설정 고르기 글에 API별 지원표와 다중 샘플 비용을 정리해 두었어요.
라우팅 예시 — 월 10만 건 서비스의 비용 비교
예시 가정이에요. 월 10만 건이 들어오는 사내 도우미가 있고, 요청은 모두 입력 2,000·답 400토큰이에요. 그중 80%는 문서 찾기·요약처럼 쉬운 요청, 20%는 여러 단계 분석이 필요한 요청이라고 놓았어요. 어려운 요청은 높은 effort 에서 평균 사고 8,000토큰을 쓴다고 가정했어요.
전부 사고 4,000토큰으로 보내면 4,800달러예요. 쉬운 8만 건만 사고를 끄면, 어려운 2만 건에 오히려 사고를 두 배(8,000토큰)로 줘도 2,400달러로 절반이 돼요. 쉬운 요청을 Haiku 5.5 로 내리면 1,792달러, 처음보다 63% 줄어요. 비용 대부분이 어려운 20%(1,760달러)에서 나온다는 점도 보여요. 여기서 더 줄이려면 어려운 요청의 사고 양을 평가셋으로 깎아 봐야 해요.
라우팅을 어떻게 나눌지는 세 가지가 흔해요. 요청 종류(엔드포인트·기능)별로 effort 를 고정하는 방식이 가장 단순하고 예측하기 쉬워요. 그다음은 작은 모델이 먼저 답하고, 검증(테스트 실패, JSON 검증 실패, 낮은 확신)에 걸릴 때만 큰 모델·높은 effort 로 다시 보내는 방식이에요. 마지막은 분류용 작은 모델로 난이도를 먼저 판정하는 방식인데, 분류 호출 비용과 오분류 비용을 같이 계산해야 해요.
Claude 에서 한 대화 안에서 effort 를 바꾸려면 주의할 점이 있어요. 요청 최상위의 effort 를 바꾸면 그 값이 프롬프트에 렌더링돼서 캐시가 깨져요. Opus 5.5·Sonnet 5.5·Haiku 5.5·Fable 5.1 은 메시지 단위 effort 변경(베타)을 지원하고, 이 방식은 캐시를 유지해요. Claude effort 문서에 헤더와 메시지 형식이 나와 있어요.
상황별 effort 추천표
공식 문서의 권장과 위 계산을 합쳐 시작점을 정리했어요. 어디까지나 출발점이고, 최종 값은 평가셋으로 정해요.
| 작업 | 시작 설정 | 근거 |
|---|---|---|
| 분류·추출·짧은 형식 변환 | OpenAI none/minimal, Claude low 또는 사고 끔 | OpenAI 가이드가 분류·빠른 검색에 none 을 권함 |
| 채팅·고객 응대 | low~medium + 스트리밍 | Sonnet 5.5 문서가 채팅에 medium·low 권장 |
| 문서 Q&A(RAG) | low~medium | 근거 문서가 이미 주어져 추론 단계가 짧음 |
| 도구 호출·검색·계획 | OpenAI low, Claude medium | OpenAI 가이드가 도구 사용·계획에 low 를 권함 |
| 에이전트 코딩·여러 단계 디버깅 | medium~high, max_tokens 크게 | Sonnet 5.5 는 명확한 과제 medium, 어려운 과제 high |
| 수학·알고리즘·긴 분석 | high, 필요하면 xhigh | 품질이 오르는지 평가로 확인한 뒤에만 올림 |
| 야간 대량 분석 | high + 배치 처리 | 지연 상관없음, 50% 할인 |
모델마다 기본값이 다르다는 점도 기억해 두세요. Claude Opus 5.5·Haiku 5.5 는 effort 기본값이 medium, 그 밖의 effort 지원 모델은 high 예요. Opus 5.5 는 사고를 끌 수 없어서 thinking: {type: "disabled"} 를 보내면 400 오류가 나요. Sonnet 5.5 에서 앞쪽 사고를 끄려면 "disabled" 대신 between_tools 를 쓰고, 이 설정은 low~high 에서만 돼요. 이전 모델에서 쓰던 effort 값을 그대로 옮기지 말고 새로 훑어보라는 것이 문서의 공통된 권고예요.
직접 서빙할 때 — Qwen3 사고 모드와 KV 캐시 메모리
오픈 모델을 직접 띄우면 토큰 요금은 없지만, 사고가 GPU 메모리를 먹어요. Qwen3 모델 카드는 대부분의 질의에 출력 길이 32,768토큰을 권하고, 어려운 수학·코딩 벤치마크에는 38,912토큰까지 잡으라고 적어요. 이 길이가 그대로 KV 캐시 크기가 돼요.
Qwen3-8B 의 설정 파일(36층, KV 헤드 8개, 헤드 차원 128, bf16)로 토큰 하나의 KV 캐시를 계산하면 2(K·V) × 36 × 8 × 128 × 2바이트 = 147,456바이트, 약 144KiB 예요.
- 사고 없이 입력 2,000 + 답 400 = 2,400토큰이면 요청 하나에 약 0.33GiB
- 사고까지 32,768토큰을 다 쓰면 요청 하나에 약 4.5GiB
같은 GPU 메모리로 동시에 처리할 수 있는 요청 수가 최대 약 14분의 1로 줄어요. 바이트를 GiB 로 바꿀 때 1,000과 1,024 기준이 헷갈리면 데이터 용량 변환기로 확인하세요. GPU 메모리 배분과 동시 요청 수 계산은 vLLM KV 캐시 용량 계산 글에 자세히 있어요.
직접 서빙에서 쓰는 손잡이는 이렇게 정리돼요.
enable_thinking=False는 템플릿에 빈 사고 구간을 미리 넣어 사고를 건너뛰게 해요. 턴마다 바꾸려면 메시지에/think,/no_think를 붙여요(사고 모드가 켜져 있을 때만).- 사고 모드에서는 temperature 0.6·top-p 0.95·top-k 20 이 권장값이고, 모델 카드는 그리디 디코딩을 쓰지 말라고 강조해요. 성능이 떨어지고 같은 말을 끝없이 반복할 수 있어서예요.
- 사고 길이에 딱 맞는 상한이 필요하면
max_tokens로 자르거나, s1 논문의 budget forcing 처럼 예산이 차면 사고 종료 토큰을 강제로 넣고 답을 쓰게 하는 방법이 있어요. 이 논문은 사고를 늘려 AIME24 정답률이 50%에서 57%로 올랐다고 보고했지만, 무한정 늘린다고 계속 오르지는 않는다는 점도 함께 적었어요.
비용·장애로 이어지는 흔한 실수
- max_tokens 를 사고 없을 때처럼 잡음. OpenAI 는 이때 응답
status가incomplete, 이유가max_output_tokens로 오고, 처음 실험할 때는 최소 25,000토큰을 확보하라고 권해요. Claude 는stop_reason: "max_tokens"가 오면 한도를 올리거나 effort 를 낮추라고 안내해요. 잘린 요청에 사고가 필요했으면 한도를, 과하게 생각했으면 effort 를 고쳐요. - 사고 로그를 감사 기록처럼 믿음. Anthropic 의 사고 충실성 연구에서 프롬프트에 힌트를 몰래 넣었을 때 Claude 3.7 Sonnet 은 평균 25%, DeepSeek R1 은 39%만 사고에서 힌트를 썼다고 밝혔어요. 사고 내용을 "모델이 이렇게 판단했다"는 근거로 사용자에게 보여 주거나 규정 준수 증빙으로 쓰지 마세요.
- 쉬운 요청에도 높은 effort. 과잉 사고 연구는 "2 더하기 3"에 o1 계열 모델이 일반 모델보다 평균 1,953% 많은 토큰을 썼고, 한 모델은 이 질문에 풀이를 13가지나 냈다고 보고했어요. 단순 요청 비율이 높은 서비스일수록 effort 를 낮춘 효과가 커요.
- 대화 중간에 effort 를 최상위에서 바꿈. Claude 에서는 캐시가 통째로 깨져서, 한 번 아끼려다 다음 요청의 입력 전체를 쓰기 요금으로 다시 내요.
- 도구 호출 루프에서 추론 항목을 버림. OpenAI 가이드는 함수 호출이 이어질 때 마지막 호출의 추론 항목을 함수 결과와 함께 돌려보내라고 권해요. Claude 도 도구 사용 중에는 사고 블록을 수정하지 말고 그대로 돌려보내야 해요.
- 생성 속도만 보고 타임아웃을 정함. 사고 1만 토큰이면 초당 100토큰에서도 100초가 넘어요. 프록시·서버리스 함수의 제한 시간을 함께 늘리거나 비동기로 바꿔요.
추론 모델 도입 체크리스트
켜기 전
- 요청을 종류별로 나누고, 종류마다 "사고 없이도 되는가"를 평가셋 50~100건으로 재 봤다.
- 종류별 시작 effort 를 정하고, 한 단계 낮췄을 때 품질이 유지되는지 비교했다.
- 사고 토큰 예상치로 위 공식(입력 × 단가 + (사고 + 답) × 출력 단가)에 넣어 월 비용을 계산했다.
- 프록시·게이트웨이·클라이언트 타임아웃이 예상 생성 시간보다 길다.
- max_tokens 를 사고 + 답 기준으로 다시 잡았다.
켠 뒤
thinking_tokens·reasoning_tokens를 요청 종류별로 로그에 남겨 분포(중앙값·95분위)를 본다.incomplete·max_tokens로 끝난 비율을 대시보드에 띄운다.- 대화형 경로는 이전 턴 사고가 입력으로 얼마나 붙는지, 캐시 적중률과 함께 확인한다.
- 모델을 바꿀 때마다 effort 를 새로 훑는다(같은 이름의 단계가 모델마다 다른 양을 써요).
직접 서빙이라면
- 최대 출력 길이 × 토큰당 KV 크기로 요청 하나의 메모리를 계산했다.
- 사고 모드 샘플링 권장값을 쓰고, 그리디 디코딩을 끄지 않았는지 확인했다.
- 서빙 엔진의 추론 파서로 사고와 답을 나눠 저장한다.
자주 묻는 질문
사고 토큰은 입력 단가인가요, 출력 단가인가요?
출력 단가예요. Claude·OpenAI 모두 사고를 출력 토큰으로 청구하고, 화면에 요약만 보이거나 아예 안 보여도 실제 생성한 양 전체가 청구돼요. 다만 Claude 4.6 이후 모델은 지난 턴의 사고 블록이 컨텍스트에 남아 다음 요청에서 입력 단가로 한 번 더 청구돼요.
effort 를 낮추면 품질이 얼마나 떨어지나요?
작업마다 달라서 공통 숫자는 없어요. Claude 문서도 effort 효과가 작업 종류에 따라 다르니 자기 사례로 평가하라고 적어요. 평가셋을 정해 기본값에서 한 단계씩 내려 보며 정답률과 토큰 수를 같이 기록하는 것이 가장 확실해요.
사고 토큰 수를 정확히 제한할 수 있나요?
최신 API 에서는 정확한 상한이 아니라 effort 라는 부드러운 신호와 max_tokens 라는 딱딱한 한도 두 개로 조절해요. max_tokens 는 사고와 답을 합친 한도라, 너무 낮추면 답이 잘려요. 직접 서빙하는 오픈 모델은 budget forcing 처럼 사고 종료 토큰을 강제로 넣는 방식으로 상한을 둘 수 있어요.
작은 모델에 high 와 큰 모델에 low 중 무엇이 낫나요?
같은 비용에 놓고 평가셋으로 비교해야 해요. 위 계산처럼 사고를 많이 쓴 Haiku 5.5 와 사고 없는 Sonnet 5.5 의 비용이 비슷한 구간이 있어요. 연구에서는 작은 모델이 어느 정도 맞히는 문제에서만 추론 계산을 더 주는 쪽이 유리했어요.
사고 내용을 사용자에게 보여 줘도 되나요?
진행 상황을 보여 주는 용도로는 괜찮지만, 답의 근거로 내세우면 안 돼요. 연구에서 사고가 실제로 사용한 힌트를 밝히지 않는 경우가 많았어요. OpenAI 는 원문 대신 요약만 제공하고, Claude 도 요약된 사고를 돌려줘요.
정리
- 사고 토큰은 출력 단가라서, 사고 4,000토큰이면 짧은 요청 비용이 6배, 생성 시간이 11배가 돼요.
- 분류·추출·채팅은 사고를 끄거나 low, 여러 단계 코드·분석만 medium~high 로 시작하고 평가셋으로 한 단계씩 내려 보세요.
- 쉬운 요청을 사고 없이, 어려운 요청만 높은 effort 로 보내는 라우팅이 가장 큰 절감이에요. 예시에서는 63%가 줄었어요.
- 지연이 중요하고 답이 짧은 값이면 병렬 다수결을, 대량 비동기면 배치 할인을 같이 검토하세요.
- 직접 서빙은 긴 사고가 KV 캐시를 먹어 동시 처리 수가 크게 줄어요. 요청 하나 메모리부터 계산하고, 단위 변환은 데이터 용량 변환기로 확인하세요.
더 깊이 읽기
이 글은 실무에서 판단할 때 필요한 것 위주로 정리했어요. 같은 주제의 내부 동작 원리는 devboi 기술 블로그의 추론 모델과 사고 토큰 원리 — GRPO·DeepSeek-R1·budget forcing에서 도식과 코드로 단계별로 풀었어요.