--- tags: [plans, companyx, rag, answer-composition, scenario, troubleshooting] --- # Company X RAG 답변합성 시나리오·트러블 동시종결 계획 **작성일**: 2026-03-15 **상태**: 구현완료_미검증 (Phase 0 부분확정, Phase 1~4 구현완료, Phase 5 미완료) **검토일**: 2026-03-17 **갱신일**: 2026-03-17 **목표**: Company X 내부문서 근거응답 경로를 `대표 질문 특례 처리`에서 `공통 계약 기반 답변합성` 구조로 바꾸되, 구현 전에 `현재 NAS 문서 운영 상태 + 현재 임베딩 전제`를 다시 닫고 대응 troubleshooting 문서와 scenario 문서를 함께 닫습니다. > **2026-03-17 코드 검토 결과**: 이 계획의 핵심 구현(Phase 1~4)은 이미 코드에 반영되어 있음. > Phase 5(테스트 고정 및 Slack 실응답 검증)가 미완료 상태. > 상세 내용: [260317_companyx_grounding_코드검토_및_문서현행화](../worklog/260317_companyx_grounding_코드검토_및_문서현행화.md) ## 관련 문서 - [Company X RAG 답변 합성 회귀](../troubleshooting/260312_companyx_rag_answer_composition_regression.md) - [Company X 내부 문서 RAG 응답 아이디어](../ideas/260312_companyx_내부문서_rag_응답_아이디어.md) - [Company X 내부 문서 근거응답 사용자 시나리오](../scenarios/260312_companyx_내부문서_근거응답_사용자시나리오.md) - [Company X RAG 답변합성 시나리오·트러블 동시종결 리서치](../research/260315_companyx_rag_답변합성_시나리오동시종결_리서치.md) - [Company X RAG 스킬 문서](../../skills/companyx-rag/SKILL.md) ## 연결 구조 - 같은 레벨 입력: `ideas/260312_companyx_내부문서_rag_응답_아이디어.md`, `scenarios/260312_companyx_내부문서_근거응답_사용자시나리오.md` - 단일 리서치: `research/260315_companyx_rag_답변합성_시나리오동시종결_리서치.md` - 단일 플랜: 본 문서 1개 - 닫힘 흐름: 본 플랜 완료 기준 충족 시 시나리오/리서치/트러블 동시 닫힘 (아이디어 문서는 종결 상태 유지) ## 1. 이번 계획의 결정 - 현재 코드 기준으로 Phase 1~4 핵심 구현은 반영된 상태로 봅니다. - 남은 핵심은 `테스트/실응답 검증`과 `현재 NAS 문서 동기화 상태 + 현재 Company X 컬렉션 차원 + 현재 Gemini Embedding 2 전환 상태` 재검증입니다. - **저장 전제**: 2026-03-17 기준 운영 런타임은 `skill-rag-file`, `rb8001`의 핵심 벡터/검색/그래프 경로를 **PostgreSQL 중심으로 전환**한 상태입니다. - **임베딩 전제 갱신**: 컬렉션 차원 `384`는 더 이상 사용하지 않으며, `768`도 Gemini 2 기준으로 **전량 재임베딩**해야 합니다. - **Go 전환 근거**: 내부 NAS Go 동기화 리서치의 1분 벤치마크는 Go가 Python 대비 **총 사이클 +5~6%** 수준이며, “무조건 큰 폭의 시간 단축”을 보장하지 않습니다. - **청킹 리스크**: 현재 `skill-rag-file`의 `char_per_token = 4` 근사는 **한국어 과소 청킹** 가능성이 높아, 품질/비용/속도에 영향이 있습니다. - 이 문제는 `검색 인프라 확장`보다 `답변 합성 계약 부재` 문제로 다룹니다. - 질문별 `if` 분기, 질문별 direct answer, 질문별 프롬프트 추가로 닫지 않습니다. - `Company X grounding` 경로에 공통 계약 3개를 먼저 고정합니다. 1. 질문 유형 계약 2. 근거 채택 계약 3. 근거 부족 시 실패 계약 - 성공 기준은 `검색 hit 존재`가 아니라 `직접 답 + 질문 적합 근거 또는 명시적 부족 안내`로 바꿉니다. ## 2. 범위 - 포함: - Company X RAG의 현재 임베딩 경로/차원 재검증 - NAS 최신 문서 동기화본과 검색 컬렉션 반영 상태 확인 - `rb8001/app/services/companyx_grounding_service.py` - Company X 재오픈 기준 질문 20개의 응답 계약 - `SKILL.md`와 코드 계약 정합화 - 테스트 보강 - 제외: - Company X 전체 문서셋 대규모 확대 - 다른 RAG 경로 공통화 - Prompt DB 전면화 - `skill-rag-file` 자체 리팩토링 ## 3. 공통 계약 고정안 ### A. 질문 유형 계약 - 최소 유형은 아래 4개로 고정합니다. - 설명형 - 사실 확인형 - 수치 확인형 - 재정리형 - 판단 결과는 코드 내부 enum 또는 동등한 상수로 다룹니다. - 질문별 문자열 특례가 아니라 유형별 처리로 묶습니다. ### B. 근거 채택 계약 - 검색 결과가 있다고 바로 근거로 채택하지 않습니다. - 채택 기준: - 질문의 핵심 엔티티와 직접 관련이 있어야 합니다. - 질문 유형에 맞는 문서여야 합니다. - 상위 결과라도 질문과 무관하면 버립니다. - `relevance_score`는 후보 신호일 뿐, 최종 성공 판정 기준이 아닙니다. ### C. 실패 계약 - 아래 경우는 성공처럼 반환하지 않습니다. - 검색 결과 0개 - 검색 결과는 있으나 질문과 무관 - 수치/규정 질문인데 단정 가능한 근거가 없음 - 실패 응답은 아래 셋 중 하나로 고정합니다. - `문서 없음` - `질문과 맞는 문서 미확인` - `내부 문서만으로는 단정 불가` ## 4. 구현 원칙 - **인덱싱 파이프라인 전환**: 텍스트 변환 후 청킹하는 현재 방식을 Gemini Embedding 2의 멀티모달 직접 임베딩으로 전환합니다. - 대상: PDF, 이미지, docx 등 모든 파일 형식 — 텍스트 추출 없이 원본 파일 직접 임베딩 - 제한: 텍스트 8,192 토큰, PDF 6페이지 단위, 영상 120초, 오디오 80초 - 기존 텍스트 추출 파이프라인(pdftotext, PyPDF2, OCR)은 제거 대상 - **RAG 구조 전환**: 현재 규칙 기반 문자열 조합은 RAG가 아닙니다. 검색된 청크를 컨텍스트로 LLM에 전달해 답변을 생성하는 구조로 전환합니다. - 플로우: 질문 임베딩 → pgvector 유사도 검색 → 적합 청크 선별 → LLM 컨텍스트 전달 → 답변 생성 - LLM: 현재 rb8001 기준 모델 사용 (gpt-4o-mini 계열) - 근거 부족 시 LLM에게 "문서 없음"을 명시적으로 지시하는 시스템 프롬프트 포함 - `SKILL.md`의 답변 순서(`direct answer -> evidence documents -> short evidence summary`)를 LLM 프롬프트 계약으로 내립니다. - 질문별 direct answer 하드코딩을 더 늘리지 않습니다. - 질문 유형 판정과 근거 채택 판정은 별도 함수로 분리합니다. - `검색됨`과 `답할 수 있음`을 같은 상태로 취급하지 않습니다. - 메타 대화(`어떤 부분이 더 필요하신지...`)는 실패 기본 경로로 사용하지 않습니다. ## 5. 구현 단계 ### Phase 0. 운영 전제 재검증 - 확인 항목과 결과: | 항목 | 결과 | 상태 | |------|------|------| | Company X RAG 임베딩 차원 | `384d` 폐기, `Gemini Embedding 2 / 768d` 확정 (0_VALUE 정책) | **확정** | | SKILL.md 전제 | `384d` → `Gemini Embedding 2 / 768d` 갱신 완료 (2026-03-17) | **확정** | | 저장 경로 (rb8001 메모리) | PostgreSQL `memory_vectors` 등 중심 전환 확인 | **확정** | | 저장 경로 (skill-rag-file 문서 청크) | 현재 ChromaDB(`/app/chroma_db`) 저장 중. 운영 원칙(PostgreSQL 중심)과 불일치. PostgreSQL(pgvector)로 전환 필요 | **미완료** | | 인덱싱 파이프라인 | 현재 모든 파일을 텍스트 변환 후 청킹. Gemini Embedding 2의 멀티모달(PDF, 이미지, docx 등 직접 임베딩) 능력을 미활용. 원본 파일 직접 임베딩으로 전환 필요 | **미완료** | | NAS 동기화 경로 | NAS → skill-rag-file 반영 경로/시점 미확인. Phase 5에서 검증 후 Phase 0 표에 반영 | **미완료** | | 재오픈 질문 20개 재현 | Slack 실응답 재현 미실시 | **미완료** | - 현재 상태: - 임베딩/저장 전제는 확정됨. - NAS 동기화 경로와 질문 재현은 Phase 5에서 함께 검증. - 청킹 구조 개선(Gemini 2 PDF 직접 임베딩, 한국어 토큰 근사값)은 **별도 이슈로 분리해 추적**. 현재 텍스트 추출 + 문자 분할 방식으로 운영하되, 리스크로 기록. ### Phase 1. 구조 분리 - `companyx_grounding_service`에서 아래 책임을 분리합니다. - 질문 유형 판정 - query candidate 생성 - retrieval 결과 수집 - 근거 채택 판정 - direct answer 생성 - failure answer 생성 - 목표: - 현재 질문별 특례 분기와 generic fallback이 어디서 작동하는지 코드상 경계를 명확히 나눕니다. ### Phase 2. 질문 유형 계약 도입 - 최소 4개 유형 분류 함수를 추가합니다. - 재오픈 기준 질문 20개는 각 유형에 명시 매핑돼야 합니다. - 아래 3개는 대표 매핑 예시입니다. - `컴퍼니엑스의 투자사는 몇개야?` -> 수치 확인형 - `그럼 컴퍼니엑스 내부 규정 상 휴가는 얼마나 쓸 수 있어?` -> 사실 확인형 또는 규정 확인형 성격 - `오늘전통 프로그램을 Company X가 옐로펀치랑 같이 운영한다는 근거 있어?` -> 사실 확인형 ### Phase 3. 근거 채택 판정 추가 - 검색 결과를 그대로 상위 3개 노출하지 않습니다. - 질문 유형에 맞지 않는 청크는 버립니다. - 필요 최소 판정: - 엔티티 일치 여부 - 문서 성격 일치 여부 - 답변 가능 근거인지 여부 - `휴가` 질문에 `todaytradition` 청크가 잡히는 경우는 `무관한 결과`로 실패 처리해야 합니다. ### Phase 4. LLM 기반 답변 생성으로 전환 - 현재 `_build_direct_answer()` 규칙 문자열 조합을 LLM 호출로 대체합니다. - 플로우: 1. 근거 채택 판정을 통과한 청크를 컨텍스트로 조합 2. 질문 유형별 시스템 프롬프트 + 컨텍스트 + 사용자 질문을 LLM에 전달 3. LLM이 `직접 답 + 근거 문서명 + 요약` 형식으로 답변 생성 - 근거가 없거나 부족할 때는 LLM에게 `문서 없음 / 문서 미확인 / 단정 불가` 중 하나로만 답하도록 프롬프트로 강제합니다. - 질문별 하드코딩 문장을 추가하지 않습니다. ### Phase 5. 테스트 고정 및 검증 - **자동화 테스트** (코드): - 질문 유형 분류 정확성: 20개 질문 → 4유형 매핑 검증 - 근거 채택 판정: 무관한 청크 반환 시 `grounding_present=false` 확인 - 실패 응답 형식: generic 문장(`관련 근거를 찾았습니다`) 금지 확인 - 성공 응답 형식: `직접 답 + 근거 문서명 + 요약` 구조 확인 - **Slack 실응답 검증** (수동, 대표 5개): 1. `오늘전통 프로그램을 Company X가 옐로펀치랑 같이 운영한다는 근거 있어?` → 직접 답 + MOU 근거 2. `컴퍼니엑스의 투자사는 몇개야?` → 수치 답 또는 `단정 불가` 3. `내부 규정 상 휴가는 얼마나 쓸 수 있어?` → 규정 문서 확인 또는 `문서 미확인` 4. `X-COURSE가 뭐야?` → 설명 + 근거 문서 5. `근거 문서명만 다시 정리해줘` → 직전 근거 목록 재정리 - **종결 worklog**: 테스트 통과 + Slack 5개 검증 완료 시 종결 worklog 작성 - **Phase 0 갱신**: Phase 5에서 NAS 동기화 경로/시점 검증을 끝내면 Phase 0 표에 반영 - 테스트는 질문별 예외 성공이 아니라 공통 계약 준수 여부를 검증해야 합니다. - 현재 상태: **미완료** ## 6. 검증 기준 - Phase 0에서 아래가 먼저 확인돼야 합니다. 1. Company X RAG의 실제 임베딩 경로와 차원이 문서/런타임 기준으로 식별된다. 2. NAS 최신 문서 동기화본과 검색 컬렉션 반영 경로가 설명 가능해진다. 3. 재오픈 기준 질문 20개의 현재 실패 양상이 다시 재현된다. - 재오픈 기준 질문 20개에서 아래가 확인돼야 합니다. 1. 직접 답이 먼저 나온다. 2. 질문과 맞는 근거만 붙는다. 3. 근거가 부족하면 명시적으로 부족하다고 답한다. - `검색 hit 있음 = success` 경로가 제거돼야 합니다. - 질문별 특례 추가 없이도 재오픈 질문셋이 통과해야 합니다. - `SKILL.md` 요구사항과 실제 응답 형식이 일치해야 합니다. ## 7. 완료 판정 기준 1. [260312_companyx_rag_answer_composition_regression.md](../troubleshooting/260312_companyx_rag_answer_composition_regression.md)에서 정의한 재현 질문셋이 더 이상 회귀하지 않습니다. 2. [260312_companyx_내부문서_근거응답_사용자시나리오.md](../scenarios/260312_companyx_내부문서_근거응답_사용자시나리오.md)의 재오픈 기준 질문 20개가 기대 결과를 만족합니다. 3. Company X RAG의 현재 임베딩 경로/차원과 NAS 문서 반영 경로가 `research`에 최신 기준으로 반영됩니다. 4. `companyx_grounding_service`에 질문별 direct answer 특례를 추가하지 않고 공통 계약 구조로 바뀝니다. 5. 테스트가 추가되고 통과합니다. 6. 실행 결과는 `worklog 1건`으로 마감하고, 시나리오/트러블 문서와 양방향 링크를 연결합니다. ## 8. 후속 경계 - 이 계획이 닫혀도 Company X 전체 문서군 확대나 범용 RAG 정책 공통화는 별도 계획으로 다룹니다. - `Prompt DB`나 전역 오케스트레이션 구조 변경은 이번 계획 범위 밖입니다. ## 한 줄 결론 - 이번 계획은 `대표 질문 특례 처리 제거` 자체가 아니라, 현재 NAS 문서 운영 상태와 임베딩 전제를 다시 닫은 뒤 Company X 근거응답을 `질문 유형 계약 + 근거 채택 계약 + 실패 계약`으로 재구성해 시나리오와 트러블을 함께 닫는 작업입니다.