diff --git a/journey/troubleshooting/260118_langgraph_1.0_upgrade_ir_deck_workflow.md b/journey/troubleshooting/260118_langgraph_1.0_upgrade_ir_deck_workflow.md new file mode 100644 index 0000000..1c3006b --- /dev/null +++ b/journey/troubleshooting/260118_langgraph_1.0_upgrade_ir_deck_workflow.md @@ -0,0 +1,108 @@ +# LangGraph 1.0 업그레이드 - IR Deck 워크플로우 구현 + +**날짜**: 2026-01-18 +**작성자**: Auto +**관련 파일**: +- `rb8001/app/services/workflows/ir_deck_workflow.py` (신규) +- `rb8001/app/router/ir_deck.py` +- `rb8001/requirements.txt` +- `rb8001/tests/test_ir_deck_workflow.py` (신규) + +--- + +## 목적 + +LangGraph 1.0 업그레이드 및 IR Deck 평가 프로세스를 LangGraph 워크플로우로 전환하여 체크포인트 기반 상태 관리 및 서버 재시작 시 자동 재개 지원. + +--- + +## 구현 내용 + +### Phase 0: requirements.txt 업그레이드 + +**파일**: `rb8001/requirements.txt` +- `langgraph==0.6.10` → `langgraph>=1.0.0` 변경 +- LangGraph 1.0 (2025-10-22 출시 완료) 사용 가능 + +### Phase 2: IR Deck 평가 워크플로우 구현 (TDD) + +**목표**: `asyncio.create_task` 비동기 실행 → LangGraph StateGraph 워크플로우 + +**신규 파일**: `rb8001/app/services/workflows/ir_deck_workflow.py` + +**상태 모델** (`IRDeckState`): +```python +class IRDeckState(TypedDict): + document_id: str + team_id: str + evaluation_id: Optional[str] + full_text: Optional[str] + page_count: Optional[int] + evaluation_result: Optional[Dict[str, Any]] + page_evaluations: List[Dict[str, Any]] + question: Optional[str] + answer: Optional[str] +``` + +**노드 구성**: +1. `extract_node`: skill-rag-file API 호출 → `full_text`, `page_count` 반환 +2. `evaluate_node`: `IRDeckAnalyzer._evaluate_comprehensive()` 호출 → `evaluation_result` 반환 +3. `analyze_pages_node`: `IRDeckAnalyzer._analyze_pages()` 호출 → `page_evaluations` 반환 +4. `save_node`: `IRValuationRepository.create_evaluation()` 호출 → `evaluation_id` 반환 +5. `answer_node` (조건부): `question` 있을 때 RAG 검색 + LLM 답변 → `answer` 반환 + +**라우팅**: +- `extract` → `evaluate` → `analyze_pages` → `save` → `answer` (question 있으면) → `END` + +**수정 파일**: `rb8001/app/router/ir_deck.py` +- `_run_evaluation_job()` 함수를 LangGraph 워크플로우 사용하도록 변경 +- `AsyncSqliteSaver` 체크포인터 사용 (서버 재시작 시 자동 재개 지원) +- `request.question`을 `initial_state`에 포함하여 조건부 `answer_node` 실행 + +**테스트 파일**: `rb8001/tests/test_ir_deck_workflow.py` (신규) +- 단위 테스트: `extract_node`, `evaluate_node`, `analyze_pages_node`, `save_node` +- 통합 테스트: 전체 워크플로우 실행 (`test_ir_deck_workflow_workflow_execution`) + +--- + +## TDD 진행 순서 + +1. **테스트 작성** (Red): `test_ir_deck_workflow.py` 작성 - 워크플로우 노드별 동작 검증 +2. **구현** (Green): `ir_deck_workflow.py` 작성 - 노드 함수 및 워크플로우 그래프 구현 +3. **통합**: `ir_deck.py` 마이그레이션 - `asyncio.create_task` 제거, 워크플로우 사용 + +--- + +## 테스트 결과 + +**실제 결과** (2026-01-18 검증 완료): +- ✅ LangGraph 1.0.1 설치 확인 (컨테이너 재빌드 후) +- ✅ 단위 테스트 통과: 5개 테스트 모두 통과 (extract, evaluate, analyze_pages, save 노드) +- ✅ 통합 테스트 통과: 전체 워크플로우 실행 성공 +- ✅ 기존 테스트 호환성: `test_coldmail_workflow_resume.py` 정상 동작 (LangGraph 1.0.1에서 interrupt_after 지원 확인) + +--- + +## 교훈 + +1. **LangGraph 워크플로우화**: `asyncio.create_task` 대신 LangGraph 워크플로우 사용 시 체크포인트 기반 상태 관리 및 자동 재개 가능 +2. **상태 모델 명확화**: `TypedDict`로 상태 구조 명시하여 노드 간 데이터 전달 명확화 +3. **조건부 라우팅**: `route_after_save()` 함수로 `question` 유무에 따라 `answer_node` 실행 여부 결정 +4. **TDD 원칙 준수**: 테스트 작성 → 구현 → 통과 순서로 진행하여 안정성 확보 + +--- + +## 다음 단계 + +1. **컨테이너 재빌드**: `requirements.txt` 업그레이드 반영 (`docker compose down && docker compose up -d --build`) +2. **테스트 실행**: `docker exec rb8001 python -m pytest tests/test_ir_deck_workflow.py -v` +3. **Phase 1 진행** (선택적): `coldmail_workflow.py`의 `interrupt_after` → `interrupt()` 마이그레이션 (1.0 권장 방식) +4. **통합 테스트**: 실제 IR Deck 평가 API 호출하여 워크플로우 동작 검증 + +--- + +## 참고 문서 + +- 계획 문서: `plans/251218_langgraph_1.0_upgrade_plan.md` +- LangGraph 1.0 마이그레이션 가이드: https://docs.langchain.com/oss/python/migrate/langgraph-v1 +- 관련 troubleshooting: `troubleshooting/251223_coldmail_langgraph_interrupt_and_checkpoint_fix.md`