문서를 잘라 벡터로 바꿔 Chroma에 넣는 색인 단계와, 질문 하나가 검색 | 프롬프트 | 모델 | 파서 를 지나며 답이 되는 질의 단계를 한 단계씩 따라갑니다.
질문 "연차 이월은 며칠까지 가능한가요?" 가 문자열에서 dict, 메시지, 답 문자열로 모양을 바꾸는 과정을 실제 코드 줄과 함께 봅니다.
가운데의 dict를 만드는 45행만 RAG에서 새로 등장하는 부분이고, 그 뒤의 prompt | llm | StrOutputParser() 는 1일차의 체인과 같습니다. dict의 context 칸은 검색기와 format_docs 를 거친 문자열, question 칸은 질문 원문입니다.
day2_practice 안에서 실행해야 합니다. metadata.py 는 "docs/leave_policy.md", 벡터 DB를 여는 파일들은 "./chroma_db" 를 터미널의 현재 폴더 기준으로 찾습니다. (loaders.py 만 Path(__file__).parent 로 경로를 만듭니다.)vectorstore.py 를 다시 돌리면 같은 청크가 한 벌 더 쌓입니다. 청크 ID를 지정하지 않으므로 실행할 때마다 새 ID로 추가됩니다. 사본인 load_db.py 까지 실행해도 마찬가지입니다. 다시 색인하려면 13~17행의 주석을 풀어 컬렉션을 지우거나 chroma_db 폴더를 지웁니다.rag_chain.py 가 DB를 열 때 embedding_function 을 다시 넘기는 것은 질문을 벡터로 바꿀 모델이 DB 안에 들어 있지 않기 때문입니다. 모델이 다르면 두 벡터의 거리 계산이 무의미해집니다.(출처: docs/leave_policy.md) 라고 쓸 수 있는 것은 format_docs 가 청크 앞에 [docs/leave_policy.md] 를 글자로 붙였기 때문입니다. 부서나 개정일은 프롬프트에 들어가지 않습니다.verify_sources.py 는 같은 검색을 두 번 합니다. answer 쪽의 rag_chain 안에서 한 번, sources 쪽에서 한 번입니다. 그리고 sources 는 검색된 문서의 목록이지 모델이 실제로 근거로 삼은 문서의 목록이 아닙니다.| 파일 | 단계 | 하는 일 |
|---|---|---|
loaders.py | 색인 | TextLoader 로 파일 하나, DirectoryLoader 로 폴더 전체를 Document 리스트로 읽어 보는 확인용 스크립트 |
metadata.py | 색인 | 부서·개정일을 붙이고 300자/겹침 50으로 자르는 load_chunks() 정의 |
vectorstore.py | 색인 | 청크를 임베딩해 Chroma 컬렉션 sds_policies 에 저장하고 거리 점수와 필터 검색을 확인 (load_db.py 는 사본) |
retriever.py | 질의 | 저장된 DB를 열어 검색기로 만들고 k 값과 MMR에 따른 차이를 관찰 |
rag_chain.py | 질의 | 검색기, 프롬프트, 모델, 파서를 이은 RAG 체인. 다른 파일들이 import 해서 재사용 |
verify.py | 검증 | 같은 질문을 RAG 없이, RAG로 던져 비교. 문서에 없는 질문 포함 |
verify_sources.py | 검증 | RunnableParallel 로 답과 검색된 근거 문서 목록을 함께 반환 |
docs/*.md | 재료 | 연차·재택근무·출장 규정 세 편 (교육용 더미 데이터) |