107 lines
7.8 KiB
Markdown
107 lines
7.8 KiB
Markdown
# RAG 설계 가이드 (RAG 아키텍처 설계서를 쓰기 위해)
|
|
|
|
원본 평가 기준은 RAG를 세 가지로 봅니다: ① 문서 특성에 맞는 **청킹**과 근거 ② **임베딩 모델** 선정 이유 · 차원 · 거리 방식 ③ **인덱스 운영**(명명 · 파티션 · 메타데이터 · 백업 · 복구 · 확장). ①②는 직접 재서 쓰고, ③은 오늘 쓰는 저장소로 **할 수 있는 것은 구현**하고 **운영 규모의 것은 설계**로 씁니다.
|
|
|
|
## 1. 오늘 쓸 수 있는 것 (71일차와 같음)
|
|
|
|
| 부품 | n8n 노드 | 특징 |
|
|
| --- | --- | --- |
|
|
| 문서 가져오기 | HTTP Request `GET /docs` · `/docs/<name>`, 팀 문서는 Read Files 또는 Code | 마크다운, `##` 절 |
|
|
| 청크 만들기 | Code (팀이 직접 나눔) | 71일차: 절 단위(`section`) 또는 글자 수 |
|
|
| 임베딩 | Embeddings OpenAI `text-embedding-3-large` | 3072차원 (OpenAI 문서 기준, 줄일 수 있음) |
|
|
| 저장 · 검색 | Vector Store (In-Memory) | **n8n이 다시 켜지면 사라짐**, 메모리 키(`memoryKey`)로 여러 컬렉션 |
|
|
| (가산) 지속형 | PGVector · Qdrant · Pinecone 등 Vector Store 노드 | 별도 서버 · 계정 필요 |
|
|
|
|
> In-Memory 저장소는 n8n을 다시 켜면 비어 있습니다. 그래서 **색인 워크플로우(`<팀>-index`)가 언제든 처음부터 다시 만들 수 있어야** 합니다. 원본 문서가 진짜 원본(source of truth)이고, 벡터 저장소는 언제든 다시 만들 수 있는 사본입니다. 이것이 오늘의 "복구 정책"의 출발점입니다.
|
|
|
|
## 2. 원본 문서 분석 (설계서 1절)
|
|
|
|
청킹을 정하기 전에 문서를 봅니다. **재서** 표를 채웁니다 (실습 키트 `scripts/chunk_stats.py`가 문서 · 절 · 글자 수를 셉니다).
|
|
|
|
| 볼 것 | 왜 | 오늘 문서의 모양 (직접 재서 채움) |
|
|
| --- | --- | --- |
|
|
| 문서 수 · 길이 | 청크 수와 비용 | 8개 + 팀 문서 |
|
|
| 구조 | 나눌 자리 | `#` 제목 → `##` 절 → 글머리표 |
|
|
| 절 하나의 길이 | 절 단위가 너무 길거나 짧지 않은지 | 글자 수의 최소 · 중앙 · 최대 |
|
|
| 언어 | 임베딩 모델 선택 | 한국어 중심, 영문 용어(VPN · MFA) |
|
|
| 표 · 코드 | 따로 다룰지 | (있으면) |
|
|
| 갱신 주기 · 권한 | 재색인 · 메타데이터 | 팀이 정함 |
|
|
|
|
## 3. 청킹 (설계서 2절)
|
|
|
|
| 방식 | 장점 | 단점 | 어울리는 문서 |
|
|
| --- | --- | --- | --- |
|
|
| 문서 하나 = 청크 하나 | 단순 | 길면 검색이 흐려짐, 근거가 넓음 | 아주 짧은 FAQ |
|
|
| 절(`##`) 단위 | 의미 단위가 지켜짐, 근거를 절로 보여 줌 | 절 길이가 들쭉날쭉 | 규정 문서 (오늘) |
|
|
| 글자 · 토큰 수 + 오버랩 | 길이가 고름 | 문장 · 절차 중간이 잘림 | 긴 일반 글 |
|
|
| 절 + 길면 다시 나눔 (하이브리드) | 둘의 장점 | 구현이 조금 더 | 길이가 섞인 문서 |
|
|
| 의미 단위 (문장 임베딩 거리로) | 주제 경계가 정확 | 비용 · 구현 | 대용량 |
|
|
|
|
**근거는 숫자로.** "절 단위가 좋다"가 아니라, 71일차처럼 **같은 질문 세트로 두 방식을 재서** 비교합니다.
|
|
|
|
| 재는 것 | 방법 |
|
|
| --- | --- |
|
|
| 청크 수 · 길이 분포 | `chunk_stats.py --chunking section` / `--chunking 300` |
|
|
| 검색 정확도 | 질문 10개 × "기대 문서가 top_k 안에 들어왔나" (hit@k) |
|
|
| 답 품질 | 공통 시나리오 WF-01 · WF-12 · 팀 시나리오의 통과 수 |
|
|
|
|
- 청크 앞에 **문서 제목 · 절 제목을 붙이면** 검색이 문서를 더 잘 찾습니다 (71일차).
|
|
- 오버랩은 "글자 수로 자를 때" 의미가 있습니다. 절 단위면 보통 0이고, 그 까닭을 씁니다.
|
|
- 원본 요구의 예시(500토큰 · 오버랩 80)는 **예시**입니다. 우리 문서의 절은 그보다 훨씬 짧을 수 있습니다. 재 본 길이로 정합니다.
|
|
|
|
## 4. 임베딩 (설계서 3절)
|
|
|
|
| 칸 | 쓸 것 |
|
|
| --- | --- |
|
|
| 사용 모델 | `text-embedding-3-large` (과정 기본) 또는 팀이 비교한 모델 |
|
|
| 선정 이유 | 성능 (한국어 · 영어 혼합 검색 결과), 다국어, 도메인 용어, **비용** (토큰 단가 × 색인 토큰 수), 이미 쓰는 Credential |
|
|
| 벡터 차원 | 실제 값 (노드 · 모델 문서에서 확인한 값, 줄였다면 그 값) |
|
|
| 거리 방식 | 저장소가 쓰는 방식 (In-Memory는 코사인 유사도 기반 점수, 클수록 가까움). 정규화된 벡터에서 코사인과 유클리드 순위가 같은 까닭을 한 줄 |
|
|
| `top_k` | 재서 정함 (예: 3 · 5 비교) |
|
|
| 점수 기준 | 이 점수 미만은 근거로 쓰지 않음 → "검색 결과 없음" 분기 (WF-03), **재서 정한 값** |
|
|
|
|
- 비교할 모델이 있다면 같은 질문 세트로 hit@k와 비용을 표로 둡니다. 오늘 Credential로 쓸 수 있는 것은 OpenAI 모델입니다 (`text-embedding-3-small` vs `-large` 비교가 가장 쉬움). bge · multilingual-e5 같은 공개 모델은 설계서에서 "운영에서 검토할 후보"로 장단점을 써도 됩니다.
|
|
|
|
## 5. 컬렉션 · 인덱스 명명 (설계서 4절)
|
|
|
|
| 규칙 | 예 | In-Memory에서 |
|
|
| --- | --- | --- |
|
|
| `<도메인>_<용도>_v<버전>` | `tech_support_kb_v1` | Vector Store의 메모리 키 |
|
|
| 버전을 올려 새로 만들고, 검증 뒤 바꿈 (alias 전환) | `v1` → `v2` | 검색 워크플로우가 읽는 메모리 키를 설정 한 곳(Code 또는 데이터 API `/cache/active_kb`)에서 바꿈 |
|
|
| 이전 버전은 바로 지우지 않음 | `v1` 보관 | 메모리 키 두 개 공존 |
|
|
|
|
## 6. 메타데이터 · 권한 · 파티션 (설계서 4절)
|
|
|
|
| 메타데이터 | 쓰임 |
|
|
| --- | --- |
|
|
| `doc`, `title`, `section`, `chunk` | 근거 표시 (`sources`) |
|
|
| `access_level` (`all` · `it`) | **검색 전** 권한 필터 (WF-05) |
|
|
| `type` (`network` · `account` · …) | 분류 결과로 검색 범위 좁히기 |
|
|
| `updated_at`, `version` | 재색인 · 오래된 근거 경고 |
|
|
| `source_url` | 원문 링크 |
|
|
|
|
- In-Memory 저장소에서 메타데이터 필터가 어려우면, **권한별로 메모리 키를 나눕니다** (`tech_support_kb_v1_all`, `tech_support_kb_v1_it`). 이것이 작은 규모의 "파티션"입니다. 사용자 권한에 맞는 키만 검색합니다.
|
|
- 운영 규모의 파티션 · 샤딩(제품군 · 조직 · 언어별, 큰 컬렉션을 여러 노드에 나눔)은 설계서에 "데이터가 늘면" 절로 씁니다.
|
|
|
|
## 7. 백업 · 복구 · 확장 (설계서 5절)
|
|
|
|
| 항목 | 오늘 구현할 것 | 설계서에 쓸 것 (운영) |
|
|
| --- | --- | --- |
|
|
| 원본 백업 | 지식 문서 · 팀 문서는 **git 저장소**가 원본 | 문서 저장소의 백업 주기 |
|
|
| 색인 복구 | `<팀>-index`를 부르면 처음부터 다시 만듦 (몇 초 · 몇 청크 · 비용을 잼) | 지속형 저장소의 스냅숏 · 복원 절차 |
|
|
| 롤백 | 새 버전 검증 실패 → 메모리 키를 이전 버전으로 | alias 되돌리기 |
|
|
| 부분 재처리 | 실패한 문서만 다시 (색인 결과에 문서별 성공 · 실패) | 배치 · 대기열 |
|
|
| 확장 | — | 문서 수 × 10 · × 100일 때 색인 시간 · 비용 · 저장소 크기 어림, 지속형 저장소 · 배치 임베딩 · 파티션 |
|
|
|
|
- 확장 어림은 **오늘 잰 값에서** 계산합니다 (예: "청크 N개 색인에 T초 · 토큰 X개 → 문서 100배면 …"). 숫자 없이 "확장 가능하다"는 평가 기준을 채우지 못합니다.
|
|
|
|
## 8. RAG 설계서 점검표
|
|
|
|
- [ ] 문서 분석 표를 **잰 값**으로 채웠다
|
|
- [ ] 청킹 방식 두 가지 이상을 같은 질문으로 비교했다 (청크 수 · 길이 분포 · hit@k)
|
|
- [ ] 임베딩 모델 · 차원 · 거리 방식 · top_k · 점수 기준과 그 근거
|
|
- [ ] 컬렉션 명명 · 버전 · 전환 방법
|
|
- [ ] 메타데이터와 권한 필터 (검색 전)
|
|
- [ ] 색인을 처음부터 다시 만드는 시간 · 비용을 쟀다, 롤백 방법
|
|
- [ ] 데이터가 늘었을 때의 어림 (오늘 숫자에서)
|