DOCS/journey/plans/251126_intent_3step_architecture_plan.md

10 KiB

의도 파악 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):

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 구현 시작