코딩 에이전트를 위한 지속 가능한 상태(Durable State): LangGraph vs Google ADK vs OpenAI Agents
요약
장시간 실행되는 코딩 에이전트의 안정성을 위해 LangGraph, Google ADK, OpenAI Agents SDK의 상태 관리 방식을 비교 분석합니다. 단순 메모리를 넘어 워크플로우 상태, 지속성 경계, 재개 메커니즘의 차이점을 다룹니다.
핵심 포인트
- 코딩 에이전트의 안정성을 위해 단순 메모리 이상의 지속 가능한 상태 관리가 필수적임
- LangGraph는 체크포인터와 스토어를 분리하여 스레드 상태와 공유 데이터를 관리함
- 상태 관리의 핵심 요소로 상태 모델, 지속성 경계, 재개 프리미티브 등을 제시함
- LangGraph의 재개 시 노드가 다시 실행될 수 있으므로 멱등성 확보가 중요함
장시간 실행되는 코딩 에이전트는 채팅 데모에서는 숨겨지는 방식으로 실패합니다. 즉, 작업자가 재시작되거나, 몇 시간 뒤에 인간의 승인이 도착하거나, 저장소(repository)를 변경한 후 도구 호출(tool call)이 중단되는 경우입니다. "메모리 (Memory)"만으로는 충분하지 않습니다. 어떤 상태가 저장되는지, 무엇이 재개되는지, 그리고 무엇이 두 번 실행될 수 있는지를 알아야 합니다.
이 글은 LangGraph, Google ADK, 그리고 OpenAI Agents SDK에 대한 문서 기반 비교입니다. 이는 벤치마크가 아니며, 세 가지를 대상으로 공통된 워크로드를 실행하지도 않았습니다. 저는 2026년 7월 21일에 공식 문서를 검토했습니다.
평가 기준
저는 다음 항목들을 기준으로 각 옵션을 비교했습니다:
- 상태 모델 (State model): 대화 기록, 워크플로우 상태 및 세션 간 데이터.
- 지속성 경계 (Durability boundary): 무엇이 언제 영구 저장되는가.
- 재개 프리미티브 (Resume primitive): 일시 중지되거나 중단된 실행이 어떻게 계속되는가.
- 재생 및 부작용 (Replay and side effects): 도구(tools)나 노드(nodes)가 다시 실행될 수 있는가.
- 프로덕션 경로 (Production path): 스토리지 백엔드 및 운영 제어.
- 코딩 에이전트 적합성 (Coding-agent fit): 저장소 편집, 테스트, 승인 및 장시간 대기.
한눈에 보기
| 프레임워크 | 주요 지속 가능한 추상화 | 재개 핸들 (Resume handle) | 세션 간 메모리 | 주요 특징 (Sharp edge) |
|---|---|---|---|---|
| LangGraph | 스레드 상태를 위한 체크포인터 (Checkpointer); 공유 데이터를 위한 스토어 (Store) | thread_id 및 그래프 입력 또는 Command | 체크포인트와 분리된 스토어 (Store) | 재개된 노드가 재생될 수 있음; 부작용은 멱등적(idempotent)이거나 작업 내에서 격리되어야 함 |
| ... |
이 용어들은 서로 대체 가능한 것이 아닙니다. 대화 세션은 메시지를 보존할 수 있지만, 워크플로우 단계, 승인 상태 또는 파일 쓰기 결과는 정의되지 않은 상태로 남겨둘 수 있습니다.
1. LangGraph: 명시적 체크포인트와 별도의 스토어
LangGraph는 영속성(persistence)을 두 개의 의도적인 계층으로 나눕니다. **체크포인터 (checkpointer)**는 하나의 스레드에 대한 그래프 상태를 저장합니다. **스토어 (Store)**는 스레드 전반에 걸쳐 애플리케이션이 정의한 키-값(key-value) 데이터를 보유합니다. 이는 코딩 에이전트에 깔끔하게 매핑됩니다:
- checkpoint: 현재 저장소 작업, 계획, 도구 결과(tool results) 및 승인 대기(approval pause);
- store: 재사용 가능한 사용자 선호도, 팀 컨벤션(conventions) 또는 검증된 프로젝트 인덱스.
스레드 ID(thread ID)는 지속 가능한 커서(durable cursor) 역할을 합니다. 인간의 승인을 위해 interrupt()를 호출하면 실행이 일시 중지되고 상태가 저장되며, 나중에 동일한 스레드를 사용하는 Command를 통해 실행이 재개됩니다. 이는 워크플로 그래프(workflow graph)와 그 제어 흐름(control flow)을 검사할 수 있기를 원하는 경우에 매우 적합합니다.
중요한 제한 사항은 재생(replay)입니다. LangGraph 문서에 따르면 실행은 정확한 Python 라인이 아니라 체크포인트 경계(checkpoint boundary)에서 재개됩니다. 즉, 노드(node)가 다시 실행될 수 있습니다. 비결정론적 작업(nondeterministic work)과 부수 효과(side effects)를 태스크(task)나 노드에 래핑(wrap)하고, 쓰기 작업을 멱등(idempotent)하게 만들며, 풀 리퀘스트(pull request)를 열거나 마이그레이션(migration)을 적용하는 것과 같은 작업에는 멱등성 키(idempotency key)를 사용하십시오.
최적의 용도: inspect → plan → approve → edit → test → review와 같이 명시적인 단계가 있는 코딩 워크플로, 특히 타임 트래블(time travel), 인간 참여형(human-in-the-loop) 일시 중지 또는 실패 후 복구가 필요한 경우.
2. Google ADK: 이벤트 기반 세션 및 재개 가능한 워크플로
Google ADK의 세션(Session)은 단순한 메시지 목록 그 이상입니다. 세션의 상태는 직렬화 가능한 키-값(key-value) 스크래치패드(scratchpad)이며, SessionService가 재시작 후에도 상태가 유지될지 여부를 결정합니다. InMemorySessionService는 지속 가능하지 않으며, DatabaseSessionService와 VertexAiSessionService가 상태 유지를 위해 문서화된 프로덕션 지향적 영구 저장 옵션입니다.
ADK는 또한 접두사(prefix)를 통해 범위를 가시화합니다:
- 접두사 없음: 현재 세션;
- user: 해당 사용자의 세션 간 공유;
- app: 애플리케이션 전체에서 공유;
- temp: 현재 호출(invocation)에서만 유효하며 영구적이지 않음.
재개 가능성(resumability)이 활성화되면, ADK는 완료된 워크플로 태스크를 이벤트(Events)에 기록합니다. 중단된 워크플로는 저장된 세션 및 호출 ID(invocation IDs)를 사용하여 재개할 수 있습니다. 순차적 및 병렬 워크플로는 기록된 완료 상태를 사용하여 가능한 경우 이미 완료된 브랜치(branch)를 다시 실행하지 않도록 합니다.
하지만 코딩 에이전트에게는 이러한 안전 경고가 매우 중요합니다. 공식 재개(resume) 문서에 따르면, 도구(tools)는 최소 한 번(at least once) 실행이 보장되며 재개 과정에서 여러 번 실행될 수 있다고 명시되어 있습니다. 따라서 파일을 수정하거나, 브랜치(branch)를 푸시하거나, 이슈(issue)를 생성하는 도구는 중복 방지(duplicate protection) 기능과 실행 후 상태 확인(post-run reality check) 기능이 반드시 필요합니다.
가장 적합한 경우: 이미 Google의 에이전트 런타임(agent runtime)을 사용 중이며, 세션 범위(session-scoped), 사용자 범위(user-scoped) 또는 앱 범위(app-scoped)의 상태(state)와 더불어 재개 가능한 순차적 또는 병렬 워크플로(workflows)를 원하는 팀.
3. OpenAI Agents SDK: 유연한 세션, 명시적인 실행 계속(run continuation)
OpenAI Agents SDK는 플러그인 방식의 세션(Session) 인터페이스를 제공합니다. 러너(runner)는 실행 전에 세션 항목을 로드하고, 실행 후에는 새로운 항목을 영속화(persist)합니다. 공식 Python 문서에서는 파일 기반 SQLite, Redis, SQLAlchemy, MongoDB, Dapr, 암호화된 래퍼(encrypted wrappers), 그리고 OpenAI가 호스팅하는 Conversations를 옵션으로 나열하고 있습니다.
사람의 승인을 위해 일시 중지된 경우, SDK는 실행 상태(RunState)를 직렬화(serialize)합니다. 사용자가 중단(interruption)을 승인하거나 거부하면, 해당 상태와 동일한 세션을 사용하여 다시 실행합니다. 이는 유용한 구분입니다. 세션은 대화 기록(conversation history)을 저장하는 반면, RunState는 계속되어야 하는 중단된 실행(interrupted execution)을 나타냅니다.
또한 SDK를 사용하면 모델 호출 전에 검색된 기록을 제한하거나 기록이 병합되는 방식을 사용자 정의할 수 있습니다. 이는 컨텍스트(context)의 증가를 제어하는 데 도움이 되지만, 임의의 모든 워크플로 단계를 체크포인팅(checkpointing)하는 것과는 다릅니다. 긴 대기 시간, 재시도(retries) 또는 프로세스 재시작의 경우, 공식 에이전트 실행 가이드(running-agents guide)는 Temporal, Dapr, Restate, DBOS와 같은 지속 실행(durable-execution) 통합 솔루션을 권장합니다.
가장 적합한 경우: 주로 지속적인 대화와 승인 계속(approval continuation)이 필요한 에이전트 애플리케이션, 또는 실행이 긴 장애나 대기 시간 동안에도 유지되어야 할 때 워크플로 런타임(workflow runtime)을 추가하는 데 거부감이 없는 팀.
코딩 에이전트 의사결정 규칙
복구해야 하는 장애(failure)의 유형에 따라 선택하십시오:
- “알려진 단계에서 이 그래프를 재개하고 이전 상태를 검사한다(Resume this graph at a known stage and inspect prior state).” LangGraph로 시작하십시오.
- “Google의 에이전트 런타임(agent runtime) 내에 세션, 사용자 및 앱 상태를 유지한다(Persist session, user, and app state inside Google’s agent runtime).” Google ADK로 시작하십시오.
- “대화 기록을 유지하고 승인을 재개한 다음, 필요할 때 워크플로 엔진(workflow engine)을 추가한다(Persist conversation history and resume an approval, then add a workflow engine when needed).” OpenAI Agents SDK로 시작하십시오.
단순히 “메모리 (memory)”라는 단어만 보고 선택하지 마십시오. 장애(crash) 발생 후 이러한 사실들이 어디에 존재하는지 질문하십시오:
- 어떤 커밋(commit) 또는 워크트리(worktree)가 활성 상태였는가?
- 어떤 도구(tools)가 성공적으로 완료되었는가?
- 이 정확한 명령과 인자(arguments)에 대해 승인이 부여되었는가?
- 다음 단계가 재실행(replay)하기에 안전한가?
- 운영자(operator)가 오래된 상태(stale state)를 검사하고 삭제할 수 있는가?
실질적인 상태 계약 (A practical state contract)
프레임워크와 관계없이, 전체 프롬프트(prompt)를 메모리에 쏟아붓기보다는 작고 명시적인 계약(contract)을 유지하십시오:
{
"task_id": "issue-1842",
"repo_sha": "abc123",
...
보유(retention), 암호화(encryption) 및 검색(retrieval) 정책이 없다면, 비밀 정보(secrets)와 신뢰할 수 없는 도구 출력값(untrusted tool output)을 지속 가능한 메모리(durable memory)에 포함하지 마십시오. 자격 증명(credentials)이 아닌 식별자(identifiers)와 검증된 결과(verified results)를 유지하십시오.
지금 해야 할 일
- 하나의 장애 시나리오를 선택하십시오: 테스트 중 워커(worker) 재시작, 승인 대기, 또는 중복된 패치 적용.
- 상태 경계(state boundary)를 그리십시오: 대화(conversation), 워크플로 커서(workflow cursor), 도구 결과(tool result), 그리고 세션 간 메모리(cross-session memory)는 서로 별개의 것입니다.
- 부수 효과(side-effecting)를 일으키는 모든 도구에 안정적인 작업 ID(task ID)와 멱등성 키(idempotency key)를 추가하십시오.
- 동일한 시나리오를 두 번 실행하십시오: 한 번은 정상적으로, 다른 한 번은 각 도구 경계(tool boundary)에서 워커를 종료한 후 실행하십시오.
- 재개(resume) 후 리포지토리(repository), 브랜치(branch), 이슈 트래커(issue tracker) 및 CI 시스템을 확인하십시오. “프레임워크가 재개되었다”는 사실이 부수 효과(side effect)가 정확히 한 번 발생했다는 증거는 아닙니다.
솔직한 한계점 (Candid limitations)
이 비교는 일반적인 벤치마크가 아닌 공식 문서(official documentation)를 기반으로 합니다. API와 통합(integration) 환경은 빠르게 변화하며, "지속성(persistent)"이라는 용어 자체만으로는 트랜잭션성(transactionality), 암호화(encryption), 보존(retention), 다중 작성자 동작(multi-writer behavior), 또는 정확히 한 번(exactly-once) 효과를 명시하지 않습니다. 스토리지 지연 시간(storage latency), 배포 토폴로지(deployment topology), 그리고 도구 설계(tool design)가 프레임워크 선택에 더 결정적인 영향을 미칠 수 있습니다. 문서에 명시된 재개(resume) 시맨틱스(semantics)를 설계 제약 조건으로 간주하고, 여러분만의 실패 모드(failure modes)를 테스트해 보시기 바랍니다.
관측 가능성(observability)에 대해 작업 중이라면, 에이전트 트레이스(agent traces)를 회귀 테스트(regression tests)로 전환하는 방법을 참조하세요. 관련 제어 흐름(control-flow) 선택에 대해서는, 에이전트 프레임워크 전반의 핸드오프(handoffs) 대 서브에이전트(subagents) 비교를 참조하세요.
출처 (Sources)
- LangGraph persistence
- LangGraph durable execution
- Google ADK state
- Google ADK resume stopped agents
- OpenAI Agents SDK sessions
- OpenAI Agents SDK running agents and durable execution
토론 (Discussion)
여러분의 코딩 에이전트가 재생(replay) 시 안전하게 보장해야 하는 첫 번째 부수 효과(side effect)는 무엇인가요: 파일 수정, 커밋(commit), 풀 리퀘스트(pull request), 아니면 운영 환경의 변경(production change)인가요?
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기