Skip to content

[Week3] 스타듀밸리 위키 도메인 RAG 시스템 구현#18

Open
Parkhaeil wants to merge 3 commits into
mainfrom
Parkhaeil/week3-domain-rag
Open

[Week3] 스타듀밸리 위키 도메인 RAG 시스템 구현#18
Parkhaeil wants to merge 3 commits into
mainfrom
Parkhaeil/week3-domain-rag

Conversation

@Parkhaeil

Copy link
Copy Markdown
Collaborator

개요

스타듀밸리 한국어 위키를 데이터 소스로 하는 도메인 특화 RAG 시스템을 구현했습니다. 위키 크롤링 → 청킹 전략 비교 실험 → LangGraph 기반 2-step RAG 그래프까지 전 과정을 포함합니다.

구현 요약

파일 구조

assignments/Parkhaeil/week3/
├── data/
│   ├── crawl_wiki.py             # 스타듀밸리 한국어 위키 크롤러
│   └── docs_sample/              # 수집된 마크다운 24개
├── rag/
│   ├── base.py                   # RetrievalChain 추상 클래스 (FAISS 캐시 포함)
│   ├── wiki.py                   # WikiRetrievalChain (splitter_type 파라미터로 전략 전환)
│   └── utils.py                  # format_docs, format_source_list
├── eval/
│   └── test_questions.py         # Group A(verified 10개) / Group B(멀티홉 5개) 질문 풀
├── chunking_compare.ipynb        # 청킹 전략 비교 실험
└── run.ipynb                     # LangGraph RAG 메인 노트북

주요 설계

  • WikiRetrievalChainsplitter_type='recursive' | 'markdown_header' 파라미터를 두어 전략 전환 가능
  • FAISS 캐시를 전략별로 분리(.cache/faiss_index/stardew_wiki_{splitter_type}/)하여 비교 실험 시 재색인 없이 전환
  • GraphState: question / context / answer / source_docs / messages 5개 필드, MemorySaver 체크포인터
  • 답변 하단에 category + 파일명 형식 출처 자동 부착

청킹 전략 비교 결과 및 선택 이유

비교 대상: RecursiveCharacterTextSplitter vs MarkdownHeaderTextSplitter

청크 통계

기준 RecursiveCharacterTextSplitter MarkdownHeaderTextSplitter
청크 수 1,655개 339개
평균 크기 503자 2,303자
중앙값 크기 541자 1,275자

쿼리별 비교

쿼리 Recursive 결과 MarkdownHeader 결과
Q1: 양조통 재료·산출물 farming_keg.md 728자 청크 — 기본 정보 포함 farming_keg.md 전체 섹션 1,645자 — 재료·산출물 대응표 온전히 보존
Q2: 봄 작물 성장 기간 상위 결과가 7자(## 봄 작물), 5자(### 봄) 등 헤더만 잘린 무의미 청크 farming_crops_spring.md 봄 시즌 전체 컨텍스트 정상 검색
Q3: 낚시 미끼 종류·효과 farming_keg.md 등 관련 없는 문서에서 "미끼" 언급 부분 상위 노출 fishing_tackle.md § 미끼 아이템 2,099자 효과 상세표 온전히 검색

채택: MarkdownHeaderTextSplitter

Q2에서 Recursive가 7자·5자짜리 헤더만 남은 빈 청크를 상위로 올린 것이 결정적이었습니다. chunk_size=800으로 자를 때 헤더 바로 뒤 내용이 다음 청크로 넘어가면서 헤더만 남은 조각이 생성된 것으로, 검색 결과로 활용 불가능한 수준이었습니다.

반면 MarkdownHeaderTextSplitter는 위키 문서의 섹션 구조를 그대로 보존합니다. Q1의 재료-산출물 대응표(1,645자)와 Q3의 미끼 효과 상세표(2,099자)가 각각 단일 청크로 검색되어 LLM이 완전한 정보를 받을 수 있었습니다.

단점으로 평균 청크 크기가 2,303자로 커서 LLM 입력 토큰이 늘고, 최대 3,641자짜리 청크도 존재합니다. 그러나 스타듀밸리 위키처럼 헤더 단위로 정보가 명확히 구분된 문서에서는 구조 보존의 이점이 토큰 비용을 상쇄한다고 판단했습니다.

실행 결과

데이터 수집

  • crawl_wiki.pyko.stardewvalleywiki.com에서 24개 마크다운 수집
  • 카테고리: 농사(9), 낚시(3), 광산(3), 축산(3), 주민(2), 제작(1), 채집(1)

인덱싱

Loaded 24 documents, 0 failed.
Split into 339 chunks (markdown_header)
FAISS index saved to cache

Group A 테스트 (6개 최종 질문, 모두 verified)

테스트 대상 질문:

  1. 양조통(술통)에 넣을 수 있는 재료와 각각 만들어지는 제품은? → farming_keg.md
  2. 고대씨앗은 어떻게 얻고, 어디에 심을 수 있나? → farming_ancient_seed.md
  3. 온실에 심은 작물은 계절 제한이 있나? → farming_greenhouse.md
  4. 낚싯대에 미끼를 끼우는 방법은? → fishing_tackle.md
  5. 일반 달걀과 큰 달걀을 마요네즈 기계에 넣으면 품질이 다르게 나오나? → livestock_mayonnaise.md
  6. 스타듀밸리에서 결혼 조건과 절차는? → villagers_marriage.md

모든 질문이 예상 문서에서 검색되어 답변에 문서 출처가 정상 출력되었습니다.

Group B 테스트 (RAG 실패 케이스 관찰)

  • 수집 문서에 없는 정보(상자 소실 원인, 판매처 비교)는 "모른다"고 응답
  • 멀티홉 질문(가축 먹이 + 겨울 자동 공급)은 단일 문서로 불완전한 답변 → 다음 주 Agentic RAG 빌드업 소재로 분류

PGVector

  • psycopg2 미설치로 인한 에러 발생. FAISS 캐시 기반 베이스라인으로 대체.
  • 트레이드오프 정리는 run.ipynb 셀 9에 테이블로 문서화.

다음 주 연결 포인트

Group B 질문들(멀티홉, 문서 부재)이 다음 주 Agentic RAG — groundedness check, query rewrite, web search fallback — 의 직접적인 입력 소재가 됩니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants