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 설계서 점검표