13장 · 임베딩과 벡터 DB왜 임베딩이 필요한가 — 청크는 있는데, 찾을 방법이 없다임베딩 — 뜻을 숫자 목록으로 바꾼다벡터 DB와 Chroma — 벡터를 저장하고 꺼내는 곳유사도 검색과 거리 읽기 — 점수는 작을수록 가깝다따라하기 — 청크를 벡터 DB에 넣고 검색하기정리와 체크리스트실습문제와 해답
13장. 임베딩과 벡터 DB
정리와 체크리스트
13장에서 배운 것
- 임베딩 — 글을 숫자 목록(벡터)으로 바꾸는 일. 뜻이 비슷하면 벡터가 가깝습니다.
- 차원 — 벡터의 길이.
gemini-embedding-001은 3,072입니다. - 코사인 유사도 — 두 벡터의 가까움. 클수록 가깝고 같은 문장이면 1입니다.
- 벡터 DB — 벡터를 저장하고 가까운 것을 찾아 주는 저장소. 우리는 Chroma를 씁니다.
- 색인 — 청크를 벡터로 바꿔 벡터 DB에 넣는 일. 미리 한 번 합니다.
- 유사도 검색 — 질문과 가까운 청크 k개를 가져옵니다. Chroma의 점수는 거리라서 작을수록 가깝습니다.
- 재색인 — 임베딩 모델을 바꾸면 벡터를 전부 다시 만들어야 합니다.
한눈에 보는 핵심
# 색인: 미리 한 번
vectorstore = Chroma.from_documents(
documents=docs, # 본문 + 메타데이터 + id
embedding=embeddings, # 어떤 임베딩 모델로
collection_name="haru_policy", # 컬렉션 이름
persist_directory=CHROMA_DIR, # chroma_db/ 폴더에 저장
)
# 검색: 질문마다
results = vectorstore.similarity_search_with_score(q, k=2) # (청크, 거리) 목록
| 누가 한 일인가 | 내용 |
|---|---|
| 임베딩 모델 | 글을 벡터로 바꿨습니다 |
| Chroma | 벡터를 저장하고, 거리를 계산해 가까운 것을 골랐습니다 |
| 우리(개발자) | 청크의 크기, 꼬리표를 붙이는 방법, id, k, 어떤 임베딩 모델을 쓸지를 정했습니다 |
| LLM | 이번 장에서는 아무 일도 하지 않았습니다 |
다음 장으로 넘어가기 전에
chroma_db/ 폴더가 있는지 확인합니다. 14장부터는 색인을 다시 하지 않고 이 폴더를 불러오기만 합니다. 폴더가 없거나 비어 있으면 14장의 검색은 오류 없이 청크 0개를 돌려주고, 모든 질문에 "확인되지 않는다"는 답이 나옵니다.
| 상황 | 할 일 |
|---|---|
chroma_db/가 없다 |
python lesson13_rag_embedding.py 실행 |
| 정책 PDF나 청킹 방법을 바꿨다 | chroma_db/ 폴더를 지우고 다시 실행 |
| 임베딩 모델을 바꿨다 | chroma_db/ 폴더를 지우고 다시 실행 (전체 재색인) |
| 바꾼 것 없이 한 번 더 실행했다 | 문제없습니다. 12개 그대로입니다 |
체크리스트
- [ ] 단어 검사로는 "택배비 누가 내요?"를 찾지 못하는 이유를 설명할 수 있다.
- [ ] 임베딩, 벡터, 차원이 무엇인지 각각 한 문장으로 말할 수 있다.
- [ ] 겹치는 단어가 없는 두 질문의 유사도가 0.872로 나온 것이 무엇을 뜻하는지 설명할 수 있다.
- [ ] 유사도와 거리의 방향이 반대라는 것, Chroma가 주는 점수가 어느 쪽인지 안다.
- [ ] 질문과 청크를 같은 임베딩 모델로 바꿔야 하는 이유를 지도 비유로 설명할 수 있다.
- [ ] 색인과 검색이 각각 언제 일어나는지, 임베딩 API가 각각 몇 번 호출되는지 말할 수 있다.
- [ ]
lesson13_rag_embedding.py를 다시 실행해도 청크가 24개가 되지 않는 이유를 설명할 수 있다. - [ ] 검색 1위의 꼬리표가 "제9조 (분쟁 처리)"였는데도 검색이 틀리지 않은 이유를 설명할 수 있다.
- [ ] 프로젝트 폴더에
chroma_db/가 만들어진 것을 확인했다.
한 줄 핵심
임베딩은 뜻을 숫자로 바꾸고, 벡터 DB는 그 숫자를 저장해 가까운 것을 찾아 줍니다. 찾아 준 것이 정말 답인지는 아직 아무도 확인하지 않았습니다.