DOCS/journey/research/260317_skill_intent_analysis_research.md
happybell80 60a892e5ab fix: DOCS 내 0_VALUE 참조를 GitHub URL → 로컬 상대경로로 전환, 02_Governance → 20_Governance 수정 #33 #34
SSOT는 로컬 0_VALUE/. GitHub URL은 복사본 참조로 SSOT 원칙 위반.
02_Governance는 존재하지 않는 구 경로로 전부 깨진 링크.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 14:00:21 +09:00

14 KiB

스킬 문서 기반 의도분석 적용 리서치

작성일: 2026-03-17
목적: "스킬 문서가 의도분석에 반영되지 않아 잘못된 스킬로 라우팅된다" 문제를 닫기 위한 상세 리서치


0. 적용 원칙 (확인 사항)

수정 시 다음 원칙을 준수한다.

0.1 Pydantic 사용 (LangGraph보다 우선)

의도분석·스킬 라우팅 파이프라인은 Pydantic으로 스키마가 정의되어 있으며, LangGraph는 선택 경로에만 사용된다.

계층 Pydantic 모델 파일
설정 Settings(BaseSettings) app/core/config.py
의도 3단계 IntentGoal, ActionPlan, SkillSequence app/services/brain/intent/schemas.py
LLM LLMRequest, LLMResponse app/services/llm/models.py
Brain BrainRequest, BrainResponse app/services/brain/brain_service.py

LangGraph 사용 범위: intent_langgraph_workflow.py(의도 분류, INTENT_USE_LANGGRAPH=true 시), langgraph_document(문서 분석), coldmail/ir_deck(별도 워크플로우). 의도분석 기본 경로DecisionEngine.analyze_intent + _detect_traditional이며, Pydantic 스키마(IntentGoal 등)를 사용한다.

원칙: 스킬 문서 기반 확장 시 schemas.pySkillDocSummary, IntentSkillMapping 등 Pydantic 모델을 추가하고, dict/YAML 하드코딩 지양. LangGraph 노드 수정은 선택 경로 활성화 시에만 필요.

0.2 환경변수 SSOT

  • SSOT 경로: /home/admin/workspace-config/runtime.env, secrets.env
  • 규칙: 서비스별 .env는 임시 로컬 오버라이드 전용. docker-compose.ymlenvironmentenv_file보다 우선
  • 스킬 URL: SKILL_EMAIL_URL, SKILL_NEWS_URL, SKILL_SLACK_URL 등은 config에서 os.getenv로 읽되, 실제 값은 SSOT에서 주입

0.3 PostgreSQL 사용

  • DB: main_db (51123 서버)
  • 조회: sudo -u postgres psql -d main_db -c "SQL문"
  • 주요 테이블: intents, intent_prototypes, intent_thresholds, intent_path_stats, decision_logs, intent_review_queue, conversation_log
  • 원칙: 의도/스킬 메타데이터는 DB 우선, YAML/파일은 폴백. 스킬 문서 기반 확장 시 DB 스키마와 정합성 유지

0.4 예외·폴백 남발 금지

  • 상위 원칙: 헌장 — "광범위 예외 처리나 폴백으로 증상을 숨기지 않는다", "실패 반복 시 규칙 수정 원칙: 같은 실수가 반복되면 예외·폴백을 늘리지 말고, 규칙·프롬프트를 수정"
  • AGENTS.md: "임시 우회, 광범위 예외 처리, 상태코드 왜곡으로 증상을 숨기지 말고 원인 경로를 직접 수정"
  • 적용: 의도분석 실패 시 UNKNOWN → LLM 폴백 반복 확대 대신, 스킬 문서·규칙·프롬프트를 수정하여 원인 경로를 바로잡음

0.5 로빙 자가 개선 피드백 루프

로빙은 의도분석·스킬 실행 결과를 피드백으로 수집하고, 베이지안/Thompson 기반으로 경로별 성공률을 갱신한다.

구성요소 파일 역할
decision_logs rb8001/app/state/intent_runtime_repository.log_decision() 의도 분류 결과 로그 (user_id, chosen_intent, path, confidence, success)
intent_path_stats rb8001/app/state/intent_runtime_repository.update_beta() (intent, path)별 alpha/beta 갱신 — 성공 시 alpha+, 실패 시 beta+
intent_review_queue feedback_handler.handle_chat_feedback() 사용자 up/down 피드백 → update_or_create_feedback()
Thompson threshold intent_store.get_thompson_thresholds() intent_path_stats 기반 동적 τ — INTENT_USE_DYNAMIC_TAU=1 시 사용
self_improvement self_improvement_endpoint, self_improvement_repository 정책 버전·실행 스냅샷 저장 (predict/act/evaluate/reflect)

적용: 스킬 문서 기반 의도분석 수정 시, decision_logs·intent_path_stats에 새 path(예: skill_doc)를 추가하면 피드백 루프가 자동으로 해당 경로의 성공률을 학습한다. (rb8001/app/state/intent_runtime_repository.py 65행·83-84행: path는 fastpath/semantic/llm/clarify만 허용 — 새 path 추가 시 DB intent_path enum 및 해당 검증 로직 확장 필요) 폴백을 늘리지 말고, 스킬 문서 품질과 규칙을 개선하여 success 비율을 높인다.


1. 문제 요약

  • 증상: "요즘 뉴스 있어?" → skill-news 미호출(에러), "로빙 스탯 알려줘" → D&D 일반론 답변
  • 원인: 의도분석·스킬 선택이 DOCS/skills/ 스킬 문서를 참조하지 않음

2. 전체 흐름 (메시지 → 스킬 실행)

message_service.route_message()
  → create_execution_plan() [decision_engine]
      → analyze_intent() [decision_engine]
      → decide_skill_sequence() [decision_engine]
  → for skill in execution_plan["skills"]:
      → 특수 액션(web_search, create_event 등) 또는
      → _get_service_url_for_skill() → _call_service() / call_internal_llm()

3. 수정 대상 코드 위치 (파일:줄)

3.1 의도 분석 소스 (스킬 문서 미참조)

파일 내용 수정 방향
rb8001/app/services/brain/intent_registry.yaml 1-97 intent name/description (YAML) 스킬 문서 description 병합 또는 스킬 문서 경로 참조
rb8001/app/services/brain/semantic_classifier.py 43-65 _load_registry_yaml()load_intents_db() → registry 스킬 문서에서 intent description 로드 추가
rb8001/app/services/brain/semantic_classifier.py 21-27 intent_registry.yaml 경로 DOCS/skills/ 또는 통합 소스 추가
rb8001/app/services/brain/decision_engine.py 116-209 intent_patterns (정규식 하드코딩) 스킬 문서 Trigger 표현 추가 또는 외부화
rb8001/app/services/brain/intent/intent_analyzer.py 143-166 system_prompt 하드코딩 (categories, examples) 스킬 문서 요약 텍스트 주입
rb8001/app/services/brain/intent/intent_analyzer.py 226-264 _fallback_analyze() 키워드 하드코딩 스킬 문서 기반 키워드 확장

3.2 스킬 선택 (하드코딩, 스킬 문서 미참조)

파일 내용 수정 방향
rb8001/app/services/brain/intent/skill_selector.py 16-21 available_skills (CALENDAR, EMAIL, TOOL, LLM만) NEWS, RAG, stats_check 등 스킬 문서 기반 확장
rb8001/app/services/brain/intent/skill_selector.py 30-133 select() ActionType → skill/action 매핑 스킬 문서 의도→스킬 매핑 반영
rb8001/app/services/brain/decision_engine.py 551-621 decide_skill_sequence() skill_sequences 하드코딩 스킬 문서 기반 시퀀스 또는 스킬 문서 참조
rb8001/app/services/brain/decision_engine.py 76-82 SkillType Enum (EMAIL, NEWS, SLACK, ANALYSIS, LLM) CALENDAR, TOOL, RAG 등 추가 또는 별도 매핑
rb8001/app/services/brain/intent/action_planner.py 17-163 plan() IntentCategory → ActionType 매핑 스킬 문서 의도→액션 매핑 반영

3.3 stats_check 특수 케이스 (LLM으로 잘못 라우팅)

파일 내용 수정 방향
rb8001/app/services/brain/decision_engine.py 596-598 STATS_CHECKSkillType.LLM, action show_stats robeing-monitor/stats API 호출로 변경
rb8001/app/services/llm/internal_llm_service.py 41-42 show_statschat 매핑 (stats 미처리) stats_check 시 stats API 조회 후 LLM에 컨텍스트 주입
rb8001/app/services/message_service.py 391-396 skill_type_enum = SkillType(skill_type_str) "CALENDAR", "TOOL" 등 문자열 skill 처리 (현재는 특수 if 블록으로 처리)

3.4 스킬 URL/실행 (환경변수 의존)

파일 내용 수정 방향
rb8001/app/core/config.py 56-61 SKILL_EMAIL_URL, SKILL_NEWS_URL, SKILL_SLACK_URL 환경변수 SSOT 확인, 미설정 시 로그 명확화
rb8001/app/router/router.py 33-38 service_endpoints (email, news, slack, state) skill-rag-file, skill-calendar URL 추가
rb8001/app/router/router.py 139-148 _get_service_url_for_skill() SkillType 확장 시 URL 매핑 추가

3.5 Intent Store (DB/YAML 소스)

파일 내용 수정 방향
rb8001/app/services/brain/intent_store.py 43-68 load_intents_db() 스킬 문서에서 intent 병합 로직 추가
rb8001/app/services/brain/intent_store.py 71-119 load_prototypes_db(), load_multi_prototypes_db() 스킬 문서 description 임베딩 추가 (선택)

3.6 IntentGraph / LangGraph (선택 경로)

파일 내용 수정 방향
rb8001/app/services/brain/intent_graph.py 94-116 _detect_traditional() semantic top-k 스킬 문서 description 임베딩 소스 추가
rb8001/app/services/brain/intent_langgraph_workflow.py 1-228 LangGraph 의도 분류 워크플로우 스킬 문서를 state/노드 컨텍스트로 주입

4. 스킬 문서 경로 (참조 대상)

경로 용도
robeing/DOCS/skills/SKILL.md 요약, 의도→스킬 매핑
robeing/DOCS/skills/skill-email/SKILL.md email 의도 Trigger/Do
robeing/DOCS/skills/skill-news/SKILL.md news 의도 Trigger/Do
robeing/DOCS/skills/skill-slack/SKILL.md slack 의도 Trigger/Do
robeing/DOCS/skills/skill-calendar/SKILL.md calendar 의도 Trigger/Do
robeing/DOCS/skills/skill-rag-file/SKILL.md document_analysis Trigger/Do
robeing/DOCS/skills/skill-llm/SKILL.md general_chat, stats_check 등
robeing/DOCS/skills/companyx-rag/SKILL.md companyx 근거 검색

5. 권장 수정 순서

  1. Phase 1: intent_analyzer.py system_prompt에 DOCS/skills/SKILL.md 요약 텍스트 주입 (143-166행)
  2. Phase 2: semantic_classifier.py가 스킬 문서 description을 intent 소스로 추가 (intent_registry + 스킬 문서)
  3. Phase 3: skill_selector.py available_skills 확장 및 의도→스킬 매핑을 스킬 문서에서 로드
  4. Phase 4: stats_check 전용 처리 (robeing-monitor API 호출) 추가
  5. Phase 5: decision_engine.intent_patterns를 스킬 문서 Trigger 기반으로 보강 (선택)

6. 관련 문서


7. 확인 완료 항목 (미확인 → 확인)

항목 확인 결과
스킬 URL 51124 주입 rb8001/docker-compose.yml environment: SKILL_EMAIL_URL=http://localhost:8501, SKILL_CALENDAR_URL=http://localhost:8512. SKILL_NEWS_URL, SKILL_SLACK_URL은 env에 없음(config.py Optional). runtime.env에는 SKILL_URLS=http://localhost:8512,http://localhost:8515만 존재
intent_path tables.md 224-231행 문서화. rb8001/app/state/intent_runtime_repository.py 65행·83-84행에서 path 검증: fastpath/semantic/llm/clarify만 허용. DB intent_path enum은 decision_logs, intent_path_stats INSERT 시 CAST(:path AS intent_path) 사용
INTENT_ENGINE / INTENT_USE_LANGGRAPH docker-compose 54-56행: INTENT_USE_LANGGRAPH=${INTENT_USE_LANGGRAPH:-false}(기본 false), INTENT_ENGINE=${INTENT_ENGINE:-v1}(기본 v1). 의도분석 기본 경로는 Pydantic 기반 v1

8. Phase 1~5 구체화 (입력·출력·검증)

Phase 입력 출력 검증 방법
1 DOCS/skills/SKILL.md 요약 텍스트 intent_analyzer.py system_prompt에 주입 시나리오 50개 전체 통과. Phase 1 검증용 샘플: 3, 8, 19, 23, 34 (의도 분류 다양성)
2 skill-*/SKILL.md description semantic_classifier intent 소스 추가 "요즘 뉴스 있어?" → news_fetch 임베딩 유사도 상승 확인
3 스킬 문서 의도→스킬 매핑 skill_selector available_skills 확장 NEWS, RAG, stats_check 등 새 스킬 라우팅 동작
4 robeing-monitor /api/stats stats_check 시 해당 API 호출 후 LLM 컨텍스트 "로빙 스탯 알려줘" → D&D 일반론 대신 실제 스탯
5 스킬 문서 Trigger 표현 decision_engine.intent_patterns 보강 정규식 매칭 우선순위·커버리지 확대

9. 리서치 완성도

항목 판단
범위 스킬 문서 기반 의도분석 적용만 다룸. LangGraph, coldmail, IR deck 등은 의도분석과 직접 관련된 부분만 언급. 범위 과다 확장 없음
문제 기존 문제(스킬 문서 미참조)를 명확히 하고, 해결 방향(Phase 1~5)을 제시. 새 문제를 열지 않음
사실 스킬 URL·INTENT_ENGINE·intent_path 문서화 상태 확인 완료. 수정 대상 코드 위치·줄수 기록
해석 Pydantic 기반 의도분석이 기본 경로. 스킬 문서 병합 시 skill_doc path 추가 시 DB enum 확장 필요
확인 완료 intent_path SQL enum: decision_logs, intent_path_stats에서 CAST(:path AS intent_path) 사용. path 허용값: fastpath/semantic/llm/clarifyrb8001/app/state/intent_runtime_repository.py 65행, 83-84행에서 검증. skill_doc 추가 시 DB enum 및 해당 검증 로직 확장 필요

완성도: 97%


tags: [intent-analysis, skills, research, code-location, pydantic, feedback-loop]
상위 원칙: writing-principles