Embedding
텍스트를 벡터(Vector)로 변환
텍스트를 모델이 처리할 수 있게 토큰화하고,
사전학습 언어모델이 문맥을 반영해 벡터 표현을 생성.
둘의 유사도를 비교해 관련 문서 검색
같은 텍스트에 대해 임베딩을 다시 계산하지 않도록 결과를 저장(캐시)
작동 방식
저장 방식
| 구분 | LocalFileStore | InMemoryByteStore |
|---|---|---|
| 성격 | 영구 보관 (Persistent) | 비영구 보관 (Volatile) |
| 저장 위치 | 컴퓨터의 하드 디스크 (폴더) | 컴퓨터의 RAM (메모리) |
| 특징 | 프로그램을 껐다 켜도 데이터가 남아있음 | 프로그램을 끄면 데이터가 즉시 사라짐 |
| 용도 | 비용 절감, 운영(Production) 환경, 재사용 | 테스트, 빠른 속도 필요, 일회성 작업 |
모델이 다르면 벡터도 다르므로,
namespace 에 모델 이름을 명시해 다른 캐시 공간을 쓰도록 격리
Hugging Face의 엔드포인트에 API로 요청해서 임베딩 벡터를 받아오는 방식
Dense Vector (밀집 임베딩)
문서/쿼리를 연속값 벡터로 표현해서 의미 유사도를 계산.
문맥, 의미 파악
Sparse Embedding (Lexical Weight, 희소 임베딩)
대부분 값이 0인 고차원 벡터로 문서/쿼리를 표현.
단어별 중요도(lexical weight)를 써서 정확한 단어 매칭을 강화.
VectorStore
임베딩 벡터를 효율적으로 저장하고 Indexing하는 시스템
- 확장성 (Scalability)
- 빠른 검색 속도
- 의미 검색 (Semantic Search)
벡터 저장, 관리, 검색이 가능한 데이터베이스
밀집 벡터들 사이의 유사도 검색, 클러스터링을 효율적으로 수행하기 위한 라이브러리
클라우드 벡터 DB
Sparse Vector : 정확한 키워드 일치를 파악
↔︎ Dense Vector : 문맥과 의미를 파악
Retriever
사용자의 질문과 가장 관련된 정보를 벡터 DB에서 검색
검색 방식: Sparse vs Dense
① Sparse Retriever (키워드 중심)
문서/질문을 단어(키워드) 기반의 희소 벡터로 표현
주요 기법:TF-IDF, BM25
② Dense Retriever (의미 중심)
문서/질문을 딥러닝 임베딩으로 연속적인 dense 벡터로 표현
코사인 유사도 등으로 근접한 벡터를 찾음
벡터 저장소 내부에 구현된 유사도 검색이나 MMR 알고리즘을 활용하여,
질문에 맞는 텍스트를 찾아옴
similarity
MMR (Maximal Marginal Relevance)
similarity_score_threshold (유사도 임계값)
검색된 문서를 그대로 반환하지 않고,
query 기준으로 문서를 압축해서 관련 부분만 반환
작동 원리
① LLMChainFilter
초기 검색 결과 문서들 중에서 어떤 문서를 선택할지를 LLM 체인으로 판단
② EmbeddingsFilter
쿼리와 각 문서를 임베딩한 뒤, 유사도가 충분히 높은 문서만 남기는 필터
분할 → 중복 제거 → 관련성 필터링
작동 원리
작동 원리
여러 검색기 통합
예: BM25 같은 sparse retriever + 임베딩 기반 dense retriever
각 검색기가 뽑아온 문서 후보들을 모은 뒤,
RRF(Reciprocal Rank Fusion) 방식으로 결과를 합쳐 재순위화
Sparse(BM25/TF-IDF): 키워드/희귀 용어/정확 일치에 강함
Dense (임베딩): 동의어/표현 다양성/문맥 기반 의미 유사도에 강함
→ 상호 보완
긴 컨텍스트에 청크를 많이 넣으면 LLM이 중간에 있는 정보를 잘 못 쓰는 경향
→ retrieval로 가져온 문서들을 그대로 LLM에 넣지 않고, 순서를 재배치
작동 원리
검색은 작은 조각(자식)으로 정밀하게 하고,
실제 답변에는 큰 조각(부모)을 가져와 문맥을 채움
작동 원리
LLM으로 질문을 여러 버전의 쿼리로 확장해 여러 번 검색
문서당 여러 표현(embeddings)을 만들어 인덱싱
→ 검색 성능(recall/정확도) 개선
① 작은 청크 임베딩
② 요약 임베딩
③ 가설 질문 활용
자연어 질의를 바탕으로 구조화된 질의(Structured Query)를 생성하여, 단순 의미 검색을 넘어 메타데이터 필터링까지 동시에 수행합니
작동 원리
사용자 자연어 질의 입력
Query-constructing LLM chain이 질의를 해석해서
검색 텍스트(내용 의미 검색용)
메타데이터 조건(필터)
를 포함한 StructuredQuery 생성
Structured Query Translator가 StructuredQuery를
실제 VectorStore가 이해하는 필터 문법으로 변환
VectorStore에서 (필터 적용) + (유사도 검색)으로 문서 반환
의미 유사도 + 시간 요소(Time Decay) 감쇠를 동시에 반영해 문서를 재정렬하는 검색기
semantic_similarity : 질문(쿼리)과 문서의 의미적 유사도
decay_rate : 시간이 흐르면서 점수가 줄어드는 속도
hours_passed : 마지막으로 접근한 시점 이후 경과 시간
Reranker
- 1단계 Retriever : 빠르게 많이 찾기(속도/확장성 우선)
임베딩 유사도, BM25 같은 “가벼운 계산”- 2단계 Reranker : 후보를 정확히 정렬하기(정확도 우선)
쿼리-문서 쌍마다 무거운 모델로 평가 → 연산량 큼
작동 원리
장점
단점
질문과 문서를 따로 임베딩해서 비교하지 않고,
질문 + 문서 를 한 번에 같이 입력으로 넣고
self-attention으로 둘 사이 상호작용을 직접 보면서 관련성 점수 계산
실제 사용 패턴
Bi-encoder로 후보를 빠르게 추출,
Cross-encoder로 정확도를 높임
상용 리랭킹(Re-ranking) API
Retrieval Augmented Generation(RAG)
A. 인덱싱
B. 런타임
문서를 트리 구조로 인덱싱해서 검색 성능을 높이는 방식
Leafs : 원본 문서의 텍스트 청크
작동 원리
원문(leaf) → 요약(상위 노드) → 더 상위 요약으로 이어지는 계층적 트리 생성
장점
: 검색 시 상위 요약 노드로 큰 주제를 빠르게 찾고
필요하면 하위 leaf로 내려가 세부 근거를 찾는 식으로 다중 스케일 검색 가능
① 일반 Chain에 대화기록 추가 (멀티턴 QA 체인)
프롬프트 : 질문 + 대화 기록
prompt | llm | StrOutputParser() 로 일반 체인 생성② RAG + RunnableWithMessageHistory (멀티턴 RAG)
프롬프트 : 질문 + 대화 기록 + 검색된 문서
LangChain에서 LLM 앱 개발을 위한 표준 문법
A | B | C 처럼 순서대로 이어진 실행파이썬의 사용자 정의 함수를 LCEL에서 쓸 수 있게 Runnable로 감싸는 래퍼
ex. prompt | RunnableLambda() | model
입력값(이전 단계 출력)을 보고 조건에 맞는 경로로 체인을 분기시키는 라우팅 도구
def 함수(): if ... return chain 파이썬 함수
형태가 고정: [(cond1, r1), (cond2, r2), ...], default
첫 True 조건을 찾아 그 Runnable 실행
여러 Runnable을 병렬로 실행하고, 결과를 dict(map) 형태로 모아주는 Runnable
RunnableParallel 실행 결과 : {"context": ..., "question": ...}
런타임에 체인을 동적으로 변경하는 방법
① configurable_fields
같은 컴포넌트의 특정 설정값(예: model_name)을 런타임에 바꾸는 방법
② configurable_alternatives
컴포넌트 자체를 후보 중에서 런타임에 선택하는 방법
python 함수 위에 붙이면 RunnableLambda로 변환
제너레이터 함수(yield)를 사용하면 스트리밍을 유지 가능
LCEL에서 입력/출력 흐름과 무관한 고정 인자를 Runnable에 미리 붙여두고, 실행할 때마다 자동으로 전달되게 하는 기능
실패 시 대체 Runnable/모델/체인으로 자동 전환해 서비스를 안정화하는 메커니즘
주의 : 재시도(Retry) 끄기
많은 LLM 래퍼는 기본적으로 재시도(retry) 진행
기본 재시도 동작을 꺼야 fallback 사용 가능
처리해야할 오류를 구체적으로 명시
특정 예외에만 폴백이 발동되도록 예외 필터링
ex. exceptions_to_handle