- 7-8월 초기 구축 문서 12개를 _archive/troubleshooting/2025_07-08_initial_setup/로 이동 - book/300_architecture/390_human_in_the_loop_intent_learning.md를 journey/research/intent_classification/로 이동 (개발 여정 문서) - 빈 폴더 제거 (journey/assets/*)
4.3 KiB
4.3 KiB
rb8001 문서 분석 실패 원인: RAG 검색 타임아웃 + PK 시퀀스 불일치로 대명사 해소 실패
날짜: 2025-10-23 (KST) 작성자: happybell80 관련 파일: rb8001/app/pipelines/langgraph_document.py, rb8001/app/state/conversation_repository.py, rb8001/app/router/slack_handler.py
문제 상황
- 23:08, 23:19, 23:24, 23:40 시각에 Slack에서 “이 기업 … 분석” 요청 시 원하는 IR 문서가 아닌 다른 문서가 주입되거나, 일반 안내 답변만 반환됨.
- 로그에서 문서 파이프라인(LangGraph) 단계에서 간헐적으로 실패하며, 직전 대화가 DB에 저장되지 않아 대명사(“이 기업”) 해소가 실패하는 현상 확인.
주요 증상 로그 (KST)
- 23:08:17 WARNING LangGraph pipeline failed, continue without snippets (예외 메시지 공백)
- 23:08:22 ERROR PostgreSQL save failed: duplicate key value violates unique constraint "conversation_log_pk"
- 23:19:27 RAG /api/text 200 → full text 주입 성공 (정상 흐름 사례)
- 23:24:14 ERROR PostgreSQL save failed: duplicate key (id)=(1093)
- 23:40:46 ERROR [Graph] pipeline failed (ReadTimeout) at RAG /api/search 단계 → 컨텍스트 미주입, 일반 답변으로 폴백
원인 분석
- 외부 의존(RAG 8508) 타임아웃으로 LangGraph 문서 파이프라인 중단
- RAG /api/search 호출 기본 타임아웃(10s) 초과로 ReadTimeout 발생 → 스니펫/원문 미주입 → 일반 답변 폴백.
- conversation_log PK 시퀀스 불일치
- conversation_log.id 시퀀스가 MAX(id)보다 뒤처져 duplicate key 발생 → 직전 대화 저장 실패 → 최근 컨텍스트에 GX workvisa가 반영되지 않음 → 대명사 해소 실패.
- 대명사(“이 기업”) 해소 경로
- 의도가 document_analysis일 때, 문맥 엔티티 해소가 실패하면 팀 RAG 상위 문서가 주입되어 엉뚱한 문서(예: 리버스마운틴) 분석으로 이어짐.
해결 방안 (코드 적용)
- 파일:줄번호 명시 (간결)
- rb8001/app/pipelines/langgraph_document.py:54
- RAG 검색 타임아웃/재시도 추가
- env: RAG_SEARCH_TIMEOUT(기본 25), RAG_SEARCH_RETRIES(기본 1), RAG_SEARCH_BACKOFF(기본 1.5s)
- rb8001/app/router/slack_handler.py:247
- 문서 파이프라인 실패 시 예외 타입·traceback 로깅 추가
- rb8001/app/pipelines/langgraph_document.py:94
- 파이프라인 시작/예외 상세 로그(스택 포함) 출력
- rb8001/app/state/conversation_repository.py:77
- PK 중복 시 시퀀스 실시간 재정렬(setval(MAX(id)+1)) 후 1회 재시도
구현 완료
- 커밋
- a1c71db: RAG 검색 타임아웃 25s + 1회 재시도(백오프) 추가
- 33f7b55: 문서 파이프라인 상세 로깅(예외 타입/스택)
- 35f5a40: conversation_log PK 중복 자동 복구(시퀀스 재정렬 후 재시도)
- 2b03f1a: 기타 안정화(포트/URL 정합, autoincrement 사용)
- 배포: docker compose up -d --build (51124 rb8001)
검증 결과
- 문서 파이프라인 재현 스크립트로 예외 타입·스택 로깅 확인
- rb8001/scripts/debug_document_pipeline.py (컨테이너 내부 실행)
- 23:19 케이스: full text 주입 200 정상 확인 사례 존재
- 23:40 케이스: 이전(10s) 타임아웃으로 ReadTimeout 확인 → 타임아웃 상향/재시도 적용 이후 재현 시 안정성 개선 기대
운영 가이드/설정
- 타임아웃 조정
- RAG_SEARCH_TIMEOUT=25 (초), RAG_SEARCH_RETRIES=1, RAG_SEARCH_BACKOFF=1.5 (초)
- 응답 지연을 고려해 필요 시 값 미세 조정 권장
- 시간대: 로그 판단은 KST(UTC+9). OpenSearch는 UTC, 변환 후 비교 필요
교훈 (필수)
- 외부 의존 실패는 기본적으로 발생한다 → 타임아웃 상향, 재시도, 백오프, 서킷브레이커 등 회복 탄력성 설계가 필수
- DB 시퀀스 불일치가 컨텍스트 저장 실패로 이어져 대명사 해소 실패까지 전파됨 → 저장 계층 안정화가 상위 기능 품질에 직접 영향
- 실패 원인 추적성 확보(예외 타입/스택/컨텍스트 로깅) 없이는 재현/해결에 장시간 소요 → 상세 로깅 표준화 필요
다음 조치
- skill-rag-file(8508) 응답 시간 프로파일링 및 쿼리 튜닝 점검
- Slack 응답 SLA 고려한 타임아웃/재시도 파라미터 최적화
- conversation_log.id 시퀀스 정기 점검(운영 점검 스크립트에 포함) 및 알림