From 9f8fa2183028bcbbf4c89619342e1f2c220147fa Mon Sep 17 00:00:00 2001 From: happybell80 Date: Sat, 21 Mar 2026 16:41:17 +0900 Subject: [PATCH] =?UTF-8?q?RAG=20=EC=9B=8C=ED=81=AC=ED=94=8C=EB=A1=9C?= =?UTF-8?q?=EC=9A=B0=20=EC=A0=95=EB=B9=84:=203=EC=A4=91=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EB=B0=98=EC=98=81=20+=20=EB=8B=A8=EA=B3=84?= =?UTF-8?q?=EB=B3=84=20=EC=A6=9D=EB=B6=84=20=EC=9D=B8=EB=8D=B1=EC=8B=B1=20?= =?UTF-8?q?=EC=9B=8C=ED=81=AC=ED=94=8C=EB=A1=9C=EC=9A=B0=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - companyx_grounding_pipeline: team_id 기반 라우팅, 멀티쿼리, hybrid RRF 반영 - rag_search_grounding_request: search_mode, threshold, 점수 필드 추가 - rag_upload_indexing_pipeline: 청킹/임베딩/tsvector 기준 명시 - companyx_incremental_indexing_workflow: 200→2000→5000 단계별 실행 흐름 (신규) - README: 인덱스에 증분 인덱싱 워크플로우 추가 Co-Authored-By: Claude Opus 4.6 --- workflow/03_rag/README.md | 1 + .../03_rag/companyx_grounding_pipeline.md | 23 ++++--- .../companyx_incremental_indexing_workflow.md | 63 +++++++++++++++++++ .../03_rag/rag_search_grounding_request.md | 11 ++-- .../03_rag/rag_upload_indexing_pipeline.md | 13 +++- 5 files changed, 97 insertions(+), 14 deletions(-) create mode 100644 workflow/03_rag/companyx_incremental_indexing_workflow.md diff --git a/workflow/03_rag/README.md b/workflow/03_rag/README.md index 216ab05..8450f9c 100644 --- a/workflow/03_rag/README.md +++ b/workflow/03_rag/README.md @@ -23,6 +23,7 @@ tags: [workflow, rag, companyx, grounding, ssot] 3. [RAG 검색·Grounding 요청](./rag_search_grounding_request.md) 4. [Company X Grounding 파이프라인](./companyx_grounding_pipeline.md) 5. [Markdown 중간표현 SSOT 요약](./markdown_intermediate_ssot.md) +6. [Company X 단계별 증분 인덱싱 워크플로우](./companyx_incremental_indexing_workflow.md) ## 공통 운영 원칙 - 문서는 JSON보다 먼저 읽는 실행 기준이다. diff --git a/workflow/03_rag/companyx_grounding_pipeline.md b/workflow/03_rag/companyx_grounding_pipeline.md index 393fc02..57cbbfc 100644 --- a/workflow/03_rag/companyx_grounding_pipeline.md +++ b/workflow/03_rag/companyx_grounding_pipeline.md @@ -25,16 +25,25 @@ tags: [workflow, rag, companyx, grounding, answer] - 근거 부족 시 명시적 실패 응답 ## 처리 순서 -1. 질문이 Company X 근거응답 대상인지 판단한다. -2. 벡터 유사도 검색으로 상위 결과를 수집한다. -3. 검색 결과를 LLM에 컨텍스트로 전달하고, LLM이 질문 적합도를 판단해 답변한다. -4. LLM 응답을 Pydantic으로 검증한다. -5. 근거가 부족하면 LLM이 `failure_reason`을 명시하고, 추정 답변 대신 실패 응답으로 끝낸다. +1. `team_id == COMPANYX_TEAM_ID`이면 grounding 경로로 진입한다. 마커 체크 없이 team_id 기반으로 판단한다. +2. 질문 유형을 분류한다 (설명형/사실확인형/수치확인형/재정리형). +3. 멀티쿼리를 생성한다 (`_build_query_candidates()`, 7~9개 변형). +4. 하이브리드 검색(벡터+키워드 RRF, search_mode=hybrid)으로 상위 결과를 수집한다. +5. 검색 결과를 LLM에 컨텍스트로 전달하고, LLM이 질문 적합도를 판단해 답변한다. +6. LLM 응답을 Pydantic(`CompanyXRAGOutput`)으로 검증한다. +7. 근거가 부족하면 LLM이 `failure_reason`을 명시하고, 추정 답변 대신 실패 응답으로 끝낸다. + +## 검색 모드 +- 기본 검색 모드는 `hybrid`이다 (벡터+키워드 RRF 합산). +- 벡터 검색: PGVector cosine similarity (Gemini Embedding 2, 768d). +- 키워드 검색: PostgreSQL tsvector + GIN 인덱스, prefix 매칭(`:*`). +- 점수 합산: RRF (Reciprocal Rank Fusion, k=60), 정규화하여 0~1 범위로 반환. +- Apache AGE 그래프 점수는 hook으로 가산 가능 (현재 보조적 위치). ## 근거 선별 원칙 - 키워드 기반 룰로 검색 결과를 필터링하지 않는다 (룰베이스 절제 원칙 — global-principles.md §B.6). -- 벡터 검색이 반환한 유사도 순서를 신뢰하고, LLM이 컨텍스트를 보고 적합도를 재판단한다. -- 근거 선별 책임은 LLM에 있으며, 코드 레벨에서는 유사도 상위 결과를 문서 다양성 기준으로 선택만 한다. +- 하이브리드 검색이 반환한 RRF 정규화 점수 순서를 신뢰하고, LLM이 컨텍스트를 보고 적합도를 재판단한다. +- 근거 선별 책임은 LLM에 있으며, 코드 레벨에서는 점수 상위 결과를 문서 다양성 기준으로 선택만 한다. ## 실패 분기 - 검색 결과가 0건이면 `문서 없음`으로 실패한다. diff --git a/workflow/03_rag/companyx_incremental_indexing_workflow.md b/workflow/03_rag/companyx_incremental_indexing_workflow.md new file mode 100644 index 0000000..280bc4a --- /dev/null +++ b/workflow/03_rag/companyx_incremental_indexing_workflow.md @@ -0,0 +1,63 @@ +tags: [workflow, rag, companyx, indexing, batch, incremental] + +# Company X 단계별 증분 인덱싱 워크플로우 + +## 목적 +- NAS 원본 문서에서 대상을 선정하고, 단계별로 인덱싱을 확장하며, 각 단계마다 검색·grounding 품질을 검증한 뒤 다음 단계로 진입하는 상위 실행 흐름을 고정한다. + +## 상위 원칙 +- [RAG Workflow Index](./README.md) +- [writing-principles.md](../../../../0_VALUE/02_Governance/writing-principles.md) + +## 단계 정의 + +| 단계 | 대상 수 | mtime 컷오프 | 상태 | +|------|--------:|--------------|------| +| 0단계 | 200 | 수동 선정 (`latest_200_companyx.txt`) | 완료 | +| 1단계 | 2,000 | `2026-01-28` 이후 | 미착수 | +| 2단계 | 5,000 | `2025-11-30` 이후 | 미착수 | + +- mtime 컷오프 근거: [NAS 정보 종합 리서치](../../../../infra/DOCS/journey/research/260321_companyx_nas_정보_종합_리서치.md) + +## 실행 순서 + +각 단계는 아래 순서를 반복한다. + +### 1. 대상 선정 +- NAS 원본 경로(`/mnt/nas/workspace/6.Company X`)에서 mtime 기준으로 대상 파일 목록을 생성한다. +- 이전 단계에서 이미 인덱싱된 파일은 제외한다 (증분). +- NAS 접속 절차: [51123 Remote Workspace Operations](../../../../infra/DOCS/workflow/51123_remote_workspace_operations_workflow.md) + +### 2. 인덱싱 실행 +- 대상 파일을 배치 스크립트로 업로드·인덱싱한다. +- 단위 절차: [RAG 업로드·인덱싱 파이프라인](./rag_upload_indexing_pipeline.md) + +### 3. 검색 검증 +- 단계별 대표 질문셋으로 하이브리드 검색(벡터+키워드+그래프) 적중을 확인한다. +- 검색 절차: [RAG 검색·Grounding 요청](./rag_search_grounding_request.md) + +### 4. Grounding 검증 +- 대표 질문셋으로 근거 답변 품질을 확인한다. +- Grounding 절차: [Company X Grounding 파이프라인](./companyx_grounding_pipeline.md) + +### 5. 다음 단계 진입 조건 +- 대표 질문셋 적중률이 이전 단계 수준을 유지하거나 개선돼야 한다. +- grounding 실패율이 증가하면 원인 분석 후 다음 단계를 보류한다. +- 인덱싱 오류(텍스트 추출 실패, 임베딩 실패)가 전체 대상의 5%를 넘으면 원인을 해소한 뒤 재실행한다. + +## 실패 분기 +- NAS 마운트 불가 시 대상 선정 단계에서 중단한다. +- 인덱싱 배치 중 부분 실패는 실패 파일 목록을 남기고, 성공분만으로 검증을 진행한다. +- 검증 품질이 이전 단계보다 떨어지면 다음 단계로 넘어가지 않는다. + +## 0단계 (200개) 검증 결과 +- 16개 대표 질문 전수 PASS (260321) +- grounding 11/18 성공 +- 상세: [로빙 다형식문서 RAG 적용 1차 계획](../../journey/plans/260320_로빙_다형식문서_RAG_적용1_계획.md) + +## 관련 문서 +- [RAG 업로드·인덱싱 파이프라인](./rag_upload_indexing_pipeline.md) +- [RAG 검색·Grounding 요청](./rag_search_grounding_request.md) +- [Company X Grounding 파이프라인](./companyx_grounding_pipeline.md) +- [NAS 정보 종합 리서치](../../../../infra/DOCS/journey/research/260321_companyx_nas_정보_종합_리서치.md) +- [하이브리드검색 품질개선 계획](../../journey/plans/260321_하이브리드검색_품질개선_계획.md) diff --git a/workflow/03_rag/rag_search_grounding_request.md b/workflow/03_rag/rag_search_grounding_request.md index 19f3fac..34042af 100644 --- a/workflow/03_rag/rag_search_grounding_request.md +++ b/workflow/03_rag/rag_search_grounding_request.md @@ -16,18 +16,21 @@ tags: [workflow, rag, companyx, search, grounding] - 사용자 식별자 - 검색 제한값 - Company X 대상 여부 +- `search_mode`: `vector` | `keyword` | `hybrid` (기본 `hybrid`) +- `threshold`: 검색 모드별 최소 점수 (vector 0.35, keyword 0.001, hybrid RRF 정규화) ## 출력 -- 검색 결과 목록 +- 검색 결과 목록 (각 항목에 `vector_score`, `keyword_score`, `rrf_score`, `graph_score` 포함) - 검색 결과 수 - 근거 문서 후보 - 0건 또는 오류 시 실패 상태 ## 처리 순서 1. 질문과 사용자 정보를 받는다. -2. Company X 대상이면 Company X 컬렉션 우선으로 검색한다. -3. 검색 결과를 답변 프롬프트에 넣을 수 있는 형태로 정리한다. -4. 근거 문서 후보를 로빙 답변 경로에 전달한다. +2. Company X 대상이면 Company X 팀 컬렉션(team_id)으로 검색한다. +3. `search_mode=hybrid`이면 벡터+키워드 RRF 합산 검색을 수행한다. +4. 검색 결과를 답변 프롬프트에 넣을 수 있는 형태로 정리한다. +5. 근거 문서 후보를 로빙 답변 경로에 전달한다. ## 실패 분기 - 검색 결과가 0건이면 `문서 없음` 또는 `미확인`으로 넘길 수 있어야 한다. diff --git a/workflow/03_rag/rag_upload_indexing_pipeline.md b/workflow/03_rag/rag_upload_indexing_pipeline.md index 4e67aaa..2af92af 100644 --- a/workflow/03_rag/rag_upload_indexing_pipeline.md +++ b/workflow/03_rag/rag_upload_indexing_pipeline.md @@ -26,8 +26,11 @@ tags: [workflow, rag, companyx, upload, indexing] ## 처리 순서 1. 요청 페이로드를 정규화한다. 2. 원본 문서를 `skill-rag-file` 업로드 엔드포인트로 전달한다. -3. 텍스트 추출, 청킹, 임베딩, 저장을 수행한다. -4. 저장 결과를 그대로 반환한다. +3. 텍스트 추출을 수행한다. OCR 대상(이미지 PDF 등)은 OCR 폴백 경로로 처리한다. +4. 청킹한다 (기준: 1,000자 chunk, 200자 overlap). +5. 임베딩한다 (Gemini Embedding 2, 768d). +6. DB 저장 시 `tsvector` 컬럼이 트리거로 자동 생성된다 (`simple` 설정). +7. 저장 결과를 그대로 반환한다. ## 실패 분기 - 파일 누락이면 업로드 전에 실패한다. @@ -37,8 +40,12 @@ tags: [workflow, rag, companyx, upload, indexing] ## 현재 기준 - RAG 인덱싱은 `skill-rag-file`이 담당한다. -- Company X 문서는 일반 업로드와 섞이지 않도록 팀/컬렉션 경계를 분리한다. +- Company X 문서는 `team_id`(`79441171-3951-4870-beb8-916d07fe8be5`) 경계로 분리한다. - 검색 가능한 상태가 되기 전까지는 Grounding 파이프라인에 연결하지 않는다. +- 청킹 기준: 1,000자 chunk, 200자 overlap. +- 임베딩: Gemini Embedding 2, 768차원, HNSW cosine 인덱스. +- `tsvector` 컬럼은 INSERT/UPDATE 트리거로 자동 생성된다 (`simple` 설정, GIN 인덱스). +- 배치 인덱싱 스크립트: `skill-rag-file/scripts/reindex_companyx_latest_200.py` (200개 기준). ## 검증 기준 - 업로드 직후 검색 API로 최소 1건 이상 적중하는지 확인한다.