체크포인팅은 while 루프 에이전트가 무너지는 지점

루프형 에이전트를 위한 LangGraph 체크포인팅, 휴먼 리뷰, 재시도, 내구 실행.

체크포인팅은 while 루프 에이전트가 무너지는 지점
Share

장난감 수준의 에이전트에서는 체크포인트가 쉬워 보입니다. 상태를 어딘가에 쓰고, 재시작한 뒤, 이어서 실행하면 됩니다. 문제는 루프가 어떤 단계가 이미 실행됐는지, 어떤 도구 결과를 신뢰해야 하는지, 사람이 다음 작업을 승인했는지를 증명해야 할 때 드러납니다.

while-loop 에이전트에서 체크포인트가 깨지는 이유

단순한 while-loop 에이전트는 프로세스를 멈추거나, 재시작을 견디거나, 리뷰어를 기다리거나, 실패한 도구 호출 뒤 올바른 상태로 재개해야 하기 전까지는 괜찮습니다. 에이전트에 외부 부작용이 생기는 순간, 체크포인트는 파일 I/O 한 줄이 아니라 런타임의 문제가 됩니다. LangGraph는 2024년 1월 17일 순환형 에이전트 그래프를 위해 소개되었고 , 이후 LangChain은 2025년 10월 22일 LangChain 1.0에서 LangGraph를 내구성 있는 장기 실행 에이전트를 위한 하위 수준 런타임으로 제시했습니다 .

빠른 답변: while-loop 에이전트가 체크포인트에서 깨지는 이유는, 명시적인 상태 머신을 재개하기보다 보통 제어 흐름을 처음부터 다시 시작하기 때문입니다. LangChain은 2026년 7월 LangGraph 월간 다운로드가 6,500만 건을 넘었다고 밝혔고 , 이는 내구성 있는 그래프 런타임이 이제 에이전트의 주류 패턴이 되었음을 보여줍니다.

2026년 7월의 원본 영상은 이 비교를 위한 편집상의 출발점으로 유용하지만 , 구현 결정은 기본 런타임 문서를 기준으로 삼는 편이 좋습니다. LangGraph의 자체 개요는 이를 장기 실행 상태ful 에이전트를 위한 오케스트레이션으로 설명하며, 지속성 문서는 체크포인트를 스레드별로 정리된 저장된 그래프 상태로 정의합니다 .

"LangGraph provides durable execution, human-in-the-loop, persistence, and memory," — LangChain 문서 (source: LangGraph Overview)

실무에서의 변화는 루프를 다듬는 방식에서 명시적인 그래프를 설계하는 방식으로 옮겨가는 것입니다. 루프에서는 모델 호출, 도구 실행, 재시도, 승인 대기, 최종 응답이 하나의 제어 구조 안에 들어가는 경우가 많습니다. 그래프에서는 이것들이 이름 붙은 노드와 조건부 엣지가 되므로, 체크포인트는 단순히 "어떤 JSON이 저장됐다"는 뜻을 넘어서 런타임이 에이전트를 어디서 재개할 수 있는지까지 알려줍니다.

LangGraph를 쓰기 전에 정해야 할 것

Why checkpointing fails in while-loop agents

LangGraph를 쓰기 전에 에이전트를 상태 머신으로 정의하세요. 즉 messages, proposed_action, approved, tool_result, error 메타데이터, 재시도 카운터, 감사 필드를 담는 타입이 있는 상태 객체가 필요합니다. LangGraph는 내구성 있는 실행, 지속성, 스트리밍, human-in-the-loop 제어를 갖춘 상태ful 장기 실행 에이전트에 맞게 설계되어 있으며, LangChain 에이전트는 이런 런타임 기능을 위해 내부적으로 LangGraph를 사용합니다 LangGraph Overview.

설계 단계에서는 코드를 쓰기 전에 워크플로의 단계를 먼저 이름 붙여야 합니다. 실용적인 그래프라면 plan_or_call_model, route_tool_or_finish, request_approval, execute_tool, handle_rejection, finalize 같은 노드를 둘 수 있습니다. 이 이름 붙이기가 중요한 이유는 체크포인트가 단순히 직렬화된 변수 덤프가 아니라 그래프 상태에 묶이기 때문입니다 LangGraph Persistence.

상태 또는 노드 루프 밖으로 빼야 하는 이유
messages 체크포인트가 적용된 실행 사이에서도 대화와 도구 컨텍스트를 보존합니다.
proposed_actionapproved 부작용이 발생하기 전에 리뷰 결정을 명시적으로 남깁니다.
error 및 재시도 카운터 전체 에이전트를 재시작하지 않고도 런타임이 실패를 재시도하거나 라우팅할 수 있게 합니다.
audit 필드 누가 실행을 승인, 거절, 수정, 재개했는지 기록합니다.

메모리, 일시 중지/재개, 체크포인트 조회가 필요한 모든 실행에는 안정적인 configurable.thread_id를 전달해야 합니다. 그렇지 않으면 런타임이 올바른 체크포인트 계보를 안정적으로 가져올 수 없습니다 LangGraph Persistence. LangGraph는 2024년에 순환형 에이전트 그래프를 위한 라이브러리로 소개되었고 , 2025년 LangChain 1.0 발표에서는 LangGraph를 맞춤형 프로덕션 에이전트를 위한 하위 수준 런타임으로 자리매김했습니다 .

InMemorySaver는 테스트와 프로토타입에만 사용하세요. 해당 레퍼런스 페이지는 이를 프로덕션이 아니라 디버깅과 테스트에 적합한 것으로 설명합니다 InMemorySaver reference. 배포된 에이전트에서는 특히 사람의 승인이 프로세스를 넘어 실행을 일시 중지할 수 있다면 Postgres 또는 AsyncPostgresSaver 같은 지속성 체크포인트부터 시작하세요 LangChain human-in-the-loop docs.

LangGraph 실행 경로를 단계별로 잡기

Before touching LangGraph (source: cdn.prod.website-files.com)

실행 가능한 LangGraph 에이전트는 명시적인 상태 머신에서 시작합니다. 상태를 정의하고, 노드에 이름을 붙이고, 엣지를 그린 다음, 지속성과 검토 게이트를 추가합니다. LangGraph는 내구성 있는 실행, 스트리밍, human-in-the-loop 제어, 지속성, 메모리를 위해 LangChain 에이전트 아래에서 동작하는 저수준 런타임입니다 .

  1. 그래프 코드를 쓰기 전에 상태부터 스케치하세요. 기존 while 루프를 이름 붙은 전환들의 집합으로 다루세요. 실용적인 상태 객체라면 messages, proposed_action, approved, tool_result, error, 재시도 메타데이터, 감사 필드를 담을 수 있습니다. 노드는 plan_or_call_model, route_tool_or_finish, request_approval, execute_tool, handle_rejection, finalize처럼 이름 붙입니다. 이렇게 하면 루프 경계가 하나의 함수 안에 숨지 않고 눈에 보입니다.
  2. 모든 종료 경로에 조건부 엣지를 추가하세요. 라우팅 노드는 최종 응답, 안전한 도구 실행, 사람 검토, 거절 처리, 재시도, 종료 오류 중 하나를 선택해야 합니다. LangGraph의 모델은 노드와 엣지를 중심으로 구성되며, 노드는 결정적 코드, LLM 호출, 도구 호출, 하위 에이전트가 될 수 있습니다 . 판단 기준은 단순합니다. 어떤 분기가 운영 동작을 바꾼다면 엣지로 만드세요.
  3. 재개가 필요해지기 전에 체크포인트를 연결하세요. 체크포인터와 함께 그래프를 컴파일하고, 연속성이 중요할 때마다 같은 안정적인 configurable.thread_id로 호출하세요. LangGraph 지속성은 그래프 상태를 스레드별 체크포인트로 저장해 일시 중지와 재개, 대화 메모리, 장애 복구, 시간 여행식 디버깅을 가능하게 합니다 . 로컬 테스트에는 InMemorySaver를 사용하고, 내구성이 필요한 실행은 영속 체크포인터로 옮기세요.
  4. 사람 검토는 액션 경계에 두세요. LangGraph 수준에서는 검토 노드에서 interrupt()를 호출하고, 같은 thread_idCommand(resume=...)를 사용해 재개합니다 . LangChain 에이전트 수준에서는 HumanInTheLoopMiddleware가 선택된 도구 호출을 중단하고 검토자가 승인, 수정, 거절할 수 있게 합니다 .
  5. 불안정한 노드에 재시도를 붙이세요. 전체 실행을 하나의 넓은 예외 처리기로 감싸는 대신, 모델 호출, 원격 API, 데이터베이스, 도구에는 RetryPolicy를 사용하세요. LangGraph 문서의 재시도 기본값에는 max_attempts=3, initial_interval=0.5초, backoff_factor=2.0, max_interval=128.0초, jitter=True가 포함됩니다 . 노드 단위 재시도는 그래프의 감사 기록을 보존하고, 복구를 실패한 작업에 묶어 둡니다.

재시도는 노드에 붙이는 것이 맞습니다

Numbered runnable path for LangGraph (source: cdn.prod.website-files.com)

LangGraph 에이전트에서 노드 단위 재시도는 실무적으로 가장 적절한 경계입니다. 실패가 어디에서 났는지 숨기지 않으면서 실패한 모델 호출, API 요청, 데이터베이스 작업, 도구 노드만 다시 시도하기 때문입니다. 문서에 나온 RetryPolicy 기본값은 max_attempts=3, initial_interval=0.5초, backoff_factor=2.0, max_interval=128.0초, jitter=Truedefault_retry_on입니다 .

이 경계는 운영상 중요합니다. 에이전트 전체를 감싸는 넓은 try/except는 “실행이 실패했다”라고만 말할 수 있습니다. 반면 execute_tool, call_model, write_to_db에 붙은 재시도 정책은 어떤 단위가 실패했는지, 몇 번 재시도했는지, 중단 시점에 어떤 상태가 있었는지를 보여줍니다. 비용이 큰 원격 호출에서는 전체 대화 루프를 다시 재생하는 것보다 실패한 노드만 반복하는 편이 더 저렴하고 살펴보기도 쉽습니다.

"LangGraph는 그래프 실행 중 발생할 수 있는 일시적 오류를 처리하기 위한 내장 재시도 메커니즘을 제공합니다." — LangChain 문서 (source: LangGraph fault tolerance)

현재 한 가지 주의점이 있습니다. 같은 장애 허용 문서에서는 노드별 타임아웃과 노드 단위 오류 처리기가 langgraph>=1.2를 필요로 하며, 인용된 문서 기준으로 알파 상태이고 Python 전용이라고 설명합니다 . 특히 프로덕션 스택에 TypeScript 에이전트도 포함되어 있다면, 이런 기능은 유용하지만 아직 움직이는 런타임 제어 수단으로 다루세요.

체크포인트는 부분 성공 이후 “재시도”의 의미도 바꿉니다. LangGraph 지속성은 실패한 superstep 안에서도 성공한 노드의 pending write를 기록할 수 있으므로, 재개된 실행은 모든 분기를 처음부터 다시 실행하지 않고 완료된 병렬 작업을 유지할 수 있습니다 . 일반적인 while 루프에 대개 없는 부분이 바로 이것입니다. 단순히 한 번 더 시도하는 것이 아니라, 어떤 노드가 이미 쓸 수 있는 상태를 만들었는지 재개 가능한 기록으로 남깁니다.

단순 루프 다음에는 어디로 가야 할까

에이전트가 데모, 로컬 프로토타입, 단기 작업, 되돌릴 수 있는 작업이라면 단순 루프가 여전히 올바른 출발점입니다. LangChain create_agent 레퍼런스는 익숙한 흐름을 설명합니다. 모델을 호출하고, 도구 호출을 실행하고, 도구 메시지를 반환한 뒤, 실행이 끝날 때까지 모델을 다시 호출하는 방식입니다.

에이전트가 긴 대기, 사람의 검토, 외부 부작용, 상태 점검, 재생, 복구, 감사 기록처럼 실제 업무의 형태를 견뎌야 한다면 LangGraph로 옮겨가야 합니다. 이것이 “루프 엔지니어링”과 그래프 엔지니어링을 가르는 실질적인 기준입니다. LangGraph는 2024년 1월 순환형 에이전트 그래프를 위한 라이브러리로 공개 소개되었고 , 현재 LangChain의 자체 설명에서도 내구성 있고 상태를 유지하는 에이전트를 위한 더 낮은 수준의 런타임으로 다룹니다.

루프를 프로덕션으로 올리기 전에 다음 경계를 확인하세요.

  • LangGraph persistence에서 설명하듯, 실행이 올바른 체크포인트 계보로 재개되어야 한다면 안정적인 thread_id 값을 사용하세요.
  • 체크포인트 이후 재생 과정에서 LLM 호출, API 요청, 인터럽트가 반복될 수 있으므로, 외부 작업 ID를 사용해 도구 호출을 멱등적으로 만드세요.
  • 중요한 결과를 낳는 작업에만 인터럽트를 거세요. LangChain의 human-in-the-loop 미들웨어는 승인, 수정, 거절 같은 검토자 결정을 지원합니다.
  • 특히 긴 대화와 자주 재개되는 워크플로에서는 체크포인트 기록의 보존 규칙을 정하세요.

핵심은 분명합니다. 상태를 잃어도 괜찮다면 루프를 유지하고, 일시 중지, 재시도, 검토, 복구가 제품 요구사항이 되는 순간 LangGraph로 전환하세요.

자주 묻는 질문

LangGraph가 while 루프 에이전트를 대체하나요?

아니요. LangGraph는 기본 에이전트 루프를 대체한다기보다 그 구조를 명시적으로 드러냅니다. 상태, 노드, 엣지, 조건부 라우팅, 영속성, 복구가 하나의 루프 본문 안에 숨는 대신 런타임의 일부가 됩니다. 단기 데모와 되돌릴 수 있는 작업에는 단순 루프도 여전히 충분합니다. 에이전트에 내구성 있는 상태, 일시 중지와 재개, 검토 게이트, 장애 복구가 필요할 때는 LangGraph가 더 잘 맞습니다.

human-in-the-loop 검토에는 왜 체크포인팅이 필요한가요?

human-in-the-loop 검토에 체크포인팅이 필요한 이유는 에이전트가 중요한 작업을 실행하기 전에 멈추고, 현재 상태를 저장하고, 검토자의 결정을 기다린 다음, 같은 스레드 계보에서 다시 이어가야 하기 때문입니다. LangGraph의 인터럽트 흐름은 이런 일시 중지와 재개 모델을 중심으로 설계되어 있으며, LangChain의 HumanInTheLoopMiddleware도 도구 호출을 실행 전에 승인, 수정, 거절할 수 있도록 체크포인팅을 요구합니다.

InMemorySaver는 언제 충분한가요?

InMemorySaver는 프로세스가 종료된 뒤 상태를 잃어도 괜찮은 로컬 디버깅, 테스트, 프로토타입에 충분합니다. 프로덕션 에이전트는 재시작, 검토자 지연, 장시간 실행 워크플로를 지나서도 체크포인트 데이터가 살아 있어야 하므로 영속 체크포인트 저장소를 사용해야 합니다. LangGraph의 영속성 문서는 체크포인트를 메모리, 복구, 타임 트래블, 사람 검토에 사용되는 스레드별 저장 그래프 상태로 설명합니다.

LangGraph 에이전트에서 재시도는 어디에 두어야 하나요?

재시도는 전체 그래프 실행을 감싸는 곳이 아니라, 실패 가능성이 있는 노드 자체에 두어야 합니다. LangGraph에서는 모델 호출, 원격 API, 데이터베이스, 외부 도구에 노드 수준 재시도 정책을 붙일 수 있으며, 이렇게 하면 복구 범위가 실패한 작업으로 한정됩니다. 공식 fault-tolerance 문서max_attempts=3 같은 기본값과 지수 백오프를 포함한 재시도 정책을 설명합니다 .

이 글이 도움이 되셨다면, 새 글이 올라올 때마다 이메일로 받아보세요.

구독하기