diff --git a/journey/plans/251017_intent_analysis_improvement_plan.md b/journey/plans/251017_intent_analysis_improvement_plan.md index c786e63..df1346e 100644 --- a/journey/plans/251017_intent_analysis_improvement_plan.md +++ b/journey/plans/251017_intent_analysis_improvement_plan.md @@ -488,3 +488,12 @@ test_cases = [ **작성 완료**: 2025-10-17 **권장 다음 액션**: Phase 1 구현 시작 (2주 스프린트) **검토 필요**: 임베딩 모델 선택, 의도 설명 초안 + +--- + +## 10. 관련 문서 + +- **[의도 파악 3단계 아키텍처 전환 계획](./251126_intent_3step_architecture_plan.md)** (2025-11-26) + - 의도 파악 → 행동 계획 → 스킬 선택의 3단계 구조 설계 + - LLM 기반 제로샷 의도 분석으로 무한한 의도 처리 가능 + - TDD 시나리오 및 구현 계획 포함 diff --git a/journey/plans/251126_intent_3step_architecture_plan.md b/journey/plans/251126_intent_3step_architecture_plan.md new file mode 100644 index 0000000..dcea6e3 --- /dev/null +++ b/journey/plans/251126_intent_3step_architecture_plan.md @@ -0,0 +1,300 @@ +# 의도 파악 3단계 아키텍처 전환 계획 + +**작성일**: 2025-11-26 +**작성자**: Auto (Claude) +**상태**: 계획 단계 +**관련 문서**: +- `251017_intent_analysis_improvement_plan.md` - 의도 분석 개선 플랜 +- `251023_happybell80_의도_런타임_하이브리드_임베딩_베이지안_동적학습.md` - 의도 런타임 설계 +- `311_FastAPI_구조_원칙.md` - 코드 작성 원칙 + +--- + +## 1. 문제 발견 + +### 1.1 현재 구조의 근본적 문제 + +**발견된 문제**: +- IntentType이 스킬/액션과 직접 1:1 매핑되어 있음 +- 의도 파악이 곧 스킬 선택으로 이어지는 구조 +- 진정한 "의도 파악(무엇을 원하는가)" → "행동 계획(어떻게 할 것인가)" → "스킬 선택(어떤 도구를 쓸 것인가)"의 단계적 분리가 없음 + +**실제 문제 사례**: +``` +사용자: "12월 10일 11시 종합운동장에서 뵙겠습니다. 준비물: 노트북,휴대폰 일정등록" +로빙: "네, 종합운동장 미팅 일정을 12월 10일 11시에 등록해 드릴게요. 구글 캘린더에 등록해드릴까요?" +사용자: "그래" +로빙: "안녕하세요! 무엇을 도와드릴까요? 😊" # ❌ 일반 인사로 돌아감 +``` + +**원인 분석**: +- "구글 캘린더에 등록해드릴까요?" 응답이 `calendar_event` intent로 저장됨 +- "그래" 같은 동의 메시지가 `_confirm`으로 끝나는 intent를 찾지 못함 +- `calendar_event`는 approval 대상이 아니어서 `calendar_approval`로 변환되지 않음 + +### 1.2 아키텍처 구조적 문제 + +**현재 구조**: +``` +IntentType (스킬/액션과 직접 매핑) + ↓ +decide_skill_sequence() → 스킬 선택 +``` + +**문제점**: +- 의도 파악이 스킬 선택에 가까움 +- 새로운 의도 추가 시 스킬도 함께 정의해야 함 +- 의도와 구현이 강하게 결합됨 + +--- + +## 2. 개선 방향 + +### 2.1 3단계 구조 설계 + +**목표**: 의도 파악 → 행동 계획 → 스킬 선택의 단계적 접근 + +``` +1단계: 의도 파악 (IntentAnalyzer) + - 추상적 목표 파악 (일정 관리, 정보 검색, 커뮤니케이션 등) + - LLM 기반 제로샷 의도 분석 (무한한 의도 처리 가능) + - 사용자가 무엇을 원하는지 추상적 수준에서 이해 + +2단계: 행동 계획 (ActionPlanner) + - 구체적 행동 결정 (등록/조회/삭제/수정 등) + - 의도를 달성하기 위한 구체적 행동 계획 + - 여러 행동이 필요한 경우 순서 및 우선순위 결정 + +3단계: 스킬 선택 (SkillSelector) + - 적절한 도구 선택 (calendar_skill.create_event 등) + - 행동을 수행할 적절한 스킬 선택 + - 스킬 실행 가능 여부 확인 +``` + +### 2.2 3단계 구조의 장점 + +- **의도와 구현의 분리**: 같은 의도라도 다른 행동/스킬로 구현 가능 +- **확장성**: 새로운 스킬 추가 시 기존 의도 재사용 가능 +- **유연성**: 행동 계획 단계에서 여러 대안 고려 가능 +- **명확성**: 각 단계의 책임이 명확히 분리됨 +- **무한한 의도 처리**: LLM 기반으로 아직 구현되지 않은 의도도 파악 가능 + +--- + +## 3. 구현 계획 + +### 3.1 폴더 구조 + +``` +app/services/brain/ +├── intent/ # 신규 폴더 +│ ├── __init__.py +│ ├── schemas.py # IntentGoal, ActionPlan, SkillSequence +│ ├── intent_analyzer.py # 1단계: 의도 파악 +│ ├── action_planner.py # 2단계: 행동 계획 +│ ├── skill_selector.py # 3단계: 스킬 선택 +│ ├── intent_graph.py # 기존 파일 이동 +│ └── semantic_classifier.py # 기존 파일 이동 +├── decision_engine.py # 래퍼로 유지 (하위 호환성) +├── brain_service.py # 3단계 파이프라인 호출 +└── ... +``` + +### 3.2 데이터 구조 정의 + +**Pydantic 모델** (`app/services/brain/intent/schemas.py`): + +```python +from pydantic import BaseModel +from typing import Optional, List, Dict, Any +from enum import Enum + +class IntentCategory(str, Enum): + """추상적 의도 카테고리""" + SCHEDULE_MANAGEMENT = "schedule_management" # 일정 관리 + INFORMATION_RETRIEVAL = "information_retrieval" # 정보 검색 + COMMUNICATION = "communication" # 커뮤니케이션 + DOCUMENT_PROCESSING = "document_processing" # 문서 처리 + TASK_EXECUTION = "task_execution" # 작업 실행 + GENERAL_INQUIRY = "general_inquiry" # 일반 질의 + UNKNOWN = "unknown" + +class IntentGoal(BaseModel): + """1단계: 의도 파악 결과""" + category: IntentCategory # 추상적 카테고리 + description: str # LLM이 파악한 의도 설명 + confidence: float # 신뢰도 (0.0 ~ 1.0) + raw_intent: Optional[str] = None # LLM 원본 출력 (디버깅용) + context_hints: Dict[str, Any] = {} # 컨텍스트 힌트 + +class ActionType(str, Enum): + """구체적 행동 타입""" + CREATE_EVENT = "create_event" + QUERY_EVENTS = "query_events" + DELETE_EVENT = "delete_event" + UPDATE_EVENT = "update_event" + SEARCH_WEB = "search_web" + SEARCH_MEMORY = "search_memory" + SEND_EMAIL = "send_email" + READ_EMAIL = "read_email" + ANALYZE_DOCUMENT = "analyze_document" + CLARIFY = "clarify" + CHAT = "chat" + +class ActionPlan(BaseModel): + """2단계: 행동 계획 결과""" + actions: List[Dict[str, Any]] # 행동 목록 + requires_clarification: bool = False + clarification_message: Optional[str] = None + +class SkillSequence(BaseModel): + """3단계: 스킬 선택 결과 (기존 execution_plan과 호환)""" + skills: List[Dict[str, Any]] # 스킬 목록 + intent: Dict[str, Any] # 원본 의도 정보 (하위 호환성) +``` + +### 3.3 데이터 흐름 + +``` +IntentAnalyzer.analyze() → IntentGoal + ↓ +ActionPlanner.plan(IntentGoal) → ActionPlan + ↓ +SkillSelector.select(ActionPlan) → SkillSequence + ↓ +기존 execution_plan 형식으로 변환 (하위 호환성) +``` + +### 3.4 하위 호환성 유지 + +**기존 DecisionEngine 클래스는 래퍼로 유지**: +- 내부적으로 3단계 파이프라인 호출 +- 기존 API 인터페이스 유지 +- 점진적 마이그레이션 가능 + +--- + +## 4. TDD 시나리오 + +### 시나리오 1: 일정 등록 동의 처리 (현재 문제 해결) +``` +사용자: "12월 10일 11시 종합운동장에서 뵙겠습니다. 준비물: 노트북,휴대폰 일정등록" +로빙: "네, 종합운동장 미팅 일정을 12월 10일 11시에 등록해 드릴게요. 구글 캘린더에 등록해드릴까요?" +사용자: "그래" +→ IntentGoal: {category: SCHEDULE_MANAGEMENT, description: "일정 등록 승인"} +→ ActionPlan: {actions: [{type: CREATE_EVENT, goal: "구글 캘린더에 일정 등록"}]} +→ SkillSequence: {skills: [{skill: "CALENDAR", action: "create_event"}]} +→ 성공: 일정 등록 완료 +``` + +### 시나리오 2: 아직 구현되지 않은 의도 처리 +``` +사용자: "내일 오후 2시 회의실 예약해줘" +→ IntentGoal: {category: SCHEDULE_MANAGEMENT, description: "회의실 예약 요청"} +→ ActionPlan: {actions: [{type: CREATE_EVENT, goal: "회의실 예약"}]} +→ SkillSelector: 회의실 예약 스킬 없음 감지 +→ 로빙: "죄송합니다. 회의실 예약 기능은 아직 준비 중입니다. 구글 캘린더에 일정만 등록해드릴까요?" +``` + +### 시나리오 3: 복합 의도 처리 +``` +사용자: "리버스마운틴 유사 기업 찾아서 가치평가 보고서 이메일로 보내줘" +→ IntentGoal: {category: INFORMATION_RETRIEVAL, description: "기업 검색 및 분석 후 이메일 발송"} +→ ActionPlan: {actions: [ + {type: SEARCH_WEB, goal: "리버스마운틴 유사 기업 검색", priority: 1}, + {type: ANALYZE_DOCUMENT, goal: "가치평가 분석", priority: 2}, + {type: SEND_EMAIL, goal: "보고서 이메일 발송", priority: 3} +]} +→ SkillSequence: {skills: [ + {skill: "TOOL", action: "web_search"}, + {skill: "LLM", action: "analyze"}, + {skill: "EMAIL", action: "compose"} +]} +``` + +### 시나리오 4: 맥락 기반 의도 파악 +``` +사용자: "아까 말한 그 기업 투자 단계는?" +→ IntentGoal: {category: INFORMATION_RETRIEVAL, description: "이전 대화에서 언급된 기업의 투자 단계 조회", context_hints: {reference: "previous_conversation"}} +→ ActionPlan: {actions: [{type: SEARCH_MEMORY, goal: "이전 대화에서 기업 정보 검색"}]} +→ SkillSequence: {skills: [{skill: "LLM", action: "search_memory"}]} +→ 성공: ChromaDB에서 관련 대화 검색 후 답변 +``` + +### 시나리오 5: 모호한 의도 명확화 +``` +사용자: "이메일 보내줘" +→ IntentGoal: {category: COMMUNICATION, description: "이메일 발송 요청", confidence: 0.6} +→ ActionPlan: { + requires_clarification: True, + clarification_message: "누구에게 보내실까요? 어떤 내용을 보내실까요?" +} +→ SkillSequence: {skills: []} +→ 로빙: "누구에게 보내실까요? 어떤 내용을 보내실까요?" +``` + +--- + +## 5. 수정 범위 + +### 5.1 수정 필요한 부분 + +**백엔드 (rb8001)**: +- `app/services/brain/decision_engine.py` → 3단계 파이프라인으로 재구성 +- `app/services/brain/intent/` 폴더 신규 생성 +- `app/services/brain/brain_service.py` → 3단계 파이프라인 호출 + +### 5.2 수정 불필요한 부분 + +- **Gateway (robeing-gateway)**: 변경 불필요, JWT 검증/프록시 역할 유지 +- **프론트엔드**: 변경 불필요, API 인터페이스 동일 +- **DB 스키마**: 변경 불필요, 의도/행동 계획은 런타임 처리 + +--- + +## 6. 구현 순서 + +### Phase 1: 구조 설계 및 스키마 정의 (1일) +1. `app/services/brain/intent/` 폴더 생성 +2. `schemas.py` 작성 (IntentGoal, ActionPlan, SkillSequence) +3. 기존 파일 이동 (intent_graph.py, semantic_classifier.py) + +### Phase 2: IntentAnalyzer 구현 (2일) +1. LLM 기반 제로샷 의도 분석 +2. IntentCategory 분류 +3. TDD 테스트 작성 + +### Phase 3: ActionPlanner 구현 (2일) +1. IntentGoal → ActionPlan 변환 로직 +2. 복합 행동 처리 +3. Clarify 로직 + +### Phase 4: SkillSelector 구현 (2일) +1. ActionPlan → SkillSequence 변환 +2. 기존 execution_plan 형식으로 변환 +3. 하위 호환성 유지 + +### Phase 5: 통합 및 테스트 (2일) +1. DecisionEngine 래퍼 구현 +2. 기존 테스트 통과 확인 +3. TDD 시나리오 검증 + +--- + +## 7. 참고 사항 + +### 7.1 코드 작성 원칙 준수 +- 계층 분리: router → services → state +- 파일 크기: 한 파일 최대 300줄 +- 의존성 방향: 단방향 흐름 + +### 7.2 하위 호환성 +- 기존 DecisionEngine API 유지 +- 기존 execution_plan 형식 유지 +- 점진적 마이그레이션 가능 + +--- + +**작성 완료**: 2025-11-26 +**다음 단계**: Phase 1 구현 시작 +