본문 바로가기
프로그래밍/AI

추론 모델 에이전트가 느린 이유는 생각 토큰: thinking을 끄기 전에 확인할 것

by me_in_sk 2026. 9. 26.
반응형
로컬 LLM

추론 모델 에이전트가 느린 이유는 생각 토큰: thinking을 끄기 전에 확인할 것

여러 역할이 토론하는 에이전트가 한 번에 35분 — 시간이 어디서 새고, 생각을 끄면 무엇을 잃는지 같은 질문으로 비교했다
핵심 요약
  • 느린 에이전트를 줄이려면 먼저 입력을 읽는 시간과 답을 쓰는 시간을 나눠 본다. 이 사례에서는 답을 쓰는 쪽이 86%였다. 프롬프트를 다듬어서 줄일 수 있는 몫은 크지 않았다.
  • 추론형 모델은 답 앞에 생각하는 토큰을 먼저 쓴다. 세어 보니 만든 토큰의 74%가 생각이었다. 짧게 답하는 토론 역할일수록 비율이 높았다.
  • 생각이 길면 느린 것에서 끝나지 않는다. 출력 한도를 생각이 다 써 버려 답이 빈 응답이 온다. 출력 한도와 생각에 쓸 한도를 따로 둔다.
  • 토론 역할의 생각을 끄자 29% 빨라졌고 최종 결론도 같았다. 그런데 중간 결과에서 형식이 깨지고 앞 역할의 주장을 따지는 힘이 약해졌다. 끄지 않고 한도를 두는 쪽을 택했다.
이 글의 환경과 용어

32GB 메모리의 맥 미니(M6)에서 Qwen3.8-27B 모델을 돌렸다. 서버는 애플의 머신러닝 프레임워크 MLX 위에서 도는 오픈소스 추론 서버 MTPLX다. Ollama, LM Studio, llama.cpp 같은 다른 서버도 원리는 같지만 설정 이름과 기본값은 다르다.

  • 생각 토큰(thinking): 추론형 모델이 답을 쓰기 전에 먼저 만드는 중간 추론 텍스트. 화면에 안 보여도 생성 시간과 토큰 수에 들어간다.
  • 생각 강도: OpenAI 호환 API의 reasoning_effort 값(low·medium·high 등). 모델이 얼마나 길게 생각할지의 경향을 정한다.
  • 생각 한도: 생각 토큰의 최대 개수. 이 서버는 실행 옵션으로 둘 수 있고, 한도에 닿으면 생각을 끝내고 답으로 넘어가게 한다.

1.느린 에이전트, 시간은 어디서 새나

여러 역할이 차례로 의견을 내고 토론해 결론을 내는 에이전트를 로컬 모델에 올렸다. 오픈소스 트레이딩 분석 프레임워크 TradingAgents의 구성으로, 분석가 넷이 자료를 모으고, 강세·약세 연구원이 토론하고, 트레이더와 리스크 담당 셋을 거쳐 마지막 담당자가 결론을 낸다. 모두 12역할이다. 종목 하나를 분석하는 데 35분이 걸렸다.

흔한 첫 손은 프롬프트를 줄이는 것이다. 그 전에 할 일이 있다. 서버 기록에서 입력을 읽는 시간과 답을 쓰는 시간을 나눠 본다. 프롬프트를 줄이면 앞쪽만 줄어든다.

나눈 결과 (요청 21건)시간비율
입력을 읽는 시간약 4분14%
답을 쓰는 시간약 27분86%

답을 쓰는 시간이 대부분이면 방법은 둘뿐이다. 토큰을 덜 쓰거나 빨리 쓰거나. 쓰는 속도는 대개 하드웨어가 정하므로 움직일 수 있는 것은 쓰는 양이다. 입력을 읽는 시간을 줄이는 방법(요청마다 같은 앞부분의 계산을 기억해 두었다 다시 쓰는 prefix 캐시)은 prefix 캐시를 다룬 글에 정리했다.

쓰는 속도는 무엇이 정하나 →

맥에서 로컬 LLM 속도 미리 가늠하기: 메모리 대역폭과 투기적 디코딩

답을 쓰는 속도는 메모리 대역폭이 정한다. 초당 19토큰이면 생각 1,500토큰만으로 1분이 넘는다.

2.쓴 토큰 가운데 실제 답은 얼마인가

서버가 알려 주는 "생성 토큰 수"에는 답만 들어 있지 않다. 추론형 모델은 답을 쓰기 전에 생각하는 과정을 토큰으로 먼저 쓴다. 화면에 보이지 않는 경우가 많아서, 답은 짧은데 왜 오래 걸리는지 모르게 된다.

세는 방법은 간단하다. 받은 답을 모델과 같은 토크나이저로 세어 서버가 알려 준 생성 토큰 수에서 빼면, 나머지가 생각한 양이다.

역할별 생성 토큰 = 생각 + 답 — 종목 분석 한 번 (전체의 74%가 생각) 짧게 답하는 토론 역할일수록 생각이 길다 시장 분석가 4,012 (63% 생각) 감성 분석가 851 (79% 생각) 뉴스 분석가 2,379 (63% 생각) 재무 분석가 4,533 (72% 생각) 강세 연구원 1,947 (80% 생각) 약세 연구원 1,522 (77% 생각) 리서치 매니저 1,672 (78% 생각) 트레이더 1,430 (77% 생각) 공격형 리스크 1,602 (83% 생각) 보수형 리스크 2,886 (85% 생각) 중립형 리스크 2,779 (84% 생각) 포트폴리오 매니저 2,467 (62% 생각) 답 생각 점선 위: 도구로 자료를 모으는 분석가 · 아래: 앞 결과를 받아 토론하고 결정하는 역할
토론하고 결정하는 역할은 답 한 문단을 위해 그 네다섯 배를 생각했다.

3.생각이 넘치면 무슨 일이 생기나

생각이 길면 느린 것으로 끝나지 않는다. 출력 한도(최대 생성 토큰 수)는 생각과 답을 합쳐 센다. 생각이 한도를 다 쓰면 답을 쓰기 전에 생성이 끊기고, 클라이언트는 "답이 비었다"거나 "출력 한도에 닿았다"는 응답을 받는다.

흔한 대응은 한도를 올리는 것이다. 그러면 다음에는 더 길게 생각하다가 또 끊긴다. 실제로 이렇게 흘러갔다.

설정결과
생각 강도 높음, 출력 한도 2천 토큰한도를 생각으로 다 써서 중단
생각 강도 낮춤, 한도 2천여전히 자주 한도에 닿음
생각 강도 낮춤, 한도 4천한 역할이 4천 토큰을 전부 생각에 쓰고 답 없음
+ 생각 한도 1,500토큰한도에 닿으면 서버가 생각을 끊고 답으로 넘어간다

해법은 출력 한도와 생각 한도를 따로 두는 것이다. 출력 한도는 답이 들어갈 자리이고, 생각 한도는 생각에 쓸 수 있는 몫이다. 요청에 넣는 생각 강도는 경향을 바꿀 뿐 상한을 보장하지 않는다. 생각 한도를 서버 쪽에서 강제하는 기능이 있으면 그걸 쓴다. 이 글의 서버에는 있었고, 어떤 서버에는 없을 수 있다. 없다면 출력 한도를 넉넉히 두고 "답이 비었는지"를 따로 검사한다.

생각 한도가 모든 요청에 걸리지는 않을 수 있다

이 서버는 생각 한도를 도구를 쓰는 요청에만 걸었다. 그래서 도구로 자료를 모으는 분석가 역할은 막혔지만, 도구 없이 토론만 하는 역할은 한도를 넘어 2천 토큰 넘게 생각했다. 한도를 켰다면 어떤 요청에 실제로 걸렸는지 서버 기록으로 확인한다.

4.생각을 끄면 얼마나 빨라지고 무엇을 잃나

생각 대부분이 토론 역할에 몰려 있으니, 그 역할만 생각을 끄면 되지 않을까. 짧게 답하는 역할이니 괜찮을 것 같다. 같은 질문으로 두 번 돌려 비교했다. A는 모든 역할이 생각을 켰고, B는 토론·트레이더·리스크 6역할의 생각을 껐다.

A (모두 생각)B (6역할 생각 끔)
12역할 전체 시간37.7분26.6분 (−29%)
생성 토큰약 2만8천약 1만8천
최종 결론비중 확대비중 확대
토론 글에 JSON 코드 블록이 섞인 역할없음5개 역할
소수점 열 자리 넘는 숫자를 그대로 옮긴 곳2곳29곳
트레이더의 진입가과열을 지적하고 한 단계 낮춰 진입과열을 지적하고도 현재가로 진입

두 구성을 한 번씩만 돌린 비교라, 수치 하나하나보다 차이의 방향을 본다. 결론만 보면 B가 이긴다. 그런데 결론이 같다고 분석이 같은 것은 아니다. A의 리스크 담당은 앞 역할이 제안한 손절 간격이 평소 하루 변동폭의 절반도 안 된다고 짚었고, 다른 담당은 "고점 대비 14% 싸다"는 주장이 고점에 끌려간 판단이라고 반박했다. B의 담당들은 앞 역할이 쓴 숫자를 그대로 옮기며 비중만 조정했다. 생각을 끄면 형식을 지키는 일과 앞 사람의 주장을 따지는 일이 먼저 약해졌다.

처음 비교에서 틀린 두 가지

처음에는 B의 문제 목록에 "답에 한자가 섞였다"와 "6월 고점 가격을 틀리게 적었다"도 넣었다. 다시 세어 보니 둘 다 생각을 끈 탓이 아니었다. 한자는 B에서만 나왔지만 생각을 켠 역할에서도 나왔다. 고점 가격은 원래 데이터와 대조해 보니 A도 틀렸다.

A를 정답지로 놓고 B를 채점한 것이 실수였다. 품질은 두 실행을 서로 비교하지 말고 원래 입력 데이터와 대조한다.

5.빠르기와 품질을 어떻게 함께 재나

결론이 같다는 이유로 빠른 쪽을 고르기 쉽다. 에이전트의 결론은 대개 몇 개의 범주(사라·들고 있어라·팔아라) 중 하나라 우연히 같아지기 쉽다. 그래서 중간 결과를 본다. 사람이 읽고 인상으로 판단하면 방금처럼 틀리므로, 셀 수 있는 것은 기계로 센다.

  1. 형식이 깨졌나. 글이어야 할 자리에 코드 블록이나 JSON이 섞인 곳을 센다.
  2. 숫자가 정리됐나. 반올림 안 된 긴 소수, 단위 없는 숫자를 센다.
  3. 원래 데이터와 맞나. 답에 나온 가격·날짜를 입력 데이터에서 찾아본다.
  4. 자기 말과 맞나. 스스로 지적한 위험과 그 역할이 낸 결정이 앞뒤가 맞는지 본다.
  5. 앞 사람의 말을 따졌나. 특정 주장을 짚어 반박했는지, 같은 말을 되풀이했는지 본다.
  6. 다른 언어가 섞였나. 다만 양쪽 모두에서 세어 원인을 가른다.

6.이 결론이 안 통하는 조건

  • 생각 없는 버전을 따로 잘 학습시킨 모델. 이 비교는 같은 모델의 스위치만 끈 것이다. 비추론 버전이 따로 있는 모델은 결과가 다를 수 있다.
  • 역할의 출력을 정해진 형식으로 받는 구성. 형식이 강제되면 1번 문제는 줄고, 판단의 질만 남는다.
  • 빠르고 싼 클라우드 모델. 개발 중에 같은 12역할을 클라우드의 소형 모델(GPT-5 mini)로 돌렸을 때는 약 3분이었다. 거기서는 생각을 줄일 이유가 약하다.
  • 최종 결론만 쓰는 경우. 중간 토론을 버린다면 이 글의 품질 기준이 덜 중요하다. 다만 그렇다면 토론 역할이 필요한지부터 묻는다.

7.정리

  1. 서버 시간을 입력 읽기와 답 쓰기로 나눈다. 답 쓰기가 대부분이면 프롬프트 다듬기의 효과가 작다.
  2. 생성 토큰을 생각과 답으로 나눠 센다.
  3. 출력 한도와 생각 한도를 따로 둔다. 생각 강도는 한도가 아니다.
  4. 생각 한도가 실제로 어떤 요청에 걸렸는지 확인한다.
  5. 생각을 끄기 전에 같은 입력으로 비교해 본다. 결론과 함께 중간 결과까지 본다.
  6. 품질은 원래 데이터와 대조해 기계로 센다.

생각을 끄면 빨라졌지만 형식과 반박이 무너졌다. 줄여야 할 것은 생각 자체가 아니라 생각에 쓸 수 있는 몫의 상한이었다.

로컬 LLM · Apple Silicon

반응형

댓글