diff --git a/plans/250831_rb8001_postgresql_context_integration.md b/plans/250831_rb8001_postgresql_context_integration.md deleted file mode 100644 index deecb06..0000000 --- a/plans/250831_rb8001_postgresql_context_integration.md +++ /dev/null @@ -1,88 +0,0 @@ -# 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()` 호출 - ```python - # 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에서 객체 저장 시도 - - 해결: _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`로 기능 토글 \ No newline at end of file diff --git a/troubleshooting/250831_rb8001_postgresql_context_integration.md b/troubleshooting/250831_rb8001_postgresql_context_integration.md new file mode 100644 index 0000000..5b7c151 --- /dev/null +++ b/troubleshooting/250831_rb8001_postgresql_context_integration.md @@ -0,0 +1,71 @@ +# rb8001 PostgreSQL 대화 기록 통합 및 Frontend-Slack 연동 + +**작성일**: 2025-08-31 +**작성자**: 51123 서버 관리자 +**상태**: ✅ 구현 완료 +**목표**: ChromaDB 벡터 검색과 PostgreSQL 최근 대화를 모두 LLM 프롬프트에 포함 + +--- + +## 1. 문제 상황 + +- **현상**: rb8001이 ChromaDB 벡터 검색만 참조하여 엉뚱한 답변 +- **원인**: PostgreSQL conversation_logs의 최근 대화 미참조 +- **영향**: 직전 대화 컨텍스트 손실, 일관성 없는 응답 +- **테스트**: "내 이름은 김종태" → "내 이름은?" → "모릅니다" 응답 + +## 2. 원인 분석 + +### 발견된 문제점 +- `router.py` 라인 115-119: context에 user_id, channel, robeing_id만 포함 +- PostgreSQL 조회 함수 없음 (ConversationLog 모델만 정의) +- `/api/message` 엔드포인트가 `router._call_internal_llm()` 직접 호출 +- route_message()는 존재하지만 아무도 호출하지 않음 +- Frontend는 UUID, Slack은 Slack ID 사용으로 사용자 분리 + +## 3. 구현 완료 내역 + +### 3.1 대화 컨텍스트 통합 +- **database.py**: `get_recent_conversations()` 함수 추가 - PostgreSQL에서 최근 10개 대화 조회 +- **gemini_handler.py**: context['recent_conversations'] 활용하여 프롬프트에 포함 +- **router.py**: 최근 대화 조회 및 context 전달 구현 + +### 3.2 엔드포인트 통합 (근본 해결) +- **문제 발견**: handle_message() 존재하지 않음, 실제는 route_message() +- **main.py 수정**: `/api/message` 엔드포인트가 route_message() 호출하도록 변경 +- **slack_handler.py 수정**: 모든 Slack 요청도 route_message() 통합 +- **결과**: Frontend/Slack 모두 동일한 로직 사용으로 일관성 확보 + +### 3.3 Frontend 응답 형식 수정 +- **문제**: results 배열 구조에서 bot_response 추출 실패 +- **main.py 수정**: results[0].content 추출 로직 및 디버그 로깅 추가 + +### 3.4 PostgreSQL 저장 오류 해결 +- **문제**: HTTP Response 객체를 DB에 직접 저장 시도 +- **_save_conversation() 수정**: Response 객체를 문자열로 변환 (response.text 또는 str()) + +### 3.5 Slack-Frontend 통합 달성 +- **Slack ID → UUID 자동 변환**: slack_user_mapping 테이블 활용 +- **route_message() 진입점**: Slack ID 감지 시 UUID 조회 및 변환 +- **이중 저장**: user_id(UUID)와 slack_user_id(원본) 모두 저장 +- **결과**: 김종태, 이고은 등 사용자가 어느 채널에서든 대화 연속성 유지 + +## 4. 성과 +- **총 5개 커밋**: 약 200줄 코드 수정 +- **Frontend ↔ Slack 완전 통합**: 크로스 채널 대화 공유 +- **대화 기록 영속성**: PostgreSQL과 ChromaDB 모두 정상 저장 +- **사용자 경험 개선**: "내 이름은?" 질문에 정확한 답변 가능 + +## 5. 기술 세부사항 + +### 수정된 파일 +- `database.py`: get_recent_conversations() 함수 추가 +- `gemini_handler.py`: recent_conversations 컨텍스트 활용 +- `router.py`: Slack ID → UUID 변환 로직 +- `main.py`: route_message() 호출로 통합 +- `slack_handler.py`: route_message() 통합 + +### 데이터베이스 스키마 +- `conversation_logs.user_id`: UUID (Frontend 사용자) +- `conversation_logs.slack_user_id`: VARCHAR (Slack ID 보존) +- `slack_user_mapping`: Slack ID ↔ UUID 매핑 테이블 활용 \ No newline at end of file