콘텐츠로 이동

인풋 ID 지원중단 (Inputs ID Deprecation)

@persist로 표시한 플로우를 이전 실행에서 이어서 시작하는 공식적인 방법은, 그 실행의 UUID를 inputs.id로 넘기는 거였어요. 그런데 CrewAI가 이 이어받기를 전담하는 별도 필드 restore_from_state_id를 새로 내놓았습니다. 같은 역할을 하면서도 inputs 페이로드를 과하게 쓰지 않고, 이어받기 키가 새 실행의 정체성과 묶이지 않도록 해 주죠.

마이그레이션 (Migration)

지금 @persist 플로우를 inputs={"id": ...}로 시작하고 있다면, 이렇게 바꾸면 됩니다.

# 지원중단 (deprecated)
flow.kickoff(inputs={"id": "abcd1234-5678-90ef-ghij-klmnopqrstuv"})

# 권장 (supported)
flow.kickoff(
    inputs={},  # 이어받기와 무관한 실제 소비 값만
    restore_from_state_id="abcd1234-5678-90ef-ghij-klmnopqrstuv"
)

두 방식의 계보(lineage) 의미는 서로 달라요.

  • inputs={"id": <uuid>} (지원중단) — resume: 해당 id 아래에 기록이 쌓이며, 같은 flow_uuid 히스토리를 이어갑니다.
  • restore_from_state_id=<uuid>fork: 스냅샷에서 상태를 복원한 뒤, 새로운 state.id 아래에 기록합니다. 원본 플로우의 히스토리는 그대로 보존됩니다.

대부분의 운영 시나리오, 다시 말해 이전 상태를 바탕으로 플로우를 다시 돌리는 경우에는 fork가 원하는 동작이에요. 전체 모델은 Mastering Flow State 가이드에서 확인할 수 있습니다. 플로우를 CrewAI AMP REST API로 시작한다면 아래 AMP 절의 페이로드 마이그레이션을 참고하세요.

@persist에서 inputs.id를 지원중단하나요

inputs.id가 여태까지 @persist 플로우를 이어받는 공식 방법이긴 했어요. 문제는 같은 UUID가 두 가지 일을 동시에 한다는 점입니다.

  1. 어느 스냅샷에서 @persist가 상태를 복원할지를 고른다 — 해당 UUID 아래 저장된 상태를 불러옵니다.
  2. 그 UUID가 새 실행의 Flow Execution ID가 된다 — SDK에서는 state.id, 어떤 맥락에서는 flow_id로 표면화됩니다. 이번 kickoff의 모든 @persist 기록도 같은 UUID 아래에 쌓이죠.

이 이중 역할이 바로 이 가이드가 설명하는 문제의 근본 원인입니다. 넘겨준 UUID가 곧 새 실행의 id이기 때문에, 같은 inputs.id를 넘기는 두 번의 kickoff는 서로 다른 두 실행이 아닙니다. id를 공유하고, 영속 기록을 공유하고, AMP에서는 실행 목록의 한 행까지 공유해요. "이 스냅샷에서 복원하되, 이번 실행은 따로 기록해 줘"라고 말할 방법이 없으니 두 책임을 분리하지 못하는 거죠. restore_from_state_id가 바로 그 분리입니다. 어느 스냅샷에서 복원할지만 @persist에 알려주고, 새 실행은 자유롭게 새로운 state.id를 받게 해요. 복원 출처와 기록된 실행이 더 이상 같은 UUID가 아니게 되는데, 대부분의 운영 시나리오가 원하는 게 바로 이것입니다.

제거 일정 (Removal timeline)

@persist 하이드레이션용 inputs.id는 CrewAI의 향후 릴리스에서 제거될 예정입니다. 당장 하드 컷오프는 없어서 기존 플로우는 계속 동작해요. 다만 v1.14.5 이상으로 업그레이드한 뒤에는 새 코드에서 restore_from_state_id를 쓰고, 기존 플로우도 다음 기회에 마이그레이션하는 게 좋습니다.

AMP

플로우를 CrewAI AMP에 배포했다면 배포된 크루로 보내는 kickoff 페이로드로 마이그레이션이 이어집니다. inputs.id를 재사용할 때 나타나는 증상도 배포 대시보드에서 드러나죠. 아래 두 절에서 둘 다 다룹니다. 지금 배포된 플로우를 inputsid를 넣어 시작하고 있다면, UUID를 최상위 restoreFromStateId 필드로 옮기면 됩니다.

```bash theme={null}

지원중단 (Deprecated)

curl -X POST \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_CREW_TOKEN" \ -d '{"inputs": {"id": "abcd1234-5678-90ef-ghij-klmnopqrstuv", "topic": "AI Agent Frameworks"}}' \ https://your-crew-url.crewai.com/kickoff

```bash theme={null}
# 권장 (Supported)
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_CREW_TOKEN" \
  -d '{
        "inputs": {"topic": "AI Agent Frameworks"},
        "restoreFromStateId": "abcd1234-5678-90ef-ghij-klmnopqrstuv"
      }' \
  https://your-crew-url.crewai.com/kickoff

restoreFromStateId는 kickoff 페이로드에서 inputs 옆에 있지, 그 안에 있지 않아요. inputs 객체는 이제 플로우가 실제로 소비하는 값만 담죠.

inputs.id를 재사용하면 벌어지는 일

AMP가 이미 존재하는 실행의 inputs.id와 일치하는 kickoff를 받으면, 새 실행을 만들지 않고 기존 기록으로 귀결시킵니다. 배포 대시보드에서는 이렇게 보입니다.

  • 실행 상태 (Execution status) — 새 실행의 상태가 이전 실행의 상태를 덮어써요. 끝난 실행이 running으로 되돌아가거나, 새 kickoff가 실패하면 completed 실행이 error로 바뀔 수 있어요. 어느 쪽이든 대시보드는 더 이상 원래 실행을 반영하지 않습니다.
  • 트레이스 (Traces) — 같은 실행 id를 공유하므로 OTel 트레이스가 kickoff를 넘어 쌓여요. 이전 실행의 트레이스가 새 실행의 것으로 대체되거나 섞입니다. 단계별 리플레이가 더 이상 단일 실행에 대응하지 않죠.
  • 실행 목록 (Executions list) — 별도 행으로 나타나야 할 kickoff들이 한 항목으로 합쳐져서 히스토리가 숨겨집니다.

restoreFromStateId로 마이그레이션하면 모든 kickoff가 저마다의 실행 상태, 트레이스, 목록의 행을 가지면서도 여전히 이전 실행에서 상태를 복원합니다. 이전 실행의 상태는 유지한 채 각 실행을 독립적으로 기록하고 싶을 때, 이것이 바로 그 해법이에요.

실무 관점 (Practical perspective)

이 마이그레이션의 핵심은 "복원의 근원"과 "기록되는 실행"을 분리한다는 데 있어요. 이전에는 inputs.id 하나가 스냅샷 선택과 실행 id를 동시에 담당했기 때문에, 같은 id로 두 번 돌리면 서로 다른 실행이 되는 게 아니라 같은 실행이 두 번 이어지는 불상사가 생겼죠. 특히 AMP 운영에서는 대시보드의 상태·트레이스·목록이 전부 꼬이기 때문에, 재실행이 잦은 플로우일수록 restore_from_state_id로 옮기는 걸 미루지 않는 게 좋습니다. 다만 제거에 하드 컷오프가 없으니, 서두르기보다는 v1.14.5 이상으로 올린 뒤 다음 유지보수 주기에 묶어 처리하면 됩니다.

더 알아보기 (Further reading)

  • Mastering Flow State — resume/fork의 전체 사고 모델과 state.id·flow_uuid의 관계
  • CrewAI AMP — 배포된 크루의 kickoff 페이로드 작성