개요
이 튜토리얼에서는 LangChain의 document loader, embedding, vector store 추상화에 대해 알아봅니다. 이러한 추상화는 (벡터) 데이터베이스 및 기타 소스에서 데이터를 검색하여 LLM 워크플로우와 통합하는 것을 지원하도록 설계되었습니다. 이는 검색 증강 생성(retrieval-augmented generation) 또는 RAG의 경우처럼 모델 추론의 일부로 추론할 데이터를 가져오는 애플리케이션에 중요합니다. 여기서는 PDF 문서에 대한 검색 엔진을 구축합니다. 이를 통해 입력 쿼리와 유사한 PDF의 구절을 검색할 수 있습니다. 이 가이드에는 검색 엔진 위에 최소한의 RAG 구현도 포함되어 있습니다.개념
이 가이드는 텍스트 데이터 검색에 중점을 둡니다. 다음 개념을 다룹니다:설정
설치
이 튜토리얼에는langchain-community 및 pypdf 패키지가 필요합니다:
LangSmith
LangChain으로 구축하는 많은 애플리케이션에는 여러 LLM 호출이 포함된 여러 단계가 포함됩니다. 이러한 애플리케이션이 점점 더 복잡해짐에 따라 chain 또는 agent 내부에서 정확히 무슨 일이 일어나고 있는지 검사할 수 있는 것이 중요해집니다. 이를 수행하는 가장 좋은 방법은 LangSmith를 사용하는 것입니다. 위 링크에서 가입한 후 추적 로깅을 시작하려면 환경 변수를 설정해야 합니다:1. Documents 및 Document Loaders
LangChain은 텍스트 단위와 관련 메타데이터를 나타내기 위한 Document 추상화를 구현합니다. 세 가지 속성이 있습니다:page_content: 콘텐츠를 나타내는 문자열;metadata: 임의의 메타데이터를 포함하는 dict;id: (선택 사항) 문서의 문자열 식별자.
metadata 속성은 문서의 소스, 다른 문서와의 관계 및 기타 정보에 대한 정보를 캡처할 수 있습니다. 개별 Document 객체는 종종 더 큰 문서의 청크를 나타냅니다.
원하는 경우 샘플 문서를 생성할 수 있습니다:
문서 로드하기
PDF를Document 객체의 시퀀스로 로드해 보겠습니다. 여기 샘플 PDF가 있습니다 — 2023년 Nike의 10-k 제출 서류입니다. 사용 가능한 PDF document loaders에 대한 LangChain 문서를 참조할 수 있습니다.
PyPDFLoader는 PDF 페이지당 하나의 Document 객체를 로드합니다. 각각에 대해 다음에 쉽게 액세스할 수 있습니다:
- 페이지의 문자열 콘텐츠;
- 파일 이름과 페이지 번호를 포함하는 메타데이터.
분할
정보 검색 및 다운스트림 질문 답변 목적 모두에서 페이지는 너무 거친 표현일 수 있습니다. 최종 목표는 입력 쿼리에 답하는Document 객체를 검색하는 것이며, PDF를 추가로 분할하면 문서의 관련 부분의 의미가 주변 텍스트에 의해 “희석”되지 않도록 하는 데 도움이 됩니다.
이를 위해 text splitters를 사용할 수 있습니다. 여기서는 문자를 기반으로 분할하는 간단한 text splitter를 사용합니다. 문서를 1000자 청크로 분할하고
청크 간에 200자의 오버랩을 둡니다. 오버랩은
중요한 컨텍스트와 관련된 진술을 분리할 가능성을 완화하는 데 도움이 됩니다. 우리는
RecursiveCharacterTextSplitter를 사용하며,
이는 새 줄과 같은 일반적인 구분 기호를 사용하여 각 청크가 적절한 크기가 될 때까지 문서를 재귀적으로 분할합니다. 이것은
일반 텍스트 사용 사례에 권장되는 text splitter입니다.
각 분할 Document가 초기 Document 내에서 시작하는 문자 인덱스가 메타데이터 속성 “start_index”로 보존되도록 add_start_index=True를 설정합니다.
2. Embeddings
벡터 검색은 비정형 데이터(예: 비정형 텍스트)를 저장하고 검색하는 일반적인 방법입니다. 아이디어는 텍스트와 연관된 숫자 벡터를 저장하는 것입니다. 쿼리가 주어지면 동일한 차원의 벡터로 embed하고 벡터 유사도 메트릭(예: 코사인 유사도)을 사용하여 관련 텍스트를 식별할 수 있습니다. LangChain은 수십 개의 제공업체의 embeddings를 지원합니다. 이러한 모델은 텍스트를 숫자 벡터로 변환하는 방법을 지정합니다. 모델을 선택해 보겠습니다:- OpenAI
- Azure
- Google Gemini
- Google Vertex
- AWS
- HuggingFace
- Ollama
- Cohere
- MistralAI
- Nomic
- NVIDIA
- Voyage AI
- IBM watsonx
- Fake
3. Vector stores
LangChain VectorStore 객체에는 텍스트 및Document 객체를 저장소에 추가하고 다양한 유사도 메트릭을 사용하여 쿼리하는 메서드가 포함되어 있습니다. 이들은 종종 텍스트 데이터가 숫자 벡터로 변환되는 방법을 결정하는 embedding 모델로 초기화됩니다.
LangChain에는 다양한 vector store 기술과의 통합 모음이 포함되어 있습니다. 일부 vector stores는 제공업체(예: 다양한 클라우드 제공업체)가 호스팅하며 사용하려면 특정 자격 증명이 필요합니다. 일부(예: Postgres)는 로컬 또는 타사를 통해 실행할 수 있는 별도의 인프라에서 실행됩니다. 다른 것들은 경량 워크로드를 위해 인메모리로 실행할 수 있습니다. vector store를 선택해 보겠습니다:
- In-memory
- AstraDB
- Chroma
- FAISS
- Milvus
- MongoDB
- PGVector
- PGVectorStore
- Pinecone
- Qdrant
vector store를 인스턴스화했으므로 이제 문서를 인덱싱할 수 있습니다.
VectorStore를 인스턴스화하면 쿼리할 수 있습니다. VectorStore에는 쿼리를 위한 메서드가 포함되어 있습니다:
- 동기 및 비동기;
- 문자열 쿼리 및 벡터별;
- 유사도 점수 반환 여부;
- 유사도 및 @[maximum marginal relevance][VectorStore.max_marginal_relevance_search](쿼리와의 유사도와 검색된 결과의 다양성 간의 균형을 맞추기 위해).
4. Retrievers
LangChainVectorStore 객체는 @[Runnable]을 서브클래스하지 않습니다. LangChain @[Retrievers]는 Runnables이므로 표준 메서드 세트(예: 동기 및 비동기 invoke 및 batch 작업)를 구현합니다. vector stores에서 retrievers를 구성할 수 있지만, retrievers는 비벡터 저장소 데이터 소스(예: 외부 API)와도 인터페이스할 수 있습니다.
Retriever를 서브클래스하지 않고 이것의 간단한 버전을 직접 만들 수 있습니다. 문서를 검색하는 데 사용할 메서드를 선택하면 runnable을 쉽게 만들 수 있습니다. 아래에서는 similarity_search 메서드를 중심으로 하나를 구축합니다:
as_retriever 메서드를 구현합니다. 이러한 retrievers에는 기본 vector store의 어떤 메서드를 호출할지, 그리고 매개변수화하는 방법을 식별하는 특정 search_type 및 search_kwargs 속성이 포함됩니다. 예를 들어 다음과 같이 위의 내용을 복제할 수 있습니다:
VectorStoreRetriever는 "similarity"(기본값), "mmr"(위에서 설명한 maximum marginal relevance) 및 "similarity_score_threshold"의 검색 유형을 지원합니다. 후자를 사용하여 유사도 점수로 retriever가 출력하는 문서를 임계값으로 설정할 수 있습니다.
Retrievers는 주어진 질문과 검색된 컨텍스트를 LLM의 프롬프트로 결합하는 검색 증강 생성(RAG) 애플리케이션과 같은 더 복잡한 애플리케이션에 쉽게 통합될 수 있습니다. 이러한 애플리케이션 구축에 대해 자세히 알아보려면 RAG 튜토리얼 튜토리얼을 확인하세요.
다음 단계
이제 PDF 문서에 대한 시맨틱 검색 엔진을 구축하는 방법을 살펴보았습니다. document loaders에 대한 자세한 내용: embeddings에 대한 자세한 내용: vector stores에 대한 자세한 내용: RAG에 대한 자세한 내용:Connect these docs programmatically to Claude, VSCode, and more via MCP for real-time answers.