langchain

LangChain은 2022년 10월 Harrison Chase가 주도해 만든, LLM 기반 애플리케이션을 구축하기 위한 프레임워크입니다. 핵심 목표는 AI 애플리케이션을 쉽고 빠르게 구현하는 것입니다. Agent, QA 시스템, 대화형 봇 등이 대표적인 활용 사례입니다. LangChain은 다양한 언어 모델과 도구를 하나의 인터페이스로 통합해 복잡한 작업을 수행할 수 있도록 지원합니다.

왜 LangChain을 사용할까?

LangChain은 다음과 같은 이유로 사용됩니다:

  1. 모듈화: LangChain은 다양한 구성 요소(예: LLM, 프롬프트 템플릿, 메모리 등)를 모듈화하여 개발자가 쉽게 조합하고 확장할 수 있도록 합니다.
  2. 도구 통합: LangChain은 외부 도구(예: 검색 엔진, 데이터베이스 등)와의 통합을 지원하여 LLM의 기능을 확장합니다.
  3. 체인 구성: LangChain은 여러 단계를 거쳐 작업을 수행하는 체인을 쉽게 구성할 수 있도록 도와줍니다.
  4. 커뮤니티 및 생태계: LangChain은 활발한 커뮤니티와 다양한 플러그인 및 확장 기능을 제공하여 개발자가 최신 기술을 활용할 수 있도록 지원합니다.

LangChain과 LLM 직접 구현의 차이점

비교 항목모델 API 직접 호출LangChain 기반 개발
개발 방식단순 작업에는 직관적이지만, 복잡한 기능은 많은 커스텀 코드 필요모듈을 조합하는 방식으로 복잡한 기능도 쉽게 구현 가능
여러 모델 지원모델 제공업체마다 다른 API를 직접 구현해야 함통합 인터페이스 제공 → OpenAI, Anthropic, Hugging Face 등 쉽게 전환/조합 가능
외부 데이터 연동데이터 로딩, 전처리, 벡터화, 검색 기능까지 모두 직접 구현해야 함PDF, DB, API 등과 쉽게 연결할 수 있는 RAG 기능과 다양한 도구 기본 제공
문맥(컨텍스트) 관리대화 히스토리를 직접 관리해야 하며 Token 초과 위험 있음Memory 컴포넌트 제공 → 단기·장기 기억을 자동 관리
복잡한 작업 자동화다단계 추론, 도구 호출 등을 구현하려면 논리 구조 설계가 어려움Agent 기능 제공 → 모델이 스스로 도구를 선택·호출해 작업 수행
운영(배포·모니터링) 지원표준화된 디버깅/모니터링 도구 부족LangSmith로 추적, 디버깅, 평가, 모니터링 지원

LangChain 아키텍처

  • LangChain
    • langchain
      • Chains
      • Agents
      • Retrieval strategies
    • langchain-community
      • Model I/O
      • Retrival
      • Tool
    • langchain-core
      • LCEL(LangChain Expression Language)
  • LangGraph
    • Directed Graph와 Conditional Edge를 기반으로 멀티 에이전트 애플리케이션을 구축할 수 있으며, 조건 분기·반복·병렬 같은 복잡한 제어 흐름을 지원한다. 또한 상태 지속성, 중단 후 재실행, 시간 여행(time travel), 인간-에이전트 협업 같은 고급 기능도 구현할 수 있다.
  • LangSmith
    • Debugging
    • Playground
    • Prompt Management
    • Annotation
    • Testing
    • Monitoring
  • LangServe
    • LangChain으로 개발한 chain, agent 등을 손쉽게 배포하고 운영할 수 있도록 지원하는 서비스

LangChain 주요 컴포넌트

Model I/O

LLM과 상호작용하는 컴포넌트로, Format → Predict → Parse 세 단계로 구성된다. 각 단계에 대응하는 컴포넌트는 순서대로 PromptTemplate, Model(LLM), OutputParser다.

LLM 분류
  • LLMs: 단순히 텍스트 생성
  • Chat Models: 대화형 모델
  • Embedding Models: 텍스트를 벡터로 변환
Message
  • System Message: 모델의 동작방식을 정의
  • Human Message: 사용자 입력
  • AI Message: 모델의 응답
PromptTemplate
  • Prompt: 모델에 전달되는 전체 텍스트
  • PromptTemplate: 변수화된 프롬프트
  • ChatPromptTemplate: 대화형 프롬프트 템플릿
  • XxxMessagePromptTemplate: 특정 유형의 메시지에 대한 프롬프트 템플릿
  • FewShotPromptTemplate: 몇 가지 예시를 포함하는 프롬프트 템플릿
OutputParser
  • StrOutputParser: 단순 문자열 출력 파서
  • JsonOutputParser: JSON 형식의 출력 파서
  • CommaSeparatedListOutputParser: 쉼표로 구분된 리스트 출력 파서
  • DatetimeOutputParser: 날짜 및 시간 출력 파서
  • XmlOutputParser: XML 형식의 출력 파서
사용방식
  • invoke: 단일 입력에 대한 예측 수행(ainvoke : 비동기 버전)
  • stream: 스트리밍 출력을 지원하는 예측 수행(astream : 비동기 버전)
  • batch: 배치 입력에 대한 예측 수행(abatch : 비동기 버전)

Chains

chain은 여러 컴포넌트(prompt template, LLM, memory, tool 등)를 연결해 특정 작업을 수행하는 단위입니다. 한 체인의 실행 결과를 다음 체인의 입력으로 넘겨 복잡한 작업을 단계적으로 처리할 수 있습니다.

종류
  • LLMChain: prompt템플릿과 LLM을 package화한 가장 기본적인 체인
  • MultiPromptChain: 여러 개의 프롬프트 템플릿을 준비해두고, 입력을 **가장 적합한 프롬프트(템플릿)**로 LLM이 자동 선택하도록 하는 라우터.
  • LLMRouterChain: LLM이 입력을 읽고, **어떤 체인(또는 프롬프트)**으로 보낼지 결정하는 Router Chain.
  • EmbeddingRouterChain: 입력을 **임베딩(Embedding)**하여 미리 정의된 “주제 벡터들”과의 유사도 계산을 통해 어떤 체인으로 보낼지 결정하는 Router Chain.
  • MultiRetrievalQaRouter: 여러 개의 Retriever(벡터DB or 검색 소스)를 준비해두고, 입력을 보고 어떤 Retriever에서 자료를 가져올지 라우팅하는 체인.
  • SimpleSequentialChain: 여러개의 체인을 순차적으로 연결하여 실행, 앞 체인의 출력이 다음 체인의 입력.
  • SequentialChain: 여러개의 체인을 순차적으로 연결하여 실행, 여러 입력·출력을 각각 지정
  • RetrievalQA: Retriever로 문서를 검색한 뒤 LLM에 넣어 답변 생성.
  • ConversationalRetrievalQAChain: 대화형 문맥을 유지하면서 Retriever로 문서를 검색한 뒤 LLM에 넣어 답변 생성.
  • LCELChain: LangChain Expression Language(LCEL)을 사용하여 체인을 정의하는 방식
  • StuffDocumentsChain: 여러 문서를 하나로 합쳐서 LLM에 전달하는 체인
  • MapReduceDocumentsChain: 여러 문서를 각각 LLM에 전달하여 요약한 뒤, 그 요약들을 다시 LLM에 전달하여 최종 요약 생성
  • MapReRankDocumentsChain: 여러 문서를 각각 LLM에 전달하여 점수를 매긴 뒤, 상위 문서들을 다시 LLM에 전달하여 답변 생성
  • RefineChain: 초기 요약을 생성한 뒤, 추가 문서들을 순차적으로 반영하여 요약을 점진적으로 개선
  • LLMMathChain: 수학 문제 해결을 위해 LLM과 계산기를 결합한 체인
  • APIChain: API 호출을 위해 프롬프트 템플릿과 LLM을 결합한 체인
  • SQLDatabaseChain: 데이터베이스 질의를 위해 프롬프트 템플릿, LLM, 데이터베이스 커넥터를 결합한 체인
  • Hypothetical Document Embeddings: 문서의 가상 임베딩을 생성하여 검색 효율성을 높이는 체인
  • VectorDBQAChain: 벡터 데이터베이스에서 문서를 검색한 뒤 LLM에 넣어 답변 생성
  • ConversationalQAChain: 대화형 문맥을 유지하면서 LLM에 답변 생성
  • TransformChain: 입력 데이터를 변환하는 함수를 체인에 통합
  • LLMCheckerChain: LLM의 출력을 검증하는 체인
  • AnalyzeDocumentChain: 문서를 분석하는 체인
  • ConstitutionalChain: LLM의 출력을 헌법적 원칙에 따라 수정하는 체인
  • ExtractionChain: 구조화된 데이터를 추출하는 체인
  • LLMRequestChain: LLM에 대한 요청을 관리하는 체인 .....

Memory

종류
Memory 종류설명특징장점
ConversationBufferMemory전체 대화를 원문 그대로 저장하여 LLM에 전달하는 기본 메모리단순 버퍼 방식, 시간순 메시지 저장구현이 쉽고 맥락 전달이 가장 자연스러움
ConversationBufferWindowMemory전체 이력을 보관하되 LLM에는 최근 N개 메시지만 전달최근 맥락 중심, 비용 절감형 방식최신 대화 맥락을 유지하면서 토큰 비용을 크게 줄일 수 있음
ConversationSummaryMemory오래된 대화를 LLM이 *요약(summary)*하여 축약 저장장기 대화에 최적화, 핵심 정보 중심매우 긴 대화도 효율적으로 유지 가능하며 토큰 사용량 최소화
ConversationSummaryBufferMemory오래된 대화는 요약, 최신 대화는 원문 유지하는 혼합형 메모리요약 + 최근 메시지 버퍼 결합자연스러운 대화 흐름 유지와 비용 절감을 동시에 실현
ConversationKGMemory대화에서 엔티티·관계·사실을 추출해 지식 그래프(KG) 형태로 저장구조적 지식 표현, 관계 기반 메모리장기적 사실·관계를 명확하고 체계적으로 저장 가능
VectorStoreRetrieverMemory대화를 임베딩하여 VectorStore에 저장 후 유사도 검색으로 관련 내용만 로드벡터 기반 검색, 확장성 높음매우 큰 대화 기록도 효율적으로 검색 가능하여 장기 기억에 강함
EntityMemory대화에서 사람·사물·장소 등 엔티티 기반 정보를 추출해 저장엔티티 중심 구조화 메모리사용자 정보·속성·선호 등을 장기적으로 안정적으로 기억
ChatMessageHistory메모리 구성에 사용되는 기본 메시지 히스토리 객체단순 메시지 저장 구조커스텀 메모리 개발 시 가장 유연하고 확장성이 좋음
Custom MemoryBaseMemory를 상속해 직접 구현하는 맞춤형 메모리완전 사용자 정의 가능서비스 요구에 맞춘 고급 메모리 구조를 구축할 수 있음

Tools

Tools는 LLM과 Agent가 외부 시스템과 상호작용할 수 있게 해 주는 컴포넌트입니다. 본질은 함수(function)로, 입력을 받아 특정 작업을 수행한 뒤 출력을 반환합니다. 검색 도구, 계산기, 데이터베이스 조회, API 통신 등이 대표적입니다.

구성
  • name: 도구 이름
  • description: 도구에 대한 설명. 프롬프트에 그대로 포함되어 LLM이 어떤 도구를 쓸지 판단하는 근거가 됨
  • parameters: 도구에 전달되는 매개변수 정의
  • return type: 도구가 반환하는 출력 형식

도구가 호출되지 않는 문제
  • LLM이 도구를 쓸 필요가 없다고 판단한 경우
  • 도구 설명이 모호해 LLM이 적절한 도구를 고르지 못하는 경우
  • 모델 자체가 도구 호출을 잘 하지 않는 경우(예: DeepSeek-R1)

해결: 도구의 description이나 프롬프트 문구를 다듬어 보고, 그래도 안 되면 다른 LLM으로 교체한다.

LangChain Tool과 MCP Server의 차이점
비교 항목내장 ToolsMCP Server
배포 위치에이전트 내부(동일 프로세스)독립 서비스(별도 프로세스/네트워크)
코드 결합도강한 결합(직접 코드 참조)느슨한 결합(프로토콜 기반 통신)
재사용성해당 에이전트에서만 사용 가능여러 에이전트 간 공유 가능
업데이트 및 유지보수수정 시 에이전트 재빌드 필요독립적으로 업데이트 가능, 에이전트 재빌드 불필요
성능로컬 직접 호출로 매우 빠름네트워크/IPC 통신 필요로 상대적으로 느림
적합한 사용 시나리오단순·특화 기능 도구범용·복잡·확장 가능한 도구

Agents

에이전트는 LLM과 도구를 결합하여 복잡한 작업을 수행하는 컴포넌트입니다. 에이전트는 사용자의 입력을 받아 적절한 도구를 선택하고 호출하여 작업을 수행한 후 결과를 반환합니다.

구성요소
  • Memory 관리: 대화형 에이전트는 Memory컴포넌트를 사용하여 대화 히스토리를 관리하고 문맥을 유지합니다.
    • short-term memory: 최근 대화 내용을 기억
    • long-term memory: 장기적인 정보나 사실을 기억
  • Tools 활용: 에이전트는 다양한 도구를 활용하여 외부 시스템과 상호작용하고 복잡한 작업을 수행합니다.
  • Planning: 에이전트는 작업을 여러 단계로 나누어 계획을 세우고 실행할 수 있습니다.
    • Reflection
    • Self-critics
    • Chain of Thoughts
    • Subgoal decomposition
  • Action and Observation: 에이전트는 도구를 호출하고 그 결과를 관찰하여 다음 행동을 결정합니다.
Deepagents

deepagents는 복잡하고 다단계 작업을 처리할 수 있는 에이전트를 구축하기 위한 독립형 라이브러리입니다.

사용해야 하는 경우
  • 계획 및 분해가 필요한 복잡하고 다단계 작업을 처리할 때
  • 파일 시스템 도구를 통해 대량의 컨텍스트를 관리할 때
  • 컨텍스트 격리를 위해 특수 하위 에이전트에 작업을 위임할 때
  • 대화 및 스레드 간에 메모리를 유지할 때
핵심 역량
  • 계획 및 분해: 작업을 여러 단계로 나누어 계획을 세우고 실행
  • Context관리: 파일 시스템 도구를 통해 대량의 컨텍스트 관리
  • 하위 에이전트: 특수 하위 에이전트를 통해 작업 위임 및 컨텍스트 관리
  • Long-term memory: LangGraph의 Store를 사용하여 스레드 간에 영구 메모리를 확장
예제
// 에이전트를 전문 연구자로 안내하는 시스템 프롬프트
const researchInstructions = `당신은 전문 연구자입니다. 당신의 임무는 철저한 조사를 수행하고 완성도 높은 보고서를 작성하는 것입니다.

정보 수집의 주요 수단으로 인터넷 검색 도구를 사용할 수 있습니다.

## \`internet_search\`

이 기능을 사용하여 특정 쿼리에 대한 인터넷 검색을 실행합니다. 반환할 최대 결과 수, 주제, 그리고 원본 콘텐츠 포함 여부를 지정할 수 있습니다.
`;
참고

Retrieval Augmented Generation

Retrieval은 외부 지식 소스에서 관련 정보를 검색해 LLM에 제공하는 컴포넌트입니다. 이를 통해 모델이 최신 정보에 접근하거나 도메인 특화 지식을 활용할 수 있습니다. LLM은 학습 시점에 지식이 고정되는 모델이므로, 사전학습 범위 밖의 정보를 다루려면 Retrieval이 필수적입니다. 환각(hallucination)을 완화하는 데도 도움이 됩니다. RAG(Retrieval Augmented Generation) 시스템의 핵심 구성 요소입니다.

Retrieval Augmented Generation 흐름1

  1. 문서 파싱

  2. 텍스트 분할

  3. 벡터화(Embedding Model 사용)

    • nomic-embed-text
    • mxbai-embed-large
    • embedding-gemma
  4. 벡터 DB 저장

  5. 질문

  6. 검색 알고리즘(Cosine Similarity, Dot Product, Euclidean Distance 등)

  7. 재정렬(Rerank Model): 유사도가 높은 순으로 다시 정렬

  8. 증강: 사용자 질문과 검색된 내용을 함께 LLM에 전달

  9. 응답 생성

Retrieval Augmented Generation 장점
  • 지식을 실시간으로 갱신할 수 있음
  • 재학습 대비 비용 효율이 높음
  • 출처를 함께 제시하므로 답변을 신뢰하고 검증할 수 있음
  • 안전하고 통제 가능: 제공한 문서에 근거한 응답만 생성하도록 제어할 수 있음
Retrieval Augmented Generation 단점
  • 검색 품질이 곧 답변 품질의 상한이 됨
  • 시스템 복잡도가 올라감
  • 컨텍스트 길이와 구성에 결과가 좌우됨
  • 제공한 문서의 품질에 크게 의존함
LangChain에서의 구현
  1. Document Loaders
  • page_content: 문서의 실제 텍스트 내용
  • metadata: 문서에 대한 추가 정보
  1. Text Splitters

    작동 원리

    우선 세분화한 후 병합하는 전략을 따릅니다. 먼저 텍스트를 작은 문장 단위로 분할한 다음, 이러한 문장들을 순서대로 결합하여 설정된 블록 크기 제한에 도달할 때까지 더 큰 블록으로 만듭니다. 새 블록을 생성할 때는 이전 블록과 일부 중복되는 부분을 유지하여 문맥의 연속성을 보장합니다.

    왜 분할이 필요한가
    • 생성된 답변의 품질 보장: 검색된 텍스트 블록이 너무 크고 관련 없는 정보가 많으면 LLM이 관련 없는 내용에 방해를 받아 핵심 문제에 집중하지 못할 수 있습니다. 심지어 관련 없는 정보를 잘못 통합하여 부정확하거나 장황한 답변을 생성할 수도 있습니다.
    • 모델의 컨텍스트 창 제한 극복: 모든 대형 모델에는 고정된 컨텍스트 창이 있으며, 이는 모델이 한 번에 "보고" 처리할 수 있는 텍스트의 총량이 제한되어 있음을 의미합니다.
    • 검색 정확도 향상: 검색 시스템은 특정 질문에 답할 수 있는 단락을 직접 찾을 수 있어 검색 결과의 관련성과 정확성을 크게 향상시킵니다.
    langchain의 Text Splitters
    • TextSplitter: LangChain에서 모든 텍스트 분할기의 기반이 되는 추상(Base) 클래스입니다.
    • CharacterTextSplitter: 문자/문단 단위로 단순하게 분할하는 기본 방식.
    • RecursiveCharacterTextSplitter: 여러 분리자를 계층적으로 적용하여 자연스럽게 텍스트를 분할하는 권장 방식.
    • TokenTextSplitter: 토큰 개수 기준으로 텍스트를 분할하는 방식(OpenAI 등 토큰 제한 대응).
    • LatexTextSplitter: LaTeX 문서 구조를 이해하고 그에 맞춰 분할
    • MarkdownTextSplitter: Markdown 구조를 이해하고 그에 맞춰 분할
  2. Text Embedding Models(예: nomic-embed-text 등)

  3. Vector Stores

  • 저장
  • 검색
  1. Retrievers
    • Vector Stores가 검색 알고리즘을 포함한 인터페이스를 제공

Callbacks

기타 미정리

chunk
  • chunkSize
  • chunkOverlap

MMR

LangChain은 검색 결과를 MMR(Maximum Marginal Relevance, 최대 한계 관련성) 기준으로 재정렬하는 기능을 지원한다. 관련성만 보고 상위를 채우면 비슷한 문서가 중복되기 쉬운데, MMR은 관련성과 다양성을 함께 고려해 순위를 다시 매긴다.

다중 쿼리 검색(Multi-Query Retrieval)

거리를 척도로 삼는 벡터 DB 검색은 query를 고차원 벡터 공간에 embedding한 뒤, 같은 공간에 embedding된 문서들과의 거리를 기준으로 유사 문서를 찾는 방식이다.

그런데 query에 쓰인 단어가 조금만 달라지거나, embedding이 query의 의미를 충분히 담아내지 못하면 정작 필요한 유사 문서를 찾지 못하는 일이 생긴다.

다중 쿼리 검색은 바로 이 문제를 겨냥한 기법이다. 프롬프트 엔지니어링을 통해 원본 query를 LLM에 넣어 서로 다른 관점의 유사 질의를 여러 개 생성하고, 각각으로 검색을 돌린 다음 그 결과를 한데 모아 중복을 제거한다. 이렇게 하면 놓칠 뻔한 유사 문서까지 더 폭넓게 확보할 수 있다.

const retriever = new MultiQueryRetriever.fromLLM({
  llm: new ChatAnthropic({}),
  retriever: new MemoryVectorStore().asRetriever(),
  verbose: true,
});
const retrievedDocs = await retriever.invoke("What are mitochondria made of?");

링크