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단계로 발전한다.
- 기본 전달(6.1) — 이전 대화를 그대로 프롬프트의
("placeholder", "{messages}")에 끼워 넣는다. 가장 단순. ChatMessageHistory(6.2) —add_user_message()/add_ai_message()로 이력을 체계적으로 저장·재사용.RunnableWithMessageHistory(6.3) — 체인을 감싸session_id별로 이력을 자동 저장·로드. 수동 관리 불필요.- 요약·트리밍(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 파서 — 또는 가능하면 함수/도구 호출.
- [ ] 챗봇에는
RunnableWithMessageHistory로session_id별 이력 자동 관리. - [ ] 대화가 길어지면 트리밍/요약으로 토큰을 관리한다.
- [ ]
stream()사용 시 람다 함수 체인 삽입은 스트리밍 호환 여부를 확인한다. - [ ]
PydanticOutputParser쓸 때model_validator로 형식 검증을 추가한다.
연습문제
- 개념.
langchain-core와langchain의 역할 차이를 한 문장씩으로 설명하라. - 비교. OpenAI API 직접 호출 대신 랭체인을 쓸 때 얻는 가장 큰 이점 1가지와 그 근거를 들어라.
- 코드.
prompt | model | StrOutputParser()에서 각 단계가 받는 입력과 내보내는 출력 타입을 적어라. - 적용. 같은 질문에 한국어·영어 답을 동시에 받으려면 어떤 러너블을 쓰고, 결과는 어떤 형태로 나오는가?
- 설계. 고객 상담 챗봇이 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 | 패키지가 다른 패키지를 선택적으로 사용. langgraph가 langchain-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. 연습문제 풀이
-
(역할 분리)
langchain-core는 LLM·벡터 저장소·검색기의 기본 인터페이스와 LCEL을 정의하는 경량 토대 패키지다.langchain은 그 위에서 체인·에이전트·검색 전략 등 실제 앱 구조를 구성하는 본체 패키지로, 설치 시langchain-core가 함께 포함된다(§1 주요 패키지 표 참조). -
(모델 교체 용이성) 가장 큰 이점은 모델 전환 시 클래스 한 줄만 바꾸면 된다는 점이다. OpenAI API를 직접 쓰면
client.chat.completions.create(model=...)호출부를 코드 전반에서 수정해야 하지만, 랭체인은ChatOpenAI(...)를ChatMistralAI(...)로 교체하는 것만으로 나머지 체인이 그대로 동작한다(§2.1 비교표·코드 예시 참조). -
(입출력 타입) 각 단계의 입출력은 다음과 같다.
| 단계 | 입력 | 출력 |
|---|---|---|
prompt (ChatPromptTemplate) |
dict (템플릿 변수 딕셔너리) |
ChatPromptValue (메시지 시퀀스) |
model (ChatModel) |
ChatPromptValue 또는 메시지 시퀀스 |
AIMessage (모델 응답 객체) |
StrOutputParser() |
AIMessage |
str (최종 텍스트) |
한 단계의 출력 타입이 다음 단계의 입력 타입과 일치하기 때문에 파이프(|)로 연결이 가능하다(§3.2 체인 연결 참조).
-
(병렬 실행)
RunnableParallel을 사용한다. 한국어 체인과 영어 체인을 각각 정의한 뒤RunnableParallel(kor=..., eng=...)로 감싸면 두 체인이 동시에 실행된다. 결과는{"kor": "한국어 답", "eng": "English answer"}형태의 딕셔너리로 반환된다(§3.2RunnableParallel설명 참조). -
(트리밍 vs 요약 선택) 상담 챗봇처럼 100턴을 넘는 대화에서는 두 전략 모두 유효하나, 트레이드오프가 다르다. 트리밍은 구현이 단순하고 속도가 빠르지만 오래된 맥락(초기 문제 상황·사용자 배경 등)을 잃어 정확도가 떨어질 수 있다. 요약은 토큰을 대폭 절감하면서 과거 정보를 일부 유지하지만, 중요 세부 내용의 손실·왜곡 위험이 있다(§6.4 참조). 따라서 초기 맥락이 후반 응답의 정확도에 결정적인 상담 챗봇이라면 요약을 우선 검토하되, 요약 품질을 별도로 검증해야 한다. 맥락 의존도가 낮고 처리 속도가 중요한 경우에는 트리밍이 실용적이다.
클릭하거나 Space를 눌러 뒤집기