DOCS/journey/plans/archive/260121_coldmail_checkpoint_interrupt_fix.md
Claude-51124 724ed609b2 docs: 콜드메일 interrupt 상태 보존 문제 해결 문서 추가
- troubleshooting: 노드 분리 설계로 interrupt 상태 보존 문제 해결
- plans/archive: 완료된 계획 문서 이동
2026-01-21 09:27:02 +09:00

2.5 KiB

콜드메일 워크플로우 interrupt() 패턴 수정 계획

작성일: 2026-01-21 완료일: 2026-01-21 관련 파일: rb8001/app/services/workflows/coldmail_workflow.py, rb8001/app/services/slack/coldmail_service.py

구현 완료: troubleshooting/260121_coldmail_interrupt_state_preservation_fix.md


문제 상황

  • process_node에서 interrupt() 호출 후에도 워크플로우가 send_node까지 진행 완료
  • waiting_confirmation이 비워진 상태로 checkpoint 저장
  • 사용자가 Slack 버튼 클릭 시 Email not found in waiting_confirmation 에러 발생

근본 원인: interrupt() 반환값을 사용하지 않고, 별도 라우팅으로 confirm_node 분기 시도

히스토리:

  • 2025-12-23: interrupt_after=["process"] 사용 → process 노드 완료 후 중단 시도
  • 2026-01-18: LangGraph 1.0 업그레이드 시 interrupt() 동적 호출로 변경
  • 누락된 부분: decision = interrupt(payload)decision으로 분기하는 패턴 미적용

아키텍처

현재 (잘못된 패턴)

process_node → interrupt() 호출 → 워크플로우 계속 진행 → send_node → END
                                   ↑ waiting_confirmation 비워짐

수정 후 (올바른 패턴)

process_node → interrupt(payload) → 워크플로우 일시정지
                    ↓
              사용자 버튼 클릭
                    ↓
              Command(resume={"confirmed": True, "email_id": ...})
                    ↓
              interrupt() 반환값으로 결과 수신 → 후속 처리

필요 작업

Phase 1: process_node 수정

  • coldmail_workflow.py:106-157: interrupt() 반환값 패턴 적용
    • decision = interrupt({"emails": waiting_confirmation}) 형태로 변경
    • decision에서 confirmed_email_id 추출하여 처리
    • interrupt() 이후 코드가 재개 시점에 실행되도록 구조 변경

Phase 2: coldmail_service.py 수정

  • coldmail_service.py:160: Command(resume=...) 호출 시 사용자 입력 전달
    • Command(resume={"confirmed": True, "email_id": email_id}) 형태로 변경

Phase 3: confirm_node 제거 또는 통합

  • route_after_process 분기 로직 제거
  • confirm_node 로직을 process_node 내부로 통합 (interrupt 반환값 처리)

검증 방법

  • 신뢰도 95% 미만 이메일 → Slack 버튼 전송 확인
  • 버튼 클릭 후 Command(resume=...) → 워크플로우 재개 확인
  • waiting_confirmation 상태 유지 및 정상 처리 확인