# 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`
