LangGraph 에이전트가 무한 루프로 50달러를 날리는 이유와 recursion_limit이 왜 무딘 도구인지 분석함
I analyzed why LangGraph agents burn $50 on infinite loops (and why recursion_limit is a blunt instrument)
핵심 요약
LangGraph 에이전트의 무한 루프 문제를 해결하고 상태를 보존하는 오픈소스 인터벤션 훅 'TokenCircuit'을 소개합니다.
- 무한 루프 문제 — 에이전트가 오류 상황에서 잘못된 재시도를 반복하며 API 비용을 낭비함
- 기존 한계점 — recursion_limit은 상태를 초기화하고 에러를 발생시켜 데이터 손실을 유발함
- 해결책 제시 — pre_model_hook을 활용해 에러를 부분 요약으로 전환하고 상태를 유지함
- 성능 최적화 — 로컬에서 실행되며 tiktoken을 사용해 20µs 미만의 오버헤드로 루프를 감지함
다들 겪어봤을 거임: LangGraph 에이전트를 돌려놓고 나면,
403 Forbidden이나 잘못된 SQL 쿼리를 만나는데, 우아하게 실패하는 대신 LLM에게 도움을 요청함. 결국 ReAct 루프에 갇혀서 네이티브recursion_limit이 강제로 종료시킬 때까지 API 크레딧을 다 태워버림.
최악인 건 뭔지 앎? 네이티브recursion_limit은 너무 무딘 도구라는 거임.GraphRecursionError를 던지면서 실행을 멈추고, 체크포인트된 상태를 싹 날려버림. 에이전트가 수집했던 부분 데이터까지 다 잃어버리고, 프론트엔드 사용자는 500 에러만 보게 됨.
지난주 내내 에이전트가 왜 이러는지 파고들었음. 특히 자체적인 자기 교정 기능이 없는 오픈 웨이트 모델(Qwen/Llama)에서 더 심함. 그냥 원시적인RuntimeError나 "BLOCKED" 문자열을 에이전트에게 던져봤자 에이전트는 혼란스러워하며 다시 루프를 돌 뿐이라는 걸 깨달음.
그래서 이걸 해결하려고 오픈소스 모델 사전 개입 훅(pre-model intervention hook)을 만들었고, 헤드리스 에이전트 백엔드를 만드는 사람들과 아키텍처를 공유하고 싶었음.
작동 원리:
전체 그래프를 감싸는 대신, LangGraph의 네이티브pre_model_hook과ToolNodeAPI를 사용함. 치명적인 충돌을 제한된 성능 저하로 바꿔줌. 에이전트가 에러 대신 부분 요약을 반환하게 해서 상태를 보존함.
100% 로컬에서 실행되고,tiktokenshingling을 사용해 의존성 없는 의미론적 루프 감지를 수행하며, 20µs 미만의 오버헤드를 추가함.
Repo: https://github.com/Devaretanmay/TokenCircut
PyPI:pip install "tokencircuit[langgraph]"
다들 에이전트가 갇혔던 가장 이상한 무한 루프는 뭐였음? 나는 Databricks 에이전트가REQUIRES_SINGLE_PART_NAMESPACESQL 에러를 20번 연속으로 재시도하던 게 제일 기억에 남음.

