1장. 랭체인 살펴보기

출처: 『RAG 마스터: 랭체인으로 완성하는 LLM 서비스』(브라이스 유·조경아·박수진·김재웅, 프리렉 2025) | 공식: https://www.langchain.com/

랭체인은 LLM 애플리케이션을 레고 블록처럼 조립하게 해주는 오픈소스 프레임워크다. 이 장은 랭체인의 패키지 구성부터 LCEL(체인 연결)·프롬프트·출력 파서·메모리까지, RAG를 만들기 위한 기본기를 한 바퀴 훑는다.

실습 — 책 공식 노트북: Ch01. Langchain Basics 폴더 — LCEL·LLM·Memory·Output Parsers 5개 노트북. 코랩에서 바로 열기: LCEL·LLM·Memory·Output Parsers.

학습 목표

이 장을 끝내면 다음을 할 수 있다.

  • 랭체인 생태계의 주요 패키지(langchain-core, langchain, langgraph 등)를 역할별로 구분한다.
  • LCEL의 파이프(|) 연산자로 프롬프트·모델·파서를 연결한 체인을 구현한다.
  • ChatPromptTemplate과 퓨샷 프롬프트를 활용해 입력을 모델용 지침으로 변환한다.
  • PydanticOutputParser·JsonOutputParser를 선택해 모델 출력을 구조화 데이터로 파싱한다.
  • RunnableWithMessageHistory와 트리밍·요약 전략으로 다중 턴 대화의 메모리를 관리한다.

전체 흐름도

랭체인의 핵심: 프롬프트 → LLM → 출력 파서를 LCEL 체인으로 잇고, 메모리로 대화 맥락을 유지한다.

[ 사용자 입력 ]
   │
   ▼
[ ChatPromptTemplate ]  ← MessagesPlaceholder (대화 이력)
   │  변수 채움 → 모델용 메시지 시퀀스
   ▼
[ ChatModel (LLM) ]     ← temperature / max_tokens 등 파라미터
   │  자유 텍스트 응답
   ▼
[ 출력 파서 ]
   ├─ StrOutputParser    (단순 문자열)
   ├─ JsonOutputParser   (JSON / 스트리밍 지원)
   └─ PydanticOutputParser (스키마 검증)
   │
   ▼
[ 최종 결과 ]
   │
   ▼
[ ChatMessageHistory / RunnableWithMessageHistory ]
   └─ 다음 턴 입력 시 이력 자동 주입

0. 사전 필수 용어

참고 — Python·API 키 사용 경험이 있다면 충분하다. 더 기초가 필요하면 선수지식 책(자연언어·신경망)을 먼저 봐도 좋다.

  • LLM(대규모 언어 모델) — 방대한 텍스트를 학습해 자연어를 이해·생성하는 모델. GPT·Claude·Gemini·LLaMA 등.
  • RAG(검색 증강 생성, Retrieval-Augmented Generation) — LLM의 생성 능력에 외부 정보 검색 을 결합해, 최신·도메인 데이터를 반영한 답을 만드는 기법. 이 책 전체의 주제.
  • 랭체인(LangChain) — LLM 앱 개발용 오픈소스 프레임워크. 모델·메모리·검색기 등을 모듈로 제공해 조립식 개발을 돕는다.
  • 체인(Chain) — 프롬프트 → 모델 → 파서처럼 여러 작업을 순서대로 연결한 작업 흐름.
  • 러너블(Runnable) — 체인의 각 단계가 공유하는 '실행 단위' 추상화. invoke·batch·stream 같은 공통 메서드를 가진다.
  • LCEL(랭체인 표현 언어) — 러너블을 파이프(|)로 연결해 체인을 선언적으로 기술하는 방식.

1. 랭체인 개요

랭체인은 하나의 패키지가 아니라 생태계다. 역할별로 나뉜 여러 패키지를 조합해 쓴다.

주요 패키지(1.1).

패키지 역할
langchain-core 생태계의 토대. LLM·벡터 저장소·검색기의 기본 인터페이스 와 LCEL을 정의. 가볍다.
langchain 체인·에이전트·검색 전략 등 앱 구조를 만드는 본체. 설치 시 core가 함께 깔린다.
langchain-community 커뮤니티가 관리하는 타사 통합 모음(선택 설치).
파트너 패키지 자주 쓰는 통합을 분리. langchain-openai, langchain-anthropic 등.
langgraph 그래프 기반으로 분기·루프가 있는 복잡한 에이전트를 설계(6장).
langserve 체인을 REST API로 배포.
langsmith 디버깅·테스트·평가·모니터링 플랫폼.

참고 — 화살표(의존성)는 "A가 B에 의존". langchain → langchain-core 처럼 core가 가장 아래에 깔린다. langgraph는 core를 피어 의존성 으로 선택 사용.

버전(1.2). 2024-09 발표된 0.3 기준. 0.1에서 패키지 분리, 0.2에서 community 의존성 제거(경량화), 0.3에서 Pydantic 2 전환 + Python 3.8 지원 종료. 버전은 자주 바뀌어도 전체 구조는 거의 그대로다.

향후 계획: 랭그래프 기능 확장(에이전트 아키텍처 주요 프레임워크), 벡터 스토어 추상화 개선, 문서화 강화.

왜 랭체인인가(1.3). OpenAI API만으로도 앱은 만들 수 있다. 그래도 랭체인을 쓰는 이유 4가지: - 모듈성 — 기능을 독립 모듈로 끼웠다 뺐다. - 통합 용이성 — OpenAI → Gemini/Mistral 교체를 설정만 바꿔서. - 확장 기능 — LCEL·러너블로 복잡한 워크플로를 간결하게. - 커뮤니티 — 풍부한 예제·지속 업데이트.

활용 사례(1.4). RAG·질의응답, 구조화 출력 추출, 챗봇, 도구 사용·에이전트 — 이 책의 각 장이 이 사례들을 단계별로 다룬다.

2. 대규모 언어 모델

랭체인은 LLM을 직접 제공하지 않는다. 대신 OpenAI·Cohere·Hugging Face 등 여러 제공자를 표준 인터페이스로 감싸 동일하게 다루게 해준다.

랭체인 vs OpenAI API(2.1).

항목 OpenAI API 직접 랭체인
구조 단순 호출 모듈화된 체인
모델 전환 코드 수정 필요 클래스만 교체
재사용성 낮음 높음
적합 간단한 작업 복잡·확장 가능한 앱
# 잘못된 예 — OpenAI 직접 호출 (모델 교체 시 코드 전반 수정 필요)
import openai
client = openai.OpenAI()
client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "안녕하세요!"}]
)

# 올바른 예 — 랭체인 체인 (모델 교체는 클래스 한 줄만)
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

prompt = ChatPromptTemplate.from_template("주제 {topic}에 대해 짧은 설명을 해주세요.")
model = ChatOpenAI(model="gpt-4o")
# 미스트랄로 교체 시: model = ChatMistralAI(api_key=MISTRAL_API_KEY)
chain = prompt | model | StrOutputParser()
chain.invoke({"topic": "더블딥"})

파라미터(2.2). 출력을 조절하는 하이퍼파라미터: - temperature(0~1) — 낮으면 일관·예측 가능, 높으면 다양·창의적. - max_tokens — 생성 길이 상한. - top_p — 상위 확률 토큰만 고려. - frequency/presence penalty — 반복 억제 / 새 단어 장려. - stop sequences — 특정 문자열 만나면 생성 중단.

주요 모델(2.3). 제공자별 문맥 크기·백만 토큰당 입출력 비용·한국어 성능을 비교해 고른다(LogicKor 대시보드 참고). 가격·모델은 빠르게 바뀌므로 항상 공식 가격표를 확인 한다.

3. 랭체인 표현 언어(LCEL)

LCEL은 "어떻게"가 아닌 "무엇을 할지"를 기술하는 선언적 방식이다. 프로토타입부터 운영까지 코드 변경 없이 일관되게 쓰도록 설계됐다.

추가 특징: - 동기·비동기 API 동일 코드 사용 가능 - 여러 작업 병렬 처리 지원 - 실패 시 자동 재시도·대체 경로 선택 - 랭스미스 통합으로 모든 단계 자동 기록·모니터링

러너블 표준 인터페이스(3.1). 모든 구성요소(모델·프롬프트·파서)가 같은 메서드를 공유한다:

동기 비동기 의미
invoke() ainvoke() 단일 입력 처리
batch() abatch() 여러 입력 동시 처리
stream() astream() 결과를 토큰 단위 스트리밍

참고stream()은 응답이 다 만들어지기 전 토큰을 실시간으로 흘려보낸다. print(token, end="", flush=True)로 즉시 화면에 표시.

체인 연결(3.2). 한 단계의 출력 타입이 다음 단계의 입력 타입과 같아 파이프로 잇는다.

# 기본 체인: prompt | model | parser
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

model = ChatOpenAI(model="gpt-4o-mini")
prompt = ChatPromptTemplate.from_template("주제 {topic}에 대해 짧은 설명을 해주세요.")
parser = StrOutputParser()
chain = prompt | model | parser

# invoke — 단일 처리
chain.invoke({"topic": "더블딥"})

# batch — 여러 입력 동시 처리
chain.batch([{"topic": "더블딥"}, {"topic": "인플레이션"}])

# stream — 토큰 단위 실시간 출력
for token in chain.stream({"topic": "더블딥"}):
    print(token, end="", flush=True)
  • 파이프 연산자 prompt | model | parser — 파이썬 __or__ 오버로딩으로 동작.
  • .pipe() 메서드chain.pipe(analysis_prompt, model, StrOutputParser()) 처럼 같은 일을 메서드로.
  • RunnableParallel — 여러 체인을 병렬 실행. 예: 한국어·영어 설명을 동시에 생성해 {kor, eng} 로 받기.
  • 람다(함수) 도 러너블로 자동 변환되어 중간 변환 로직을 끼울 수 있다(단, 스트리밍과 호환 안 될 수 있음).
# RunnableParallel — 한국어·영어 동시 생성
from langchain_core.runnables import RunnableParallel

kor_chain = (
    ChatPromptTemplate.from_template("{topic}에 대해 짧은 설명을 해주세요.")
    | model | StrOutputParser()
)
eng_chain = (
    ChatPromptTemplate.from_template("{topic}에 대해 짧게 영어로 설명을 해주세요.")
    | model | StrOutputParser()
)
parallel_chain = RunnableParallel(kor=kor_chain, eng=eng_chain)
result = parallel_chain.invoke({"topic": "더블딥"})
# {"kor": "...", "eng": "..."} 형태로 반환

4. 프롬프트

프롬프트 템플릿은 사용자 입력·변수를 모델용 지침 으로 바꿔준다. 입력은 딕셔너리로 받고, {변수} 자리에 값이 채워진다.

  • 문자열 템플릿 PromptTemplate — 단일 문자열 프롬프트.
  • 챗 템플릿 ChatPromptTemplate — system/user/ai 역할 메시지 시퀀스.
  • 메시지 자리 표시자 MessagesPlaceholder("msgs") 또는 ("placeholder", "{msgs}") — 대화 이력처럼 동적 메시지 목록을 끼울 자리.
# ChatPromptTemplate — system + user 메시지 시퀀스
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage

prompt = ChatPromptTemplate.from_messages([
    ("system", "당신은 유능한 금융 조언가입니다."),
    MessagesPlaceholder("msgs")  # 또는 ("placeholder", "{msgs}")
])
prompt.invoke({"msgs": [HumanMessage(content="주식에 대해 알려주세요.")]})

퓨샷 프롬프트(4.1). 예시 몇 개를 보여줘 성능을 끌어올리는 기법. 예시 0개=제로샷, 1개=원샷, n개=퓨샷. - FewShotPromptTemplate(examples, example_prompt, suffix="질문: {input}") 로 예시를 한꺼번에 주입. - 예제 선택기 SemanticSimilarityExampleSelector — 모든 예시를 넣지 않고, 입력과 유사도가 높은 예시만 골라(k=1) 토큰을 아낀다(임베딩 + Chroma 사용).

# 잘못된 예 — 모든 예시를 프롬프트에 하드코딩 (토큰 낭비)
from langchain_core.prompts import FewShotPromptTemplate

prompt = FewShotPromptTemplate(
    examples=examples,  # 예시 전부 주입
    example_prompt=example_prompt,
    suffix="질문: {input}",
    input_variables=["input"],
)

# 올바른 예 — 예제 선택기로 유사 예시만 선택 (토큰 절약)
from langchain_chroma import Chroma
from langchain_core.example_selectors import SemanticSimilarityExampleSelector
from langchain_openai import OpenAIEmbeddings

example_selector = SemanticSimilarityExampleSelector.from_examples(
    examples,
    OpenAIEmbeddings(api_key=api_key),
    Chroma,
    k=1,  # 가장 유사한 예시 1개만 선택
)
prompt = FewShotPromptTemplate(
    example_selector=example_selector,
    example_prompt=example_prompt,
    prefix="다음은 금융 관련 질문과 답변의 예입니다:",
    suffix="질문: {input}\n답변:",
    input_variables=["input"],
)

프롬프트 허브(4.2). from langchain import hub; hub.pull("rlm/rag-prompt") 처럼 커뮤니티 프롬프트를 가져다 쓰고, :커밋해시 로 특정 버전을 고정할 수 있다.

5. 출력 파서

출력 파서는 모델의 자유 텍스트 를 구조화 데이터로 바꾼다. JSON·XML·CSV·Pydantic 등 종류가 다양하다.

참고 — 최근 모델은 함수/도구 호출을 지원하므로, 가능하면 출력 파서 대신 함수/도구 호출 을 권장한다.

세 가지 메서드(5.1). - get_format_instructions() — 모델에게 전달할 형식 지침 생성. - parse() — 모델 응답 → 파이썬 객체 변환. - parse_with_prompt() — 프롬프트까지 받아 오류 수정·재시도 (RetryWithErrorOutputParser와 함께 사용).

파서별 특징(5.2~5.4).

파서 쓰임
PydanticOutputParser Pydantic BaseModel로 스키마 정의 + 데이터 검증(Field, model_validator). 형식 오류 방지.
SimpleJsonOutputParser 가벼운 JSON. 스트리밍 지원(키 값이 한 글자씩 채워지는 걸 실시간으로).
JsonOutputParser JSON 특화. pydantic_object= 로 스키마 결합, 부분 JSON 스트리밍 가능.
# PydanticOutputParser — 스키마 검증 포함
from langchain_core.output_parsers import PydanticOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field, model_validator

class FinancialAdvice(BaseModel):
    setup: str = Field(description="금융 조언 상황 질문")
    advice: str = Field(description="질문에 대한 금융 답변")

    @model_validator(mode="before")
    @classmethod
    def question_ends_with_question_mark(cls, values):
        if not values.get("setup", "").endswith("?"):
            raise ValueError("질문은 '?'로 끝나야 합니다.")
        return values

model = ChatOpenAI(model="gpt-4o", temperature=0.0)
parser = PydanticOutputParser(pydantic_object=FinancialAdvice)
prompt = PromptTemplate(
    template="다음 금융 관련 질문에 답변해 주세요.\n{format_instructions}\n질문: {query}\n",
    input_variables=["query"],
    partial_variables={"format_instructions": parser.get_format_instructions()},
)
chain = prompt | model | parser
# JsonOutputParser — Pydantic 스키마 결합 + 스트리밍
from langchain_core.output_parsers import JsonOutputParser
from pydantic import BaseModel, Field

class FinancialAdvice(BaseModel):
    setup: str = Field(description="금융 조언 상황을 설정하기 위한 질문")
    advice: str = Field(description="질문을 해결하기 위한 금융 답변")

parser = JsonOutputParser(pydantic_object=FinancialAdvice)
prompt = PromptTemplate(
    template="다음 금융 관련 질문에 답변해 주세요.\n{format_instructions}\n{query}\n",
    input_variables=["query"],
    partial_variables={"format_instructions": parser.get_format_instructions()},
)
chain = prompt | model | parser
chain.invoke({"query": "부동산에 관련하여 금융 조언을 받을 수 있게 질문하라."})
# → {"setup": "...", "advice": "..."} 딕셔너리

6. 메모리 관리: 대화 기록 유지

챗봇이 맥락 을 유지하려면 이전 대화를 기억해야 한다. 점점 더 자동화된 4단계로 발전한다.

  1. 기본 전달(6.1) — 이전 대화를 그대로 프롬프트의 ("placeholder", "{messages}") 에 끼워 넣는다. 가장 단순.
  2. ChatMessageHistory(6.2)add_user_message() / add_ai_message() 로 이력을 체계적으로 저장·재사용.
  3. RunnableWithMessageHistory(6.3) — 체인을 감싸 session_id 별로 이력을 자동 저장·로드. 수동 관리 불필요.
  4. 요약·트리밍(6.4) — 대화가 길어지면 비효율적. 트리밍(trim_messages(strategy="last", max_tokens=2))으로 최근 N개만 남기거나, 요약으로 과거를 압축해 핵심만 유지.
# RunnableWithMessageHistory — 세션별 자동 이력 관리
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_openai import ChatOpenAI

chat = ChatOpenAI(model="gpt-4o-mini")
prompt = ChatPromptTemplate.from_messages([
    ("system", "당신은 금융 상담사입니다."),
    ("placeholder", "{chat_history}"),
    ("human", "{input}"),
])
chain = prompt | chat
chat_history = ChatMessageHistory()

chain_with_history = RunnableWithMessageHistory(
    chain,
    lambda session_id: chat_history,
    input_messages_key="input",
    history_messages_key="chat_history",
)
chain_with_history.invoke(
    {"input": "저축을 늘리기 위해 무엇을 할 수 있나요?"},
    {"configurable": {"session_id": "session_1"}},
)

참고 — 요약은 토큰을 크게 아끼지만, 중요 정보 손실·맥락 왜곡 위험이 있다. 트리밍은 빠르지만 오래된 맥락을 잃는다. 대화 길이·정확도 요구에 맞춰 선택한다.

핵심 개념 정리

개념 한 줄 요약
랭체인 생태계 core(토대) + langchain(본체) + community/파트너 + langgraph/serve/smith
LCEL 러너블을 \| 로 잇는 선언적 체인. invoke/batch/stream 공통
모델 추상화 LLM을 표준 인터페이스로 감싸 클래스만 바꿔 교체
프롬프트 입력→지침 변환. 퓨샷·예제 선택기로 성능↑·토큰↓
출력 파서 자유 텍스트→구조화 데이터(Pydantic 검증, JSON 스트리밍)
메모리 수동 전달 → ChatMessageHistory → 자동 관리 → 요약·트리밍

한 문장 요약 — 랭체인은 모델·프롬프트·파서·메모리를 러너블 로 추상화하고 LCEL로 조립하게 해, RAG 같은 복잡한 LLM 앱을 모듈식으로 만들게 해주는 프레임워크다.

실무 체크리스트

  • [ ] langchain 만 깔아도 langchain-core 가 함께 설치됨을 안다 (의존성 방향).
  • [ ] OpenAI 직접 호출 대신 prompt | model | parser 체인으로 작성해 모델 교체 여지를 둔다.
  • [ ] 일관된 답이 필요하면 temperature=0, 창의적이면 높인다.
  • [ ] 구조화 출력이 필요하면 Pydantic/JSON 파서 — 또는 가능하면 함수/도구 호출.
  • [ ] 챗봇에는 RunnableWithMessageHistorysession_id 별 이력 자동 관리.
  • [ ] 대화가 길어지면 트리밍/요약으로 토큰을 관리한다.
  • [ ] stream() 사용 시 람다 함수 체인 삽입은 스트리밍 호환 여부를 확인한다.
  • [ ] PydanticOutputParser 쓸 때 model_validator로 형식 검증을 추가한다.

연습문제

  1. 개념. langchain-corelangchain 의 역할 차이를 한 문장씩으로 설명하라.
  2. 비교. OpenAI API 직접 호출 대신 랭체인을 쓸 때 얻는 가장 큰 이점 1가지와 그 근거를 들어라.
  3. 코드. prompt | model | StrOutputParser() 에서 각 단계가 받는 입력과 내보내는 출력 타입을 적어라.
  4. 적용. 같은 질문에 한국어·영어 답을 동시에 받으려면 어떤 러너블을 쓰고, 결과는 어떤 형태로 나오는가?
  5. 설계. 고객 상담 챗봇이 100턴 넘는 긴 대화를 처리한다. 트리밍과 요약 중 무엇을 택할지, 트레이드오프와 함께 논하라.

최신 동향 (2026-05 기준)

최신 동향 (검증 2026-05-21) — 책은 2025년(LangChain 0.3) 기준이므로 아래만 보완해 익히면 된다.

  • 메모리는 LangGraph 로 이동. 책의 ConversationBufferMemory·RunnableWithMessageHistory 는 LangChain 0.3에서 deprecated 되었고, 대화 상태는 LangGraph 의 persistence(checkpointer) 로 관리하는 것이 현재 권장이다. 개념 학습은 책 6절로 충분하되, 신규 코드는 LangGraph 메모리를 검토. (출처: https://python.langchain.com/docs/versions/migrating_memory/)
  • 복잡한 흐름은 LangGraph. LCEL은 안정화됐고, 분기·루프·에이전트처럼 복잡한 흐름은 LangGraph 권장(6장).
  • 모델·가격은 수시 변동. 책의 gpt-4o·Claude 3.5·Gemini 표기는 2025년 기준 예시다. 실제 사용 시 공식 모델 목록을 확인하라: OpenAI(https://platform.openai.com/docs/models)·Anthropic(https://docs.anthropic.com/en/docs/about-claude/models)·Google(https://ai.google.dev/gemini-api/docs/models).

부록 A. 용어 사전

한글 영문 의미
대규모 언어 모델 LLM (Large Language Model) 방대한 텍스트를 학습해 자연어를 이해·생성하는 모델
랭체인 LangChain LLM 앱 개발용 오픈소스 프레임워크. 모델·메모리·검색기 등을 모듈로 제공
체인 Chain 프롬프트 → 모델 → 파서처럼 여러 작업을 순서대로 연결한 작업 흐름
러너블 Runnable 체인의 각 단계가 공유하는 실행 단위 추상화. invoke·batch·stream 공통 메서드 제공
랭체인 표현 언어 LCEL (LangChain Expression Language) 러너블을 파이프(\|)로 연결해 체인을 선언적으로 기술하는 방식
프롬프트 템플릿 Prompt Template 사용자 입력·변수를 모델용 지침으로 변환하는 템플릿
출력 파서 Output Parser 모델의 자유 텍스트 응답을 구조화 데이터(JSON·Pydantic 등)로 변환하는 컴포넌트
메시지 자리 표시자 MessagesPlaceholder 대화 이력처럼 동적 메시지 목록을 프롬프트에 끼울 자리를 지정하는 특수 객체
퓨샷 프롬프트 Few-shot Prompt 예시 N개를 프롬프트에 포함해 모델 성능을 높이는 기법
예제 선택기 Example Selector 모든 예시 중 입력과 유사도가 높은 것만 골라 토큰을 절약하는 컴포넌트
트리밍 Trimming 긴 대화 이력에서 최근 N개 메시지만 남겨 토큰 사용량을 줄이는 전략
요약 Summarization 긴 대화 이력을 압축해 핵심만 남기는 메모리 관리 전략
피어 의존성 Peer Dependency 패키지가 다른 패키지를 선택적으로 사용. langgraphlangchain-core를 피어 의존성으로 취급
파트너 패키지 Partner Package 자주 쓰는 타사 통합을 분리한 패키지. langchain-openai, langchain-anthropic

부록 B. 핵심 비교표

OpenAI API 직접 호출 vs 랭체인

구분 OpenAI API 직접 랭체인
구조 단순 호출 모듈화된 체인
모델 전환 코드 수정 필요 클래스 한 줄 교체
재사용성 낮음 높음
스트리밍 별도 구현 stream() 공통 메서드
적합 상황 간단한 단일 작업 복잡·확장 가능한 앱

메모리 관리 전략 비교

전략 방식 장점 단점
수동 전달 대화 이력을 직접 프롬프트에 끼움 단순, 제어 용이 반복 코드, 확장 어려움
ChatMessageHistory 이력을 객체로 체계적 저장 코드 정리, 재사용 가능 수동 로드·저장
RunnableWithMessageHistory 체인 감싸 session_id별 자동 관리 완전 자동화, 멀티 세션 설정 필요
트리밍 최근 N개 메시지만 유지 빠름, 구현 단순 오래된 맥락 손실
요약 과거 대화를 압축 토큰 대폭 절감 정보 손실·왜곡 위험

출력 파서 비교

파서 스트리밍 Pydantic 검증 용도
StrOutputParser 가능 없음 단순 문자열 출력
SimpleJsonOutputParser 가능 없음 가벼운 JSON
JsonOutputParser 가능 선택적 JSON + 스키마 결합
PydanticOutputParser 제한적 있음 스키마 검증 필수 시

부록 C. 추천 참고 자료

검증된 외부 자료 (Tier 1 공식, 생존 확인 2026-05-21)

자료 링크
LangChain 공식 문서 python.langchain.com
LCEL & Runnable 인터페이스 concepts/runnables
채팅 모델 개념 concepts/chat_models
프롬프트 템플릿 concepts/prompt_templates
출력 파서 concepts/output_parsers
예제 선택기 how_to/example_selectors
메모리 마이그레이션 가이드 migrating_memory
실습 코드(깃허브) langchain-tutorial Ch01
자료 설명
책 2장 임베딩·벡터 DB로 첫 RAG 챗봇을 직접 만든다 (1장 LCEL의 실전 적용)
책 6장 분기·루프가 있는 복잡한 흐름은 langgraph 로 (1장에서 예고)

부록 D. 연습문제 풀이

  1. (역할 분리) langchain-core는 LLM·벡터 저장소·검색기의 기본 인터페이스와 LCEL을 정의하는 경량 토대 패키지다. langchain은 그 위에서 체인·에이전트·검색 전략 등 실제 앱 구조를 구성하는 본체 패키지로, 설치 시 langchain-core가 함께 포함된다(§1 주요 패키지 표 참조).

  2. (모델 교체 용이성) 가장 큰 이점은 모델 전환 시 클래스 한 줄만 바꾸면 된다는 점이다. OpenAI API를 직접 쓰면 client.chat.completions.create(model=...) 호출부를 코드 전반에서 수정해야 하지만, 랭체인은 ChatOpenAI(...)ChatMistralAI(...) 로 교체하는 것만으로 나머지 체인이 그대로 동작한다(§2.1 비교표·코드 예시 참조).

  3. (입출력 타입) 각 단계의 입출력은 다음과 같다.

단계 입력 출력
prompt (ChatPromptTemplate) dict (템플릿 변수 딕셔너리) ChatPromptValue (메시지 시퀀스)
model (ChatModel) ChatPromptValue 또는 메시지 시퀀스 AIMessage (모델 응답 객체)
StrOutputParser() AIMessage str (최종 텍스트)

한 단계의 출력 타입이 다음 단계의 입력 타입과 일치하기 때문에 파이프(|)로 연결이 가능하다(§3.2 체인 연결 참조).

  1. (병렬 실행) RunnableParallel을 사용한다. 한국어 체인과 영어 체인을 각각 정의한 뒤 RunnableParallel(kor=..., eng=...) 로 감싸면 두 체인이 동시에 실행된다. 결과는 {"kor": "한국어 답", "eng": "English answer"} 형태의 딕셔너리로 반환된다(§3.2 RunnableParallel 설명 참조).

  2. (트리밍 vs 요약 선택) 상담 챗봇처럼 100턴을 넘는 대화에서는 두 전략 모두 유효하나, 트레이드오프가 다르다. 트리밍은 구현이 단순하고 속도가 빠르지만 오래된 맥락(초기 문제 상황·사용자 배경 등)을 잃어 정확도가 떨어질 수 있다. 요약은 토큰을 대폭 절감하면서 과거 정보를 일부 유지하지만, 중요 세부 내용의 손실·왜곡 위험이 있다(§6.4 참조). 따라서 초기 맥락이 후반 응답의 정확도에 결정적인 상담 챗봇이라면 요약을 우선 검토하되, 요약 품질을 별도로 검증해야 한다. 맥락 의존도가 낮고 처리 속도가 중요한 경우에는 트리밍이 실용적이다.

난이도
에피소드
질문
카드를 로딩 중...
답변

클릭하거나 Space를 눌러 뒤집기

0 / 0
학습 진도 0%
이동   Space 뒤집기   R 셔플