반응형

LLM을 단순히 API 호출로 쓰는 수준을 넘어서, 실제 애플리케이션에 활용하려면 체인 구성, 상태 관리, 스트리밍, 관측성까지 고려해야 한다. LangChain은 이런 요구를 체계적으로 해결할 수 있도록 설계된 대표적인 프레임워크다.
이 글에서는 LCEL & Runnable → 스트리밍 → 배포/운영 → 선택 가이드 → LangChain 장점 순서로 핵심을 정리한다.
1) LCEL & Runnable
LCEL과 Runnable
- LangChain Expression Language(LCEL)은 LangChain에서 체인과 에이전트를 선언적이고 간결하게 표현하는 문법이다.
- 핵심은 모든 컴포넌트를 Runnable이라는 실행 단위로 추상화한다는 점이다.
Runnable은 LangChain이 정의한 실행 가능한 최소 단위 인터페이스다.
프롬프트, LLM, 파서, 툴 등 모든 요소가 Runnable을 구현하며, 덕분에 invoke, batch, stream 같은 공통 메서드로 일관되게 실행할 수 있다.
즉, LCEL은 Runnable들을 파이프(|)로 연결해 선언적 체인을 구성하는 방식이다.
왜 LCEL인가
- 표현력: 파이프(
|)로 체인을 직관적으로 선언 → 코드 길이·인지부하 감소. - 일관 실행 모델:
invoke / batch / stream / astream_events통일 인터페이스. - 성능 기본기: 비동기·병렬화·스트리밍을 프레임워크 레벨에서 최적화.
- 관측성 연동: LangSmith와 기본 통합 → 디버깅·회귀 분석이 용이.
핵심 API 한눈에
- 실행:
invoke(input),batch(list[inputs]),stream/astream(input) - 이벤트 스트림:
astream_events(input)(중간 단계/토큰/툴 호출 포함) - 합성:
RunnableSequence(순차),RunnableParallel(병렬) - 신뢰성:
.with_retry(),.with_fallback() - 스키마 고정:
.with_types(input_schema=..., output_schema=...)
조합 패턴 예시
# 순차 파이프 (프롬프트 → 모델 → 파서)
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
prompt = ChatPromptTemplate.from_template("Translate to French: {text}")
model = ChatOpenAI(model="gpt-4o-mini", streaming=True)
chain = prompt | model | StrOutputParser()
print(chain.invoke({"text": "Hello"}))
# 병렬 조합 (두 결과를 동시에 얻고 합치기)
from langchain_core.runnables import RunnableParallel
joke = (ChatPromptTemplate.from_template("joke about {topic}") | model)
poem = (ChatPromptTemplate.from_template("2-line poem about {topic}") | model)
both = RunnableParallel(joke=joke, poem=poem)
# both.invoke({"topic": "cats"}) → {"joke": ..., "poem": ...}
타입/신뢰성 보강
- 타입 고정:
.with_types()로 I/O 스키마를 명시. - 리트라이/폴백:
.with_retry(),.with_fallback()으로 API 오류·모델 불안정에 대비. - 계약 검증: LangServe가 JSON Schema로 문서화·검증.
미니 예제
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
prompt = ChatPromptTemplate.from_template(
"You are a concise assistant. Answer shortly.\nQ: {q}\nA:"
)
model = ChatOpenAI(model="gpt-4o-mini", streaming=True)
chain = prompt | model | StrOutputParser()
for chunk in chain.stream({"q": "What is LCEL?"}):
print(chunk, end="", flush=True)
2) 스트리밍 — SSE, WebSocket, 이벤트
언제 SSE, 언제 WebSocket?
| 요구 | 추천 | 이유 |
|---|---|---|
| 일방향 토큰 스트림(서버→클라) | SSE | 단순/가볍고, 프록시 친화, 브라우저 기본 지원 |
| 양방향 상호작용(취소/피드백 루프) | WebSocket | 임의 시점 송수신, 세션 제어 용이 |
- 일반 LLM 응답 스트리밍은 SSE로 충분.
- 도중 취소/수정 같은 양방향 상호작용은 WS 고려.
stream vs stream_events
stream / astream→ 최종 출력 청크만 순차 전달.astream_events→ 중간 단계 이벤트(LLM/툴 시작·종료, 토큰 등)까지 전달 → 리치 UI·디버깅에 유리.
FastAPI SSE 스니펫
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
app = FastAPI()
def sse(chain, q: str):
def gen():
for chunk in chain.stream({"q": q}):
yield f"data: {chunk}\n\n"
return StreamingResponse(gen(), media_type="text/event-stream")
운영 시 유의:
- 역프록시 버퍼링/압축은 지연 유발 →
X-Accel-Buffering: no, gzip off 권장. - POST+SSE는 EventSource 미지원 →
fetch-event-source등 폴리필 사용.
LangGraph 스트리밍
graph.stream(state)로 노드 단위 결과가 순차 도착.- Platform 사용 시 토큰/노드 업데이트, 사용자 인터럽트를 이벤트로 구독 가능.
3) 배포/운영 — LangServe vs LangGraph Platform
배포 옵션 비교
| 항목 | LangServe | LangGraph Platform |
|---|---|---|
| 철학 | Runnable를 REST로 빠르게 노출 | 상태형 에이전트 운영·스케일 |
| 엔드포인트 | /invoke, /batch, /stream, /stream_events, /playground |
프로젝트 관리, 그래프 시각화, 버전/릴리즈 |
| 상태/세션 | 무상태 | 체크포인트, 장기 실행, 인터럽트·재개 |
| 운영 난이도 | 낮음 (FastAPI 운영) | 플랫폼 편의성↑, 온보딩 필요 |
| 확장 | 컨테이너 스케일 | Cloud/Hybrid/Self-hosted |
| 권고 | 단순 체인·빠른 API화 | 멀티에이전트·장기 실행·협업 중심 |
관측성
- LangSmith: 체인 실행 추적, 토큰·지연·에러 분석.
- Platform: 그래프·노드 상태 시각화, 팀 협업, 릴리즈 관리.
성능·신뢰성 체크리스트
- 병렬화: 독립 단계는
RunnableParallel. - 스트리밍 우선: TTFB 단축, UX 개선.
- 리트라이/폴백: 불안정성 방어.
- 타임아웃/백오프: Rate Limit 대응.
- 캐싱: 반복 질의·임베딩 캐시.
- 메모리 관리: 요약·윈도우링.
- 에러 표면화: SSE 이벤트와 로깅 일치.
- 부하시험: 목표 QPS 산정, 워커 튜닝.
- 인터럽트: 중복 요청/취소 신호 처리.
4) 선택 가이드
=> 단순 체인은 LCEL(+LangServe), 상태형·복잡 에이전트는 LangGraph(Platform)
- PoC/단순 RAG → LCEL + LangServe.
- 분기·루프·장기 세션 → LangGraph.
- 프로토타입 → 제품화: LCEL로 시작, 운영 요구 커지면 LangGraph로 마이그레이션.
- 팀 협업/가시성: Platform 사용 권장.
LangChain 장점 정리
- 표준화된 실행 모델 (Runnable & LCEL)
- 선언적 파이프라인 (LCEL)
- 성능·안정성 내장 (비동기, 병렬, 스트리밍, retry/fallback)
- 관측성 통합 (LangSmith)
- 배포·운영 선택지 다양성 (LangServe, LangGraph Platform)
- 생태계 확장성 (RAG, 멀티에이전트, 툴 통합)
참고 링크
반응형