# 사용자 구분 및 ChromaDB 격리 문제 **날짜**: 2025-08-19 **작성자**: Claude (51124 서버) **관련 서비스**: rb8001, rb10508_micro, ChromaDB, Slack **상태**: ✅ 해결 완료 (2025-08-28) - [250828_UUID_통합_및_사용자_격리_계획.md](../troubleshooting/250828_UUID_통합_및_사용자_격리_계획.md) 참조 ## ~~발견된 문제~~ ✅ 해결됨 ### 1. ~~rb8001 사용자 구분 없음~~ ✅ 해결 - **현상**: - ~~종태님(U0925SXQFDK)을 "전희재님"으로 호칭~~ - ~~모든 사용자 대화가 하나의 ChromaDB 컬렉션에 저장~~ - ~~`robeing_rb8001_memories` 단일 컬렉션 사용~~ - **해결 (2025-08-28)**: - JWT 인증 구현 완료 - 사용자별 컬렉션 분리 (`rb8001_{user_uuid}`) - Slack ID → UUID 자동 변환 구현 ### 2. 슬랙 봇 분리 문제 - **현상**: - rb8001: 희재님 이벤트만 수신 - rb10508_micro: 종태님 이벤트 수신 추정 - 다른 슬랙 봇 토큰 사용 - **봇 토큰 차이**: ``` rb8001: xoxb-***1d99 rb10508_micro: xoxb-***ZK7q (다른 토큰!) rb10408_test: xoxb-***1d99 ``` ### 3. 사용자 식별 체계 불일치 - **rb8001**: 슬랙 user_id만 사용 - **rb10508**: Gateway JWT를 통한 웹 user_id 사용 - **통합 매핑**: 없음 ## ~~보안 및 프라이버시 위험~~ ✅ 해결 ### ~~ChromaDB 데이터 혼재~~ ✅ 해결 - **문제**: ~~한 사용자가 다른 사용자의 대화 컨텍스트에 접근 가능~~ - **예시**: ~~종태님이 "내 생일은?"이라고 물으면 희재님 생일 정보가 나올 수 있음~~ - **해결**: 사용자별 컬렉션 완전 격리 (`rb8001_{user_uuid}`) ### ~~잘못된 컨텍스트 응답~~ ✅ 해결 - **문제**: ~~이전 사용자의 대화를 현재 사용자 것으로 인식~~ - **예시**: ~~"전희재님"이라고 잘못 호칭~~ - **해결**: UUID 기반 사용자 식별 체계 통합 ## 현재 아키텍처 분석 ### rb8001 (문제 있음) ``` Slack Event → rb8001 → ChromaDB (단일 컬렉션) ↓ 사용자 구분 없음 ``` ### rb10508_micro (상대적으로 나음) ``` Web → Gateway(JWT) → rb10508 → ChromaDB (사용자별?) ↓ 사용자 인증 ``` ## 제안하는 해결책 ### 단기 (즉시 적용 가능) #### 1. ChromaDB 사용자별 분리 ```python # 현재 (문제) collection_name = "robeing_rb8001_memories" # 개선안 collection_name = f"robeing_rb8001_{user_id}_memories" # 예: robeing_rb8001_U0925SXQFDK_memories ``` #### 2. 기존 데이터 처리 - 혼재된 데이터 백업: `/backup/chroma_mixed_20250819.db` - ChromaDB 초기화 또는 마이그레이션 - 사용자별 컬렉션으로 재구성 #### 3. 슬랙 봇 토큰 통일 - 모든 서비스가 동일한 봇 토큰 사용 - 또는 명확한 역할 분리 (메인/테스트) ### 중기 (1-2주) #### 1. 사용자 관리 일원화 ```sql -- PostgreSQL users 테이블 확장 ALTER TABLE user ADD COLUMN slack_user_id VARCHAR(20); CREATE INDEX idx_slack_user_id ON user(slack_user_id); -- 매핑 테이블 CREATE TABLE user_identity_mapping ( web_user_id VARCHAR(100), slack_user_id VARCHAR(20), robeing_id VARCHAR(50), PRIMARY KEY (web_user_id, slack_user_id) ); ``` #### 2. Gateway 통합 - 슬랙 이벤트도 Gateway 거쳐서 처리 - 통일된 사용자 식별 체계 - 중앙 인증/인가 ### 장기 (1개월+) #### 1. 멀티테넌시 ChromaDB - 사용자별 + 서비스별 + 세션별 격리 - 권한 체크 미들웨어 - 데이터 접근 감사 로그 #### 2. 사용자 프로필 서비스 - 중앙화된 사용자 정보 관리 - 이름, 선호도, 권한 등 통합 - 모든 서비스가 API로 조회 ## 구현 우선순위 1. **긴급**: ChromaDB 사용자별 분리 (데이터 보안) 2. **중요**: 슬랙 봇 토큰 통일 (사용자 경험) 3. **개선**: Gateway 통합 (아키텍처 일관성) ## 위험 및 고려사항 ### 데이터 손실 위험 - 마이그레이션 전 반드시 백업 - 점진적 마이그레이션 고려 ### 서비스 중단 - 무중단 배포 전략 필요 - 새 컬렉션 생성 후 전환 ### 성능 영향 - 사용자별 컬렉션 = 메모리 사용량 증가 - 인덱싱 오버헤드 고려 ## 테스트 시나리오 1. **사용자 격리 테스트** - 종태님으로 대화 → 종태님 컬렉션만 사용 확인 - 희재님으로 대화 → 희재님 컬렉션만 사용 확인 - 크로스 체크: 서로의 정보 접근 불가 확인 2. **봇 통합 테스트** - 모든 사용자가 동일한 봇과 대화 - 일관된 응답 확인 3. **마이그레이션 테스트** - 기존 대화 이력 보존 확인 - 새 구조에서 정상 작동 확인 ## 참고 자료 - 현재 ChromaDB 위치: `/home/admin/ivada_project/rb8001/chroma_db/` - 로그 분석: `docker logs rb8001 --since "3h"` - 사용자 ID: - U0925SXQFDK: 종태님 - U091UNVE41M: 희재님 - U0935RJ60V6: rb8001 봇 ## 다음 단계 1. 로컬 개발자와 논의 2. 백업 계획 수립 3. 단계별 구현 시작 --- ## 추가 검증 결과 (2025-08-19 12:30) ### slack_user_mapping 테이블 검증 완료 #### 데이터베이스 상태 - **테이블 존재**: ✅ main_db.slack_user_mapping - **정확한 매핑 데이터**: ``` U0925SXQFDK → aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa → 김종태 U091UNVE41M → bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb → 전희재 UHHYONG91 → cccccccc-cccc-cccc-cccc-cccccccccccc → 황한용 ``` #### 코드 분석 결과 1. **rb8001**: - slack_user_mapping 테이블 조회 로직 없음 - Slack user_id만 ChromaDB metadata에 저장 - 실제 사용자 이름 변환 없이 LLM에 전달 2. **rb10508_micro**: - 마찬가지로 slack_user_mapping 미사용 - ChromaDB identity 컬렉션 자체가 없음 - 사용자 이름은 get_identity()로 조회하나 실제 데이터 없음 ### 문제 근본 원인 확정 **DB에는 올바른 매핑이 있으나, 서비스 코드에서 이를 활용하지 않음** - slack_user_mapping 테이블 생성: 2025-08-12 22:11 - 서비스 코드 업데이트: 없음 - 결과: LLM이 ChromaDB의 오염된 메모리에서 잘못된 이름 학습 ### 로그 증거 ``` INFO:app.router.slack_handler:Event: app_mention from U0925SXQFDK INFO:app.router.router:Conversation saved for user U0925SXQFDK INFO:app.router.slack_handler:Router result: { 'content': '전희재님, 8001이 무엇을 의미하는지...' } ``` 종태님(U0925SXQFDK) 이벤트에 "전희재님"으로 응답하는 명확한 증거 ### 개선 필요 코드 위치 1. **rb8001/app/router/router.py**: - route_message() 함수에서 slack_user_mapping 조회 추가 - user_name을 LLM context에 전달 2. **rb8001/app/llm/gemini_handler.py**: - 시스템 프롬프트에 정확한 사용자 이름 포함 3. **rb10508_micro/app/core/brain.py**: - think() 함수에서 slack_user_mapping 조회 - user_name 파라미터에 실제 이름 전달 ### 필수 해결 방안 1. slack_user_mapping 테이블 활용 코드 추가 2. ChromaDB 사용자별 컬렉션 분리 3. LLM 프롬프트에 정확한 사용자 정보 전달 --- **문서 끝**