DOCS/plans/250831_rb8001_postgresql_context_integration.md
happybell80 ad43e64145 docs: Frontend-Slack 통합 완료 상태 반영
- Slack ID → UUID 변환 구현 완료
- original_slack_id 보존 로직 추가
- 크로스 채널 대화 연속성 확보
- 최종 상태: 모든 문제 해결 
2025-08-31 17:02:03 +09:00

4.3 KiB

rb8001 PostgreSQL 대화 기록 LLM 컨텍스트 통합 계획

작성일: 2025-08-31
작성자: 51123 서버 관리자
상태: 구현 완료
목표: ChromaDB 벡터 검색과 PostgreSQL 최근 대화를 모두 LLM 프롬프트에 포함


1. 문제 및 해결

  • 현상: rb8001이 ChromaDB 벡터 검색만 참조하여 엉뚱한 답변 해결
  • 원인: PostgreSQL conversation_logs의 최근 대화 미참조 해결
  • 영향: 직전 대화 컨텍스트 손실, 일관성 없는 응답 해결
  • 결과: Frontend에서 "김종태님" 이름 기억, 최근 10개 대화 로드 확인

2. 기술 분석

현재 구조 (확인 완료)

  • router.py 라인 115-119: context에 user_id, channel, robeing_id만 포함
  • _save_conversation(): PostgreSQL, ChromaDB 둘 다 저장 (구현됨)
  • PostgreSQL 조회 함수: 없음 (ConversationLog 모델만 정의)

수정 필요 부분

  • 파일: /home/heejae/rb8001/main.py
  • 엔드포인트 실제 구조:
    • /api/message (라인 51-103): Frontend용, router._call_internal_llm() 직접 호출
    • /api/slack/events (라인 157-160): Slack용, slack_handler() 호출
    • /complete (라인 106-140): skill-slack용, router._call_internal_llm() 직접 호출
  • 핵심 문제: router.handle_message()는 아무도 호출 안 함, 최근 대화 조회 코드가 실행 안 됨

3. 구현 계획

3.1 PostgreSQL 조회 함수 추가 (신규 구현)

  • 파일: /home/happybell80/ivada_project/rb8001/app/state/database.py
  • 함수명: get_recent_conversations(user_id, limit=10)
  • 쿼리: SELECT message, response, timestamp FROM conversation_logs WHERE user_id = %s ORDER BY timestamp DESC

3.2 최종 해결 방안 - 기존 route_message() 활용

  • 최적 방안: main.py 엔드포인트에서 router.route_message() 호출
    # main.py /api/message (Frontend)
    result = await router.route_message(request.text, user_id, "frontend")
    
    # main.py /api/slack/events (Slack)  
    result = await router.route_message(message, user_id, "slack")
    
    • 확인: route_message (라인 77)에 최근 대화 조회 구현됨 (라인 115-125)
    • 장점: 이미 구현된 모든 기능 활용 (최근 대화 조회, 스킬 라우팅, 저장)
    • 수정: 단 2줄로 완료
    • 안전성: 기존 테스트된 코드, channel 파라미터로 구분

3.3 주의사항 및 해결된 이슈

  • Gmail 처리: "이메일" 키워드 감지 시 자동 처리 (의도된 기능)
  • 슬래시 명령어: Frontend는 / 명령어 사용 안함
  • thread_ts: Frontend는 None 전달
  • DB 저장 버그 수정: HTTP Response 객체를 문자열로 변환 (response.text 또는 str())
    • 문제: Slack에서 <Response [401]> 객체 저장 시도
    • 해결: _save_conversation()에서 response 타입 체크 후 변환

3.4 Frontend-Slack 통합 문제 해결

  • 문제: Slack은 user_id NULL로 저장, Frontend는 UUID 사용 → 대화 분리 → 해결
  • 원인: Slack ID를 UUID로 변환 안 함 → 해결
  • 해결 완료: route_message()에서 slack_user_mapping 테이블 활용
    • Slack ID 감지 시 UUID 조회
    • original_slack_id를 context에 보존
    • _save_conversation()에서 user_id(UUID)와 slack_user_id(원본) 모두 저장
  • 결과: Frontend-Slack 완전 통합, 크로스 채널 대화 연속성 확보

4. 주의사항

  • UUID 처리: Frontend(UUID) vs Slack(변환 필요) 구분
  • 성능: PostgreSQL 조회 추가로 인한 지연 고려
  • 순서: 최근 대화를 먼저, 벡터 검색을 보조로

5. 추가 이슈

  • ChromaDB telemetry 오류 발생 중 → ANONYMIZED_TELEMETRY=false 설정 필요
  • user_id UUID 타입 처리 필요 (Frontend=UUID, Slack=변환)
  • LLM: Gemini 2.5 Flash Lite (DEFAULT_LLM_MODEL=gemini-2.5-flash-lite)

6. 위험성 완화 방안

  • 성능: 캐싱 레이어 추가 또는 비동기 처리로 지연 최소화
  • UUID 오류: try-except로 UUID 검증, 실패 시 slack_user_id 폴백
  • 토큰 한계: 최근 5개로 제한, 각 대화 200자 truncate
  • 로직 충돌: PostgreSQL은 최근 사실, ChromaDB는 장기 기억으로 역할 분리
  • 점진적 적용: 환경변수 USE_POSTGRES_CONTEXT=true로 기능 토글