--- tags: [workflow, rag, companyx, grounding, answer] type: workflow last_updated: 2026-04-06 --- # Company X Grounding 파이프라인 ## 목적 - Company X 소속 사용자의 내부 문서 질문에 대해 로빙이 근거를 붙여 답하게 한다. - 직접 답과 근거 문서를 함께 반환하는 기준을 고정한다. ## 상위 원칙 - [RAG Workflow Index](./README.md) - [헌장.md](../../../../0_VALUE/00_Foundations/헌장.md) - [writing-principles.md](../../../../0_VALUE/20_Governance/writing-principles.md) ## 코드 SSOT - `rb8001/app/services/companyx_grounding_service.py` ## 입력 - 사용자 질문 (`message`) - 사용자 ID (`user_id`) - (선택) 의도 분류 결과 (`classified_intent`, `classified_confidence`) ## 출력 - `CompanyXRAGOutput` (Pydantic 모델): - `direct_answer` — 질문에 대한 직접 답변 (근거 부족 시 빈 문자열) - `evidence_docs` — 근거 문서 파일명 목록 - `failure_reason` — 답변 불가 사유 (문서 없음, 단정 불가 등) ## 진입 조건 (`should_handle_companyx_grounding()`) 1. `user_id`에서 `team_id`를 조회한다 (`get_user_team_id()`). 2. `team_id != COMPANYX_TEAM_ID`이면 진입하지 않는다. 3. LLM 의도 분류가 `companyx_rag` 이외의 확정 intent를 confidence >= 0.7로 반환했으면 진입하지 않는다. 4. `companyx_rag`으로 분류된 경우(confidence >= 0.5) 진입한다. 5. 위 두 경우 모두 아닐 때, 하위 호환성을 위해 마커 기반 판단(`_looks_like_companyx_grounding_question()`)으로 진입 여부를 결정한다. - **마커**: intent 마커(근거, 내부 문서, MOU, 계약서, 투자조합, 재무제표 등) 또는 domain 마커(오늘전통, 옐로펀치, 컴퍼니엑스 등) ## 처리 순서 (`try_companyx_grounding()`) 1. 진입 조건 확인 (위 참조). 2. 질문 유형 분류 (`_classify_question_type()`): explanatory / fact_check / quantitative / recap. 3. 멀티쿼리 생성 (`_build_query_candidates()`): 원문 + 키워드 조합 + 문서 힌트 결합으로 중복 제거 후 다수 변형 생성. 4. 하이브리드 검색 (`_search_companyx_documents()`): - 각 쿼리를 `$SKILL_RAG_FILE_URL/api/search`에 병렬 호출 (`asyncio.gather`). - 페이로드: `team_id=COMPANYX_TEAM_ID`, `limit=5`, `threshold=0.35`, `search_mode=hybrid`. - 결과를 `document_id:chunk_index` 키로 병합, 최고 점수만 유지. 5. 상위 결과 선택 (`_select_top_results()`): RRF 정규화 점수 기준 정렬, 문서 다양성(같은 document_id 중복 제거), 최대 5건(`MAX_EVIDENCE_CHUNKS`). 6. LLM 근거 답변 생성 (`_call_llm_companyx_grounding()`): - 프롬프트: `prompts/rag/companyx_grounding.md` (render_prompt). - 모델: `settings.DEFAULT_LLM_MODEL`, temperature=0.1, JSON 응답 형식. - 응답을 `CompanyXRAGOutput`으로 Pydantic 검증. 7. 최종 응답 조립 (`_build_grounded_response()`): LLM 성공 시 direct_answer + 참고 문서, 실패 시 question_type별 실패 메시지. ## 검색 모드 - 기본 검색 모드: `hybrid` (벡터 + 키워드 RRF 합산). - 벡터 검색: PGVector cosine similarity (Gemini Embedding 2, 768d). - 키워드 검색: PostgreSQL tsvector + GIN 인덱스, prefix 매칭(`:*`). - 점수 합산: RRF (Reciprocal Rank Fusion, k=60), 정규화 0~1. - Apache AGE 그래프 점수: hook으로 가산 가능 (보조적 위치). ## 근거 선별 원칙 - 키워드 기반 룰로 검색 결과를 필터링하지 않는다 (룰베이스 절제 원칙 — 헌장.md 참조). - 하이브리드 검색 RRF 정규화 점수 순서를 신뢰하고, LLM이 컨텍스트를 보고 적합도를 재판단한다. - 근거 선별 책임은 LLM에 있으며, 코드 레벨에서는 점수 상위 결과를 문서 다양성 기준으로 선택만 한다. ## 실패 분기 - 검색 결과가 0건이면 `try_companyx_grounding()`이 `None`을 반환 → `message_service`가 일반 의도 분류 경로로 fallback. - LLM이 컨텍스트만으로 답변 불가로 판단하면 `failure_reason`을 채우고, 성공처럼 반환하지 않는다. - 수치형 질문에서 값이 없으면 추정하지 않는다. - 내부 규정이나 최신 집계가 없으면 `문서 없음`, `미확인`, `불일치` 중 하나로 명시한다. - 메타 대화로 회피하지 않는다. ## 환경변수 - `SKILL_RAG_FILE_URL` — skill-rag-file 서비스 베이스 URL (필수). ## 검증 기준 - 기준 질문(오늘전통, 옐로펀치 등)에서 직접 답 + 근거 문서가 함께 나와야 한다. - 근거 부족 질문(투자사 수, 휴가 규정 등)은 추정 없이 실패해야 한다. - Slack 실응답과 테스트 응답이 같은 기준을 따라야 한다. ## 관련 문서 - [RAG 검색·Grounding 요청](./rag_search_grounding_request.md) - [Company X 내부 문서 근거응답 사용자 시나리오](../../journey/scenarios/260312_companyx_내부문서_근거응답_사용자시나리오.md)