체크포인팅: 실행 중단 후 재개

체크포인팅: 실행 중단 후 재개

오래 걸리는 크루·플로우·에이전트 실행이 중간에 실패하면 처음부터 다시 돌려야 하는데, 체크포인팅(Checkpointing)은 실행 상태의 스냅샷을 자동 저장해 실패 후 재개하거나 대체 분기로 포크할 수 있게 합니다. 저장 시점은 이벤트 기반으로 정하고(task_completed 등), 저장 백엔드는 JSON 파일이나 SQLite를 고를 수 있어요. 여기서는 동작 원리, 짧은 튜토리얼, 그리고 설정 방법을 정리합니다.

출처: 공식문서

본문

개요

체크포인팅은 실행 중 실행 상태의 스냅샷을 저장해 크루·플로우·에이전트가 실패 후 재개하거나 대체 분기로 포크될 수 있게 합니다.

설명

체크포인트란 무엇인가

체크포인트는 CrewAI가 실행 중간에 실행을 재현하는 데 필요한 모든 것을 캡처합니다: 크루·플로우·에이전트의 전체 상태 — 설정, 에이전트 메모리·지식 소스, 태스크 진행, 중간 출력, 내부 상태·속성 — 와 함께 킥오프 입력, 그 시점까지의 이벤트 히스토리, 체크포인트를 실행에 연결하는 lineage ID를 포함합니다.

복원은 그 상태를 재구성하고 이어갑니다. 완료된 태스크는 건너뛰고, 메모리·지식은 다시 수화되며, 후속 작업은 원래 실행이 만든 것과 같은 출력에 대해 실행됩니다. 포킹은 새 lineage 아래에서 같은 복원을 수행하므로 새 분기와 원래 실행이 서로 덮어쓰지 않고 나란히 체크포인트를 쓸 수 있습니다.

체크포인트가 쓰이는 시점

체크포인팅은 이벤트 기반입니다. 런타임이 on_events로 선택한 이벤트를 구독하고, 매번 발화 시 체크포인트를 씁니다. 기본 task_completed는 완료된 태스크마다 체크포인트 하나를 만듭니다 — 세분성과 디스크 사용 사이의 합리적 절충입니다. llm_call_completed 같은 더 높은 빈도 이벤트는 세밀한 복구에 사용할 수 있지만 훨씬 많은 파일을 씁니다.

저장

CrewAI와 함께 제공되는 두 공급자:

  • JsonProvider: 체크포인트마다 파일 하나를 씁니다. 사람이 읽기 쉽고 검사가 쉽습니다.
  • SqliteProvider: 단일 SQLite 데이터베이스에 씁니다. 고빈도 체크포인팅에 더 좋습니다.

둘 다 max_checkpoints가 설정되면 가장 오래된 체크포인트를 정리합니다.

자동 체크포인트 쓰기(이벤트 기반)는 best-effort입니다: 실패한 쓰기는 로깅되고 실행은 계속됩니다. 수동 `state.checkpoint()`와 `state.acheckpoint()` 호출은 실패 시 다시 던집니다.

상속 모델

Crew, Flow, Agent는 모두 checkpoint 인자를 받습니다. 자식은 자신의 값을 설정하거나 False로 탈퇴하지 않는 한 부모에게서 상속합니다. 크루에서 체크포인팅을 한 번 활성화하면 모든 에이전트가 참여하거나, 한 에이전트만 선택적으로 제외할 수 있습니다.

튜토리얼: 실패한 크루 재개

1단계: 체크포인팅이 활성화된 크루 생성

from crewai import Agent, Crew, Task

researcher = Agent(role="Researcher", goal="Research", backstory="Expert")
writer = Agent(role="Writer", goal="Write", backstory="Expert")

crew = Crew(
    agents=[researcher, writer],
    tasks=[
        Task(description="Research AI trends", agent=researcher, expected_output="bullets"),
        Task(description="Write a summary", agent=writer, expected_output="paragraph"),
    ],
    checkpoint=True,
)

2단계: 실행하고 첫 태스크 후 중단

result = crew.kickoff()

첫 태스크가 끝난 뒤 Ctrl+C를 누르세요. ./.checkpoints/를 보면 <timestamp>_<uuid>.json 파일이 체크포인트입니다.

3단계: 체크포인트에서 재개

from crewai import CheckpointConfig

result = crew.kickoff(
    from_checkpoint=CheckpointConfig(
        restore_from="./.checkpoints/<timestamp>_<uuid>.json",
    ),
)

연구 태스크는 건너뛰고, 작성자는 저장된 연구 출력으로 실행되며, 크루가 마무리됩니다.

방법 가이드

기본값으로 체크포인팅 활성화

crew = Crew(agents=[...], tasks=[...], checkpoint=True)

task_completed마다 ./.checkpoints/에 씁니다.

저장·빈도 사용자 지정

from crewai import Crew, CheckpointConfig

crew = Crew(
    agents=[...],
    tasks=[...],
    checkpoint=CheckpointConfig(
        location="./my_checkpoints",
        on_events=["task_completed", "crew_kickoff_completed"],
        max_checkpoints=5,
    ),
)

저장 공급자 선택

from crewai import Crew, CheckpointConfig
from crewai.state import JsonProvider

crew = Crew(
    agents=[...],
    tasks=[...],
    checkpoint=CheckpointConfig(
        location="./my_checkpoints",
        provider=JsonProvider(),
        max_checkpoints=5,
    ),
)
from crewai import Crew, CheckpointConfig
from crewai.state import SqliteProvider

crew = Crew(
    agents=[...],
    tasks=[...],
    checkpoint=CheckpointConfig(
        location="./.checkpoints.db",
        provider=SqliteProvider(),
        max_checkpoints=50,
    ),
)
SQLite는 동시 읽기를 위해 WAL 저널 모드를 활성화합니다. 고빈도 체크포인팅에는 SQLite를 선호하세요.

한 에이전트 제외

crew = Crew(
    agents=[
        Agent(role="Researcher", ...),
        Agent(role="Writer", ..., checkpoint=False),
    ],
    tasks=[...],
    checkpoint=True,
)

새 분기로 포크

fork()는 새 lineage 아래에서 체크포인트를 복원해 새 실행이 원본과 충돌하지 않게 합니다.

config = CheckpointConfig(restore_from="./my_checkpoints/<file>.json")
crew = Crew.fork(config, branch="experiment-a")
result = crew.kickoff(inputs={"strategy": "aggressive"})

branch 라벨은 선택 사항이며 생략하면 생성됩니다.

크루·플로우·에이전트 체크포인트

  • Crew: checkpoint=CheckpointConfig(location="./crew_cp") — 기본 트리거 task_completed.
  • Flow: on_events=["method_execution_finished"]로 스텝 실행 후 체크포인트.
  • Agent: on_events=["lite_agent_execution_completed"]로 에이전트 실행 완료 후 체크포인트.

수동 체크포인트 쓰기

이벤트에 핸들러를 등록하고 state.checkpoint()를 호출합니다:

from __future__ import annotations

from typing import TYPE_CHECKING, Any

from crewai.events.event_bus import crewai_event_bus
from crewai.events.types.llm_events import LLMCallCompletedEvent

if TYPE_CHECKING:
    from crewai.state.runtime import RuntimeState


@crewai_event_bus.on(LLMCallCompletedEvent)
def on_llm_done(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
    path = state.checkpoint("./my_checkpoints")
    print(f"Saved checkpoint: {path}")

비동기 버전은 state.acheckpoint("./my_checkpoints")를 사용합니다. 핸들러가 세 파라미터를 받으면 state 인자가 자동 공급됩니다.

CLI로 체크포인트를 보고·재개·포크

crewai checkpoint
crewai checkpoint --location ./my_checkpoints
crewai checkpoint --location ./.checkpoints.db

TUI 왼쪽 패널은 분기별로 체크포인트를 그룹화하고 fork는 부모 아래 중첩됩니다. 체크포인트를 선택하면 메타데이터·엔티티 상태·태스크 진행이 있는 상세 패널이 열립니다. Resume은 실행을 계속하고 Fork는 새 분기를 시작합니다. 상세 패널은 두 가지 편집 가능 영역을 노출합니다: Inputs(원래 킥오프 입력, 미리 채워져 편집 가능)와 Task outputs(완료 태스크의 출력 — 출력을 편집하고 Fork를 누르면 후속 태스크가 무효화되어 수정된 컨텍스트로 다시 실행).

TUI 없이 체크포인트 검사

crewai checkpoint list ./my_checkpoints
crewai checkpoint info ./my_checkpoints/<file>.json
crewai checkpoint info ./.checkpoints.db

레퍼런스

CheckpointConfig

  • location (str, 기본 .checkpoints): 저장 대상. JsonProvider는 디렉터리, SqliteProvider는 DB 파일 경로.
  • on_events (list[CheckpointEventType | Literal["*"]], 기본 ["task_completed"]): 체크포인트를 트리거하는 이벤트 유형. CheckpointEventTypeLiteral이라 타입 체커가 자동완성·거부합니다.
  • provider (BaseProvider, 기본 JsonProvider()): 저장 백엔드. JsonProvider 또는 SqliteProvider.
  • max_checkpoints (int | None, 기본 None): 유지할 최대 체크포인트 수. 쓰기 후 오래된 것부터 정리.
  • restore_from (Path | str | None, 기본 None): from_checkpoint으로 전달 시 복원할 체크포인트.

checkpoint 필드 값

Crew, Flow, Agent가 받습니다: None=부모에게 상속, True=기본값으로 활성화, False=명시적 탈퇴(상속 중단), CheckpointConfig(...)=사용자 정의 설정.

이벤트 유형

on_eventsCheckpointEventType 값의 조합을 받습니다. 기본 ["task_completed"]는 완료된 태스크마다 체크포인트 하나, ["*"]는 모든 이벤트와 일치합니다.

`["*"]`와 `llm_call_completed` 같은 고빈도 이벤트는 많은 체크포인트를 써 성능을 저하시킬 수 있습니다. `max_checkpoints`와 함께 사용하세요.

지원 이벤트(일부): Tasktask_started, task_completed, task_failed, task_evaluation; Crewcrew_kickoff_started, crew_kickoff_completed, crew_kickoff_failed 등; Agentagent_execution_started, agent_execution_completed, agent_execution_error 등; Flowflow_started, flow_finished, method_execution_started, method_execution_finished, human_feedback_requested 등; LLMllm_call_started, llm_call_completed, llm_call_failed, llm_stream_chunk, llm_thinking_chunk; Tooltool_usage_started, tool_usage_finished, tool_usage_error 등; Memory, Knowledge, Reasoning, MCP, Observation, Skill, Logging, A2A, System signals(SIGTERM, SIGINT, SIGHUP, SIGTSTP, SIGCONT), Wildcard("*").

저장 공급자

  • JsonProvider: 체크포인트마다 파일 하나, location 안에 <timestamp>_<uuid>.json 이름.
  • SqliteProvider: location에 WAL 저널링 단일 DB 파일.

CLI

명령 용도
crewai checkpoint TUI 실행; 저장 자동 감지
crewai checkpoint --location <path> 특정 위치에 대해 TUI 실행
crewai checkpoint list <path> 체크포인트 목록
crewai checkpoint info <path> 체크포인트 파일 또는 SQLite DB의 최신 항목 검사

더 알아보기