DOCS/troubleshooting/250819_happybell80_Mistral의도분석실패.md
happybell80 3e0fbe569a docs: Mistral 의도 분석 문제 해결 완료
- Mistral API 응답 파싱 경로 수정 (data.intent → data.choices[0].message.content)
- skill-email 엔드포인트 경로 수정 (/api/process → /process)
- 의도 분석 및 스킬 연동 정상 작동 확인
2025-08-19 16:39:48 +09:00

5.2 KiB

Mistral 의도 분석 실패 및 skill-email 연동 문제

날짜: 2025-08-19
작업자: happybell80 & Claude
관련 서비스: rb10508_micro, skill-email, Mistral API

오후 4시 24분

Mistral 의도 분석이 작동하지 않는 문제

증상:

  • 모든 메시지가 general_conversation으로 분류됨
  • "이메일 보내줘", "뉴스 알려줘" 등 명시적 키워드도 인식 실패
  • skill-email 서비스는 정상이지만 호출되지 않음

테스트 결과:

입력: "이메일 보내줘"
로그: [의도 분석] intent: general_conversation
결과: skill-email 미호출, Gemini 일반 응답

코드 분석:

# brain.py - 현재 코드
intent_pipeline = analyze_intent(think_input.message)
mistral_response = await call_mistral_api(intent_pipeline['request'], settings.MISTRAL_API_KEY)
intent = intent_pipeline['mapper'](mistral_response)

문제 원인:

  1. MISTRAL_API_KEY 없음: 환경변수 미설정 시 Mistral 호출 생략
  2. call_mistral_api 실패: API 호출 실패 시 기본값 반환
  3. intent_mapper 오류: 잘못된 응답 구조 파싱

확인 필요사항:

# .env 파일 확인
MISTRAL_API_KEY=??? # 설정되어 있는지 확인

코드 흐름 추적

  1. analyze_intent() 호출

    • 프롬프트 생성: "email/news/general 중 선택"
    • 요청 객체 생성
  2. call_mistral_api() 호출

    • API 키 없으면 → 실패
    • 네트워크 오류 → 실패
    • 실패 시 → {"success": False} 반환
  3. intent_mapper() 호출

    • 실패한 응답 → data.intent 없음
    • 기본값 → "general_conversation"

해결 방안

방안 1: 간단한 폴백 추가

# MISTRAL_API_KEY 없을 때 키워드 기반 폴백
if not settings.MISTRAL_API_KEY:
    if "이메일" in message or "메일" in message:
        intent = "email"
    elif "뉴스" in message:
        intent = "news"
    else:
        intent = "general_conversation"

방안 2: Mistral API 키 설정

# .env 파일에 추가
MISTRAL_API_KEY=your-mistral-api-key

방안 3: 디버그 로그 추가

logger.info(f"Mistral API Key: {'있음' if settings.MISTRAL_API_KEY else '없음'}")
logger.info(f"Mistral Response: {mistral_response}")

테스트 방법

  1. API 키 확인:
cd /home/admin/rb10508_micro
cat .env | grep MISTRAL
  1. 로그 확인:
tail -f /mnt/hdd/logs/rb10508_micro/app.log | grep "의도 분석"
  1. 수동 테스트:
# Mistral API 직접 테스트
curl -X POST https://api.mistral.ai/v1/chat/completions \
  -H "Authorization: Bearer $MISTRAL_API_KEY" \
  -d '{"model": "mistral-small-latest", "messages": [{"role": "user", "content": "이메일"}]}'

교훈

  1. 환경변수 의존성 명확히: 필수 API 키는 시작 시 검증
  2. 폴백 메커니즘 필수: 외부 API 의존 시 항상 폴백 준비
  3. 디버그 로그 중요: 의도 분석 같은 핵심 로직은 상세 로그 필요
  4. 함수형 원칙과 실용성 균형: 순수 함수도 좋지만 에러 처리도 중요

즉시 적용 가능한 해결책

# brain.py 수정 - 간단한 키워드 폴백
if not settings.MISTRAL_API_KEY:
    # Mistral 없으면 키워드 매칭
    message_lower = think_input.message.lower()
    if any(word in message_lower for word in ["이메일", "메일", "email"]):
        intent = "email"
    elif any(word in message_lower for word in ["뉴스", "news"]):
        intent = "news"
    else:
        intent = "general_conversation"
else:
    # Mistral API 호출
    mistral_response = await call_mistral_api(...)
    intent = intent_pipeline['mapper'](mistral_response)

이렇게 하면 Mistral API 없이도 기본적인 의도 분석이 가능합니다.


다음 단계:

  1. .env 파일에서 MISTRAL_API_KEY 확인
  2. 없으면 키워드 폴백 구현
  3. 있으면 API 호출 디버깅

오후 4시 36분

문제 해결 완료

문제 원인 확인:

  • Mistral API는 정상 작동하나, 응답 파싱 경로가 잘못됨
  • 잘못된 경로: data.intent
  • 올바른 경로: data.choices[0].message.content

수정 사항:

  1. brain.py의 intent_mapper 함수 수정:
# 기존 코드
intent = mistral_response.get('data', {}).get('intent', 'general')

# 수정된 코드
intent = mistral_response.get('data', {}).get('choices', [{}])[0].get('message', {}).get('content', 'general').strip().lower()
  1. external_bridge.py의 엔드포인트 경로 수정:
# 기존: f"{endpoint}/api/process"
# 수정: f"{endpoint}/process"

테스트 결과:

  • 의도 분석 정상 작동 (email, news, general)
  • skill-email 서비스 연동 성공
  • 전체 플로우 정상 작동

성공 로그:

[의도 분석] intent: email
HTTP Request: POST http://172.17.0.1:8501/process "HTTP/1.1 200 OK"

교훈

  1. API 응답 구조 정확히 파악: 외부 API 사용 시 응답 구조 문서화 필수
  2. 디버깅 시 전체 응답 로깅: 문제 발생 시 전체 응답 구조 확인
  3. 엔드포인트 경로 일치: 서비스 간 API 경로 명세 통일
  4. 단계별 테스트: 의도 분석 → 서비스 호출 → 응답 처리 각각 검증