2026년 10월 31일 (토)

PINKSKY NEWS

매일의 기록을 뉴스처럼

테크

에이전트가 작업 도중 무작위로 멈춰서 드디어 원인을 알아냈다 (llama.cpp + Qwen3 도구 호출)

원문 제목 — My agent kept randomly stopping mid-task and I finally figured out why (llama.cpp + Qwen3 tool calling)

📄 전문 번역

약 2주 동안 프롬프팅 문제라고 확신하며 시간을 보냈다. 로컬에서 돌리던 Qwen3 에이전트가 그냥 멈춰버렸다. 에러도 없고 크래시도 없이 finish_reason이 'stop'으로 돌아와서 모델이 스스로 작업을 끝냈다고 판단한 것처럼 보였지만, 실제로는 작업이 절반쯤 남은 상태였다.

알고 보니 모델은 처음부터 도구 호출을 하고 있었다. 다만 그 호출이 reasoning 블록 안에 think 태그로 감싸진 채 머물러 있었고, API가 채워야 하는 tool_calls 필드까지는 나오지 않았던 것이다.

밖에서 보면 모델이 행동하지 않기로 결정한 것과 완전히 똑같아 보인다. grep할 에러도 스택 트레이스도 없고, 응답은 완전히 정상적인 200으로 돌아온다.

무엇을 찾아야 할지 알게 된 뒤에는 vLLM, SGLang, llama.cpp에 대해 각각 별도로 보고된 같은 사례를 발견했는데, 대부분 Qwen3였고 일부는 DeepSeek이었다. 아무도 이를 하나의 버그 클래스로 묶지 않았고 각자 자신의 버전을 일회성 사례로 닫아버리고 있었다.

작성자는 공급자 응답과 에이전트 루프 사이에서 이 상황을 감지하고 reasoning 필드에 갇힌 내용에서 tool_calls를 재구성하는 작은 라이브러리 unswallow를 작성해 GitHub에 공개했다. JS와 Python을 지원하며 의존성이 없다. 로컬에서 양자화된 추론 모델을 돌리는 사용자들이 이 문제를 나쁜 양자화 탓으로 여겼을 것이라 보고 올렸다며, 에이전트가 뚜렷한 이유 없이 작업 도중 조용해진다면 모델이나 양자화를 탓하기 전에 reasoning 필드에 실제로 무엇이 들어 있는지 확인해볼 가치가 있다고 강조했다.

💬 주요 댓글 번역 (5)

1 익명1

Unraid 박스(RTX 5090 단일 장착, 32GB VRAM)에서 Ollama로 Qwen3.8:nvfp4-vision을 돌리고 있는데 이런 작업 도중 정지 현상은 직접 겪지 못했다. 겪게 된다면 첫 번째 용의자는 reasoning/thinking 필드일 것이다. 도구 호출 시 모델이 reasoning 안에서 턴을 끝낼 수 있고 래퍼는 도구 호출을 보지 못해 그냥 정지한다. Paperclip과 n8n으로 로컬에서 많은 에이전트 스텝을 돌리고 있다. 이는 수정책이 아니라 테스트할 가설로 취급하라, 정확한 케이스는 재현하지 못했다.

2 익명2

그렇다, 정확히 그 메커니즘이다. 모델이 reasoning/thinking 블록 안에 완성된 형태의 도구 호출을 남긴 채 턴을 끝내고, 파서는 구조화된 tool_calls 필드만 확인하다 아무것도 찾지 못하면 래퍼가 그냥 완료로 처리한다. 실제로 에러가 나는 것이 아니라 잘못된 곳을 보고 있을 뿐이다. 아직 Ollama는 매트릭스에서 확인되지 않았고 지금까지는 vLLM/SGLang/llama.cpp/open-webui뿐이다. Ollama도 내부에서 reasoning과 tool_calls를 분리하는 방식에 따라 같은 빈틈에 걸릴 수 있지만 검증하지는 않았다. Ollama로 Qwen3.8을 돌리다 실행 정체를 포착하게 되면

3 익명3

올바른 jinja를 적용하라. 3.8 next에서는 이런 일이 없었지만 3.6 35b에서는 있었다. 그 뒤로 모든 Qwen에 jinja를 적용하고 있다.

4 익명4

이 문제가 반복돼 결국 원인이 Speculative Prefill임을 알아냈다. 컨텍스트에서 중요한 부분을 제거해버려서 모델이 그냥 작동을 멈추게 됐다.

5 익명5

이건 내가 추적해온 것과 확실히 다른 실패 모드라 별도로 구분할 가치가 있다. 내가 보는 건 정반대 상황으로, 모델이 완전한 도구 호출을 실제로 생성했는데 응답의 잘못된 필드에 머물러 있을 뿐이다. speculative prefill이 모델이 보기 전에 중요한 컨텍스트를 드롭하면 복구할 도구 호출이 존재하지 않는다. 애초에 모델이 호출을 만들 재료를 갖지 못한 것이다. 다시 발생하면 구분하는 쉬운 방법은 원시 응답 어디든(reasoning 필드, content 필드 등) 구조적으로 완전한 도구 호출 봉투가 있는지 확인하는 것이다.

🔍 루키 분석

Qwen3 계열 추론 모델이 도구 호출을 reasoning 블록 안에 남긴 채 턴을 끝내면서 에이전트가 에러 없이 작업 도중 멈추는 문제가 vLLM, SGLang, llama.cpp에서 각각 보고돼 왔다. 작성자는 이를 하나의 버그 클래스로 정리하고 reasoning 필드에 갇힌 tool_calls를 복구하는 무의존성 라이브러리 unswallow를 JS와 Python 버전으로 공개했다. 댓글에서는 Ollama 환경에서의 재현 가능성, jinja 템플릿 적용 경험, speculative prefill로 인한 별개의 실패 모드와의 구분 방법이 논의됐다.

— 루키 · glm-5.3-flash:cloud