LCEL로 체인 구축하기
파이프 연산자로 프롬프트 템플릿, LLM, 출력 파서를 Runnable 시퀀스로 연결하고, 이를 동기 및 비동기로 호출하며, 중간 출력을 확인합니다.
LCEL로 체인 구축하기은(는) CoddyKit의 무료 AI Engineering Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Engineering Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Engineering Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
LCEL이란 무엇인가요?
LCEL (LangChain Expression Language)은 LangChain 구성 요소를 파이프라인으로 선언적으로 조합하는 방법입니다. 장황한 Chain 클래스를 인스턴스화하는 대신 | 연산자로 Runnable을 연결합니다. LCEL 체인은 스트리밍, 비동기 처리, 일괄 처리, 대체 체인을 자동으로 지원하므로 파이프 구문을 사용하는 것만으로 이러한 기능을 모두 이용할 수 있습니다.
첫 번째 LCEL 체인
가장 간단한 LCEL 체인은 PromptTemplate, ChatModel, OutputParser를 조합합니다. 각 구성 요소는 Runnable이며, 파이프 연산자가 이들을 연결합니다. chain.invoke()를 호출하면 입력이 각 단계를 순서대로 통과하고, 각 단계의 출력이 다음 단계의 입력이 됩니다.
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
prompt = ChatPromptTemplate.from_template(
'Write a product description for: {product}'
)
model = ChatOpenAI(model='gpt-4o-mini', temperature=0.7)
parser = StrOutputParser()
chain = prompt | model | parser
result = chain.invoke({'product': 'noise-cancelling headphones'})
print(result)체인 내부 구조 살펴보기
LCEL 체인은 구조를 투명하게 보여줍니다. chain.steps에는 구성 요소가 순서대로 나열됩니다. chain.input_schema와 chain.output_schema를 호출하면 입력과 출력으로 전달되는 형식을 확인할 수 있습니다. 또한 invoke() 호출은 체인 정의를 변경하지 않고 단일 호출에 실행 이름, 태그, 콜백을 전달할 수 있는 config 매개변수를 받습니다.
# Inspect chain structure
print('Steps:', chain.steps)
print('Input schema:', chain.input_schema.schema())
print('Output schema:', chain.output_schema.schema())
# Named run for observability
result = chain.invoke(
{'product': 'coffee maker'},
config={'run_name': 'product-desc-run', 'tags': ['production']}
)동기 호출과 비동기 호출 비교
LCEL 체인은 모든 메서드에 대해 동기 버전과 비동기 버전을 제공합니다. invoke()는 호출한 스레드를 차단합니다. ainvoke()는 비동기 방식에 해당하며 이벤트 루프를 차단하지 않도록 FastAPI 핸들러 및 기타 비동기 컨텍스트에서 사용해야 합니다. 비동기 버전의 의미는 동일하며, 인터페이스상의 차이는 await뿐입니다.
import asyncio
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
chain = ChatPromptTemplate.from_template('Explain {topic}') | ChatOpenAI() | StrOutputParser()
async def main():
# Async invocation
result = await chain.ainvoke({'topic': 'quantum computing'})
print(result)
asyncio.run(main())체인을 통한 토큰 스트리밍
LCEL 체인은 전체 과정에서 스트리밍을 전달합니다. chain.stream()을 호출하면 모델이 토큰을 생성하는 즉시 받을 수 있습니다. StrOutputParser는 스트리밍을 인식하므로 전체 응답을 기다리지 않고 개별 문자열 청크를 전달합니다. 따라서 사용자는 긴 대기 후 완성된 답변을 받는 대신 즉시 피드백을 받을 수 있습니다.
chain = (
ChatPromptTemplate.from_template('Tell me about {topic} in detail.')
| ChatOpenAI(model='gpt-4o-mini')
| StrOutputParser()
)
# Print each token as it arrives
for chunk in chain.stream({'topic': 'neural networks'}):
print(chunk, end='', flush=True)
print() # newline at end
# Async streaming
async def stream_async():
async for chunk in chain.astream({'topic': 'transformers'}):
print(chunk, end='', flush=True)여러 입력 일괄 처리
chain.batch()는 입력 사전 목록을 받아 설정 가능한 동시성으로 처리합니다. LangChain은 내부적으로 호출을 병렬 스레드에서 실행하므로 반복문에서 invoke()를 호출하는 것보다 일괄 처리가 훨씬 빠릅니다. max_concurrency 매개변수는 병렬 API 호출 수를 제한하여 요청률 제한을 초과하지 않도록 합니다. 결과는 입력과 같은 순서로 반환됩니다.
products = [
{'product': 'laptop'},
{'product': 'tablet'},
{'product': 'smartwatch'},
{'product': 'earbuds'},
]
# Process all 4 concurrently
results = chain.batch(products, config={'max_concurrency': 4})
for product, description in zip(products, results):
print(f'{product["product"]}: {description[:80]}...')RunnablePassthrough와 RunnableLambda
RunnablePassthrough는 입력을 변경하지 않고 그대로 전달하므로, 변환된 데이터와 함께 원래 컨텍스트를 전달할 때 유용합니다. RunnableLambda는 모든 Python 함수를 Runnable로 감싸 LCEL 체인에 임의의 로직을 삽입할 수 있게 합니다. 이 둘을 함께 사용하면 완전한 사용자 지정 Runnable 클래스를 작성하지 않고도 체인 단계 사이에서 데이터를 조작할 수 있습니다.
from langchain_core.runnables import RunnablePassthrough, RunnableLambda
def word_count(text: str) -> str:
count = len(text.split())
return f'{text}\n\n[Word count: {count}]'
chain = (
ChatPromptTemplate.from_template('Write about {topic}')
| ChatOpenAI(model='gpt-4o-mini')
| StrOutputParser()
| RunnableLambda(word_count) # Add word count to output
)
result = chain.invoke({'topic': 'climate change'})
print(result)RunnablePassthrough로 추가 컨텍스트 전달하기
RAG에서 흔히 사용하는 패턴은 검색된 문서와 사용자 질문을 모두 최종 프롬프트에 전달하는 것입니다. RunnablePassthrough.assign()을 사용하면 원래 키를 잃지 않고 입력 사전에 계산된 필드를 추가할 수 있습니다. 이렇게 하면 체인을 통과하는 동안 컨텍스트 객체가 확장되어 모든 데이터를 프롬프트 템플릿에서 사용할 수 있습니다.
from langchain_core.runnables import RunnablePassthrough
# Fake retriever for illustration
def retrieve_docs(question: str):
return ['Doc 1 content', 'Doc 2 content']
retriever = RunnableLambda(retrieve_docs)
rag_chain = (
RunnablePassthrough.assign(context=retriever) # adds 'context' key
| ChatPromptTemplate.from_template(
'Context: {context}\n\nAnswer: {question}'
)
| ChatOpenAI()
| StrOutputParser()
)
result = rag_chain.invoke({'question': 'What is machine learning?'})체인에 대체 체인 추가하기
LCEL 체인은 기본 체인에서 예외가 발생할 때 시도할 대체 체인을 지원합니다. chain.with_fallbacks([backup_chain])을 호출하면 하나 이상의 대체 체인을 등록할 수 있습니다. LangChain은 먼저 기본 체인을 시도하고, 예외가 발생하면 이를 포착한 뒤 대체 체인을 순서대로 시도합니다. 이는 서비스 제공자 장애나 모델 오류를 안정적으로 처리하는 표준적인 방법입니다.
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
primary_chain = (
ChatPromptTemplate.from_template('Answer: {question}')
| ChatOpenAI(model='gpt-4o')
| StrOutputParser()
)
fallback_chain = (
ChatPromptTemplate.from_template('Answer: {question}')
| ChatAnthropic(model='claude-3-haiku-20240307')
| StrOutputParser()
)
robust_chain = primary_chain.with_fallbacks([fallback_chain])
# If OpenAI fails, automatically tries Anthropic중간 단계로 디버깅하기
invoke()의 config와 verbose=True 옵션을 사용하면 LCEL 체인을 더 쉽게 디버깅할 수 있습니다. 또한 모든 체인에서 .with_config({'verbose': True})를 사용하여 각 단계의 입력과 출력을 기록할 수 있습니다. 구조화된 디버깅을 위해 전역에서 체인을 set_verbose(True)로 설정하거나 LangSmith 추적을 사용하면 시각적 추적 탐색기에서 모든 중간 값을 확인할 수 있습니다.
from langchain.globals import set_verbose, set_debug
# Verbose: logs LLM inputs/outputs
set_verbose(True)
# Debug: logs everything including prompts, parsers, and runnables
set_debug(True)
result = chain.invoke({'product': 'smart watch'})
# Or per-chain verbose config
chain_debug = chain.with_config({'verbose': True})
result = chain_debug.invoke({'product': 'laptop'})실행 시점에 구성 가능한 체인
LCEL 체인은 ConfigurableField를 통해 실행 시점 구성을 지원합니다. 모델 매개변수인 temperature, model name, max_tokens를 코드에 고정하지 않고 구성 가능한 옵션으로 노출할 수 있습니다. 호출할 때 Configurable config를 전달하면 기본값을 재정의할 수 있습니다. 이를 통해 서로 다른 설정을 사용하는 여러 사용자에게 하나의 체인을 제공하거나 모델 구성을 A/B 테스트할 수 있습니다.
from langchain_core.runnables import ConfigurableField
llm = ChatOpenAI(model='gpt-4o-mini').configurable_fields(
temperature=ConfigurableField(
id='temperature',
name='LLM Temperature',
description='Controls output creativity'
)
)
chain = ChatPromptTemplate.from_template('Write about {topic}') | llm | StrOutputParser()
# Low temperature for factual output
factual = chain.invoke(
{'topic': 'history of Rome'},
config={'configurable': {'temperature': 0.0}}
)빠른 확인
LCEL을 사용한 체인 구축에 대한 이해도를 확인해 보세요.
레슨 요약
이 레슨에서는 다음을 배웠습니다. LCEL 파이프 조합은 |를 사용해 Runnable을 깔끔하고 읽기 쉬운 파이프라인으로 연결합니다. RunnablePassthrough와 RunnableLambda를 사용하면 LCEL 방식을 벗어나지 않고 데이터 조작 단계를 삽입할 수 있습니다. 또한 대체 체인은 오류 발생 시 백업 체인을 자동으로 시도하여 체인의 복원력을 높입니다. 다음으로 더 복잡한 라우팅 로직을 위한 분기 체인과 병렬 체인을 살펴보겠습니다.
AI 튜터와 함께 Python을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 30
- 레슨
- 120
자주 묻는 질문
“LCEL로 체인 구축하기” 강의는 무료인가요?
네 — “LCEL로 체인 구축하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Engineering Academy 강의 전체를 잠금 해제할 수 있습니다. AI Engineering Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“LCEL로 체인 구축하기”에서 뭘 배우나요?
파이프 연산자로 프롬프트 템플릿, LLM, 출력 파서를 Runnable 시퀀스로 연결하고, 이를 동기 및 비동기로 호출하며, 중간 출력을 확인합니다. 브라우저에서 직접 실행하는 실습 코드로 AI Engineering Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
AI Engineering Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 AI Engineering Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“LCEL로 체인 구축하기” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 AI Engineering Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 AI Engineering Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.