LCEL(LangChain Expression Language) 사용 이유
“그냥 f-string 쓰면 되지, 왜 굳이 LCEL을 써야 하지?”
처음 강의를 들을 땐 이렇게 생각했다. 하지만 실습을 진행하며
LCEL이 왜 필요한지 자연스럽게 깨닫게 되었다.
이 글에서는 f-string 방식의 한계와 LCEL이 제공하는 이점,
그리고 ChatPromptTemplate, RunnableLambda까지 어떤 역할을 하는지 명확하게 정리해본다.
1. f-string 방식의 한계
prompt = f"너는 전문가야. {user\_input}에 대해 설명해줘."
처음엔 편하다. 하지만 실무에서는 다음 문제들이 터진다.
1) 프롬프트 변경 시 매번 코드 수정
기획자/PM이 문구 한 줄만 바꿔달라고 해도
→ 코드 수정 → 테스트 → 배포 반복.
2) 중복 증가
비슷한 프롬프트를 복붙하다 보면 수정해야 할 곳이 여러 군데 생긴다.
3) 구조가 깨지기 쉬움
사용자 입력이 이상하면 프롬프트 구조가 깨지거나 injection 문제 발생.
4) 체이닝이 안 됨
프롬프트 → LLM → 파싱 → 후처리
이런 전체 파이프라인을 함수 하나로 깔끔하게 묶기 어렵다.
2. LCEL을 사용하면 얻는 핵심 장점
LCEL은 LangChain의 선언형 파이프라인 구성 언어다.
예를 들면 이런 식이다:
chain = prompt | llm | parser
이렇게 작성하는 것이 단순히 “멋있어 보인다” 수준이 아닌, 진짜 큰 장점들이 있다.
1) 프롬프트 관리가 쉬워짐
코드와 프롬프트를 완전히 분리할 수 있어 유지보수가 쉬워진다.
2) 안전성 증가 (Injection 방지)
템플릿 구조가 고정되기 때문에 사용자 입력이 전체 프롬프트를 깨뜨릴 수 없다.
3) 체이닝 가능
프롬프트 → 모델 → 파서 → 후처리 과정을
파이프 형태로 선언적으로 연결할 수 있다.
4) LangSmith 트래킹 자동 적용
입력/출력/에러 흐름이 자동 기록된다.
5) 재사용성 매우 높음
여러 모델에 같은 프롬프트를 쓰거나, 여러 프롬프트 + 같은 LLM 조합으로 파이프라인을 쉽게 구성 가능.
결국 LCEL은 유지보수 + 안전성 + 확장성 모두 잡기 위한 선택이다.
3. ChatPromptTemplate과 RunnableLambda의 차이
LCEL을 제대로 이해하려면 ChatPromptTemplate과 RunnableLambda를 알아야 한다.
둘은 완전히 다른 역할을 수행한다.
ChatPromptTemplate
“프롬프트 구조를 정의하는 템플릿”
프롬프트를 선언적으로 만들고, 변수 바인딩을 안전하게 관리하는 도구
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_template("""
너는 전문가야. 아래 주제에 대해 설명해라.
주제: {topic}
""")
ChatPromptTemplate의 특징
- 프롬프트 구조를 깔끔하게 템플릿화
- 변수명 검증 자동 지원
- 안전하게 파라미터 바인딩
- YAML/JSON 등 외부 파일로도 쉽게 관리 가능
- f-string보다 안전하고 변경에 강함
ChatPromptTemplate은 “프롬프트 전문 관리 도구” 라고 이해하면 된다.
RunnableLambda
“파이프라인 중간에서 로직을 수행하는 단계”
LLM 호출 전/후에 파이썬 함수 로직을 끼워넣고 싶을 때 사용한다.
from langchain_core.runnables import RunnableLambda
extractkeywords = RunnableLambda(lambda x: {"keywords": x["text"].split()})
RunnableLambda의 특징
1. 입력값을 받아 파이썬 함수로 가공
2. LLM에 들어가기 전 입력값 전처리 가능
3. LLM 결과 후처리 가능
4. 체인이 복잡해질 때 매우 유용
예를 들어:
사용자 입력 → JSON 변환 → 모델 입력 구조로 재정렬 → LLM → 파싱 → DB 저장
이런 흐름에서 모든 중간 단계 로직을 RunnableLambda로 표현할 수 있다.
ChatPromptTemplate vs RunnableLambda 비교
항목ChatPromptTemplateRunnableLambda
| 목적 | 프롬프트 구조 정의 | 임의의 파이썬 로직 실행 |
|---|---|---|
| 위치 | LLM 호출 직전 | 어디든 삽입 가능 |
| 역할 | 변수 바인딩·문자열 템플릿 | 전처리·후처리·데이터 가공 |
| 사용 방식 | ChatPromptTemplate.from_template() | RunnableLambda(lambda x: ...) |
| 주 용도 | 프롬프트 관리 | 데이터 조작, 파이프라인 로직 |
ChatPromptTemplate = “프롬프트 만들기”
RunnableLambda = “파이프라인 중간 처리(전처리·후처리)”
4. ChatPromptTemplate + RunnableLambda + LCEL
= 완성형 AI 파이프라인
LCEL을 제대로 쓰려면 둘을 조합해야 한다.
chain = (
ChatPromptTemplate.from_template(
"주제: {topic}"
| llm
| RunnableLambda(lambda x: x["output"].upper()
))
1. 프롬프트 템플릿 작성
2. LLM 호출
3. 후처리 로직 실행
이 모든 걸 파이프(|)로 한 번에 구성할 수 있다.
마무리: LCEL은 현대 AI 서비스의 “정석 패턴”
LCEL은 단순한 프롬프트 작성 방식이 아니라
전체 AI 파이프라인을 선언적으로 구성하는 프레임워크다.
ChatPromptTemplate → 프롬프트 관리
RunnableLambda → 데이터 처리
LCEL → 전체 연결 및 실행
AI 에이전트, RAG, 자동화 시스템 등
규모가 커질수록 LCEL의 강점은 더 커진다.