# rb8001 의도 3단계 아키텍처 도입 및 배포

**날짜**: 2025-11-26  
**작성자**: happybell80  
**관련 파일**: `rb8001/app/services/brain/intent/schemas.py`, `rb8001/app/services/brain/intent/action_planner.py`, `rb8001/app/services/brain/intent/skill_selector.py`, `rb8001/app/services/brain/decision_engine.py:540`

---

## 문제 상황
- 의도 파악/행동 계획/스킬 선택이 `DecisionEngine` 내부에서 뒤섞여 있어, 캘린더 승인 시나리오 등 복잡한 멀티스텝 흐름을 테스트/분석하기 어렵고, 회귀 여부를 execution_plan만으로 확인하기 힘든 상태였다.  
- 의도 3단계 아키텍처 계획(251126_intent_3step_architecture_plan.md)이 문서로만 존재하고, 실제 코드/테스트/배포까지 연결된 단일 작업 흐름이 정리되어 있지 않았다.  
- 실제 컨테이너(포트 8001)에 배포된 rb8001이 이 설계를 얼마나 반영하고 있는지, 그리고 배포 후 `/api/test/router-message` 기준으로 기존 시나리오가 정상 동작하는지에 대한 기록이 없었다.

## 해결 방안
- 의도 3단계 스키마 정의  
  - `rb8001/app/services/brain/intent/schemas.py:7-57`: `IntentCategory`, `IntentGoal`, `ActionType`, `ActionPlan`, `SkillSequence`를 Pydantic 기반으로 정의해, IntentGoal → ActionPlan → SkillSequence 데이터 흐름을 명시적으로 분리했다.  
- ActionPlanner/SkillSelector 구현  
  - `rb8001/app/services/brain/intent/action_planner.py:6-40`: `ActionPlanner.plan()`에서 `IntentGoal`을 입력으로 받아, 일정 승인(`SCHEDULE_MANAGEMENT` + "일정"/"승인")인 경우 `CREATE_EVENT` 액션을 생성하고, 그 외에는 안전한 clarify 액션으로 폴백한다.  
  - `rb8001/app/services/brain/intent/skill_selector.py:6-54`: `SkillSelector.select()`에서 `ActionPlan.actions`를 순회하며 `CREATE_EVENT` → `CALENDAR.create_event`, `SEARCH_WEB` → `TOOL.web_search`, `SEND_EMAIL` → `EMAIL.compose`로 매핑된 `SkillSequence.skills`를 생성한다.  
- DecisionEngine에서 3단계 파이프라인 메타데이터 노출  
  - `rb8001/app/services/brain/decision_engine.py:560-629`: `_build_intent_pipeline()`을 추가해 `IntentType`을 `IntentCategory`/설명 문자열로 매핑하고, `ActionPlanner`와 `SkillSelector`를 호출해 `goal`, `action_plan`, `skill_sequence`를 생성한다.  
  - `rb8001/app/services/brain/decision_engine.py:631-677`: `create_execution_plan()`에서 기존 fast-path(`analyze_intent` + `decide_skill_sequence`) 결과는 그대로 사용하면서, 추가 필드 `intent_pipeline`에 3단계 결과를 메타데이터로만 포함하도록 했다(실제 실행 스킬은 기존 로직 유지).  
- TDD 및 실제 서비스 테스트  
  - `rb8001/tests/test_intent_3step_architecture.py`:  
    - `IntentGoal(SCHEDULE_MANAGEMENT, "일정 등록 승인")` → `ActionPlanner.plan()` → `CREATE_EVENT` 액션이 생성되는지 검증.  
    - `ActionPlan(actions=[CREATE_EVENT])` → `SkillSelector.select()` → `CALENDAR.create_event` 스킬이 생성되는지 검증.  
    - `DecisionEngine.create_execution_plan("그래", calendar_confirm 컨텍스트)` 결과에서 `intent.type == "calendar_approval"` 이면서 `intent_pipeline.goal.category == "schedule_management"`, `intent_pipeline.action_plan.actions`에 `create_event`가 포함되고, `intent_pipeline.skill_sequence.skills[0]`가 `CALENDAR.create_event`인지 검증.  
  - `python3 -m pytest tests/test_intent_3step_architecture.py -vv`: 로컬 컨테이너 기준 3개 테스트 모두 통과 확인.  
  - `git push origin main` 후 Gitea Actions 자동 배포 → 약 1분 내 `docker ps | grep rb8001`에서 `CREATED` 타임스탬프가 갱신되고 `STATUS`가 `Up xx seconds (healthy)`로 변경된 것 확인.  
  - 실제 컨테이너에서 `curl http://localhost:8001/api/test/health`로 테스트 엔드포인트 헬스체크, `curl http://localhost:8001/api/test/router-message`로 메시지 라우팅 플로우가 200/`status: success`를 반환하는지 확인.  

## 구현 완료
- 커밋: `a4738b9 feat: add 3-step intent pipeline metadata` (rb8001)  
- 배포: Gitea Actions → 51124 서버 SSH → `docker compose down && docker compose up -d --build` 자동 실행, `docker ps`로 신규 컨테이너 생성 및 healthy 상태 직접 확인.  

## 교훈
- 의도/행동/스킬을 한 파일(DecisionEngine) 안에서 절차적으로만 다루면, 멀티스텝 시나리오(일정 등록 → 확인 → 승인)를 테스트와 로그에서 명확히 추적하기 어렵고, 회귀 여부 판단도 힘들다. 3단계 스키마를 분리하고 execution_plan에 `intent_pipeline`을 노출하면, TDD와 실서비스 로그 분석 모두에서 동일한 구조를 재사용할 수 있다.  
- 새 아키텍처를 도입할 때는 기존 fast-path를 가능한 한 건드리지 않고, 먼저 메타데이터 형태로 붙여 관찰 가능성을 높인 뒤, 충분한 테스트/로그 기반 검증 후에 실제 실행 경로를 점진적으로 전환하는 것이 안전하다. 이번 단계에서는 CALENDAR_APPROVAL 시나리오에 대한 3단계 파이프라인만 메타데이터로 도입했다.  
- `/api/test/router-message` 실제 호출 시, approval 로직은 `conversation_log` 기반 `recent_conversations`에 의존하고 user_id는 UUID여야만 정상 동작한다. 테스트 시에도 UUID와 실제 DB 컨텍스트를 사용하는지 확인하고, approval/clarify와 같이 컨텍스트 의존적인 로직은 TDD(테스트 코드) + 실제 curl 시나리오를 둘 다 작성해두는 것이 좋다.

