RAG2026-5일10차시 · 벡터저장소 이해15 / 19← 이전목차다음 →MetaContents

10차시. 벡터저장소 이해

실습 1 — 벡터저장소 이해 실습 따라 하기

관련 수업 자료: 10차시 「3. 실습 ① — 인덱스 만들고 저장하기」(7쪽), 10차시 「4. 실습 ② — 불러와서 재사용하기」(9~10쪽) · 실습 코드 10/build_index.py, 10/load_index.py, 10/indexer.py

이 실습은 교안 해설(10_벡터저장소이해.md)의 실습 순서를 옮긴 것입니다. OpenAI 임베딩이나 채팅 모델을 부르는 파일은 .env 에 API 키가 있어야 돌아갑니다. 키가 없으면 실행 결과 샘플로 출력 모양을 확인합니다.

수업 자료와 이어지는 곳

실습 코드원본 PDF이어지는 내용
10/build_index.py7쪽10차시 「3. 실습 ① — 인덱스 만들고 저장하기」 아래에 실었습니다
10/load_index.py9쪽10차시 「4. 실습 ② — 불러와서 재사용하기」 아래에 실었습니다
10/indexer.py9~10쪽10차시 「4. 실습 ② — 불러와서 재사용하기」 › 4-1) 있으면 불러오고 없으면 만들기 아래에 실었습니다

실행 흐름

출력
faiss index가 있나 → load local  (있다)
faiss index가 있나 → 읽기 분할 임베딩  (없다)
읽기 분할 임베딩 → save local
save local → load local
load local → 질문 검색

실습 순서

키가 있으면 build_index.py로 저장하고, 같은 폴더에서 load_index.py를 다시 실행해 두 번째가 빠른지 봅니다. indexer.py는 그 분기를 함수로 감쌉니다.

스스로 확인

  • 인덱스를 질문마다 만들면 안 되는 이유를 아는가?
  • faiss 파일과 pkl 파일이 각각 무엇을 담는가?
  • 거리 점수와 유사도 점수를 섞어 읽으면 어떤 실수가 나는가?

코드 설명

  • store.save_local(INDEX_PATH) 는 폴더 하나에 index.faiss 와 index.pkl 을 씁니다. 벡터만으로는 원문을 복원할 수 없어서, 원문과 metadata는 .pkl에 따로 담깁니다.
  • FAISS.load_local(INDEX_PATH, emb, allow_dangerous_deserialization=True) 의 마지막 옵션을 빠뜨리면 ValueError가 납니다. pickle 파일은 열 때 코드가 실행될 수 있으므로 내가 만든 인덱스에만 씁니다.
  • load_local 에도 emb 를 넘기는 까닭은 질문을 임베딩해야 하기 때문입니다. 저장할 때와 다른 모델을 넘기면 오류 없이 엉뚱한 결과가 나옵니다. 여기서 많이들 헷갈리십니다.
  • load_index.py의 chunks = prepare_chuncks(DOC_PATH) 는 PDF를 다시 읽기만 하고 검색에는 쓰이지 않습니다. 실행 결과에 "로딩 완료"가 두 번 찍히는 것도 이 줄과 import 때문입니다.
  • indexer.py는 from datetime import datetime 으로 클래스를 가져왔으므로 datetime.now() 라고 써야 합니다. 지금처럼 datetime.datetime.now() 이면 폴더가 없어 새로 만드는 첫 실행에서 AttributeError가 납니다.
  • store.index.ntotal 은 FAISS 안에 든 벡터 개수입니다. 조각 하나에 벡터 하나이므로 조각 수와 같습니다.
← 이전 절10차시 · 체크리스트와 과제다음 절 →10차시 · 퀴즈 1 — 있으면 불러오고 없으면 만들기