AI VIDEO BRIEFING

LangChain LCEL 순차 체인: RunnablePassthrough·itemgetter로 맥락 손실 해결하기

LangChain의 파이프 연산자는 출력 하나만 전달해 다단계 LLM 파이프라인에서 맥락이 사라진다. dict 단계와 RunnablePassthrough, itemgetter로 변수를 분기마다 라우팅해 이 문제를 해결하는 방법을 정리했다.

LangChain LCEL 순차 체인으로 다단계 AI 파이프라인의 맥락 손실 막기 영상 대표 이미지

핵심 메시지

  • LangChain의 파이프(|) 연산자는 한 번에 입력 하나, 출력 하나만 전달하기 때문에 3단계 이상으로 길어지면 앞 단계 데이터가 자동으로 사라진다.
  • 모든 프롬프트 템플릿은 직전 출력뿐 아니라 자신이 의존하는 모든 상위 단계 변수를 명시적으로 선언해야 한다.
  • 파이프라인 중간에 파이썬 dict를 넣으면 LCEL이 이를 자동으로 RunnableParallel로 바꿔 여러 값을 동시에 만들어 전달한다.
  • RunnablePassthrough는 입력을 그대로 통과시키고, itemgetter는 딕셔너리에서 키 하나만 골라 전달하는 정밀 도구다.
  • LCEL 체인을 데이터 흐름 그래프로 바라보면 설계가 코딩 문제가 아니라 라우팅 문제로 단순해진다.

쉽게 이해하기

여러 번의 LLM 호출을 순서대로 잇는 순차 체인에서는 한 단계의 출력이 다음 단계의 입력이 된다. 문제는 LangChain의 파이프 연산자가 직전 단계의 출력 하나만 다음으로 넘긴다는 점이다. 그래서 3단계 프롬프트가 1단계에서 나온 데이터까지 필요로 하면 그 데이터는 이미 흘러가 버려 맥락 손실이 발생한다. 많은 튜토리얼이 잘 동작하는 2단계 예제만 보여주고 정작 문제가 터지는 3단계는 다루지 않는다.

영상은 블로그 작성 파이프라인을 예로 든다. 1단계는 질문에서 주제를 뽑고, 2단계는 topic과 question으로 블로그 글을 쓰며, 3단계는 blog_post와 question으로 일반 독자용 요약을 만든다. 1단계 출력 문자열을 곧장 2단계 프롬프트에 연결하면 2단계는 두 변수를 기대하는데 문자열 하나만 받아 오류가 난다. StrOutputParser가 모든 것을 텍스트로 바꿔 키가 사라지기 때문이며, 이는 버그가 아니라 받은 그대로 하나만 전달한다는 정상 동작이다.

해결책은 두 단계 사이에 dict 단계를 끼우는 것이다. LCEL은 파이프라인 안에 놓인 파이썬 dict를 자동으로 RunnableParallel로 변환한다. {topic: chain_one, question: RunnablePassthrough()} 형태로 쓰면 같은 입력에 대해 1단계 체인과 패스스루가 동시에 실행되어 추출된 주제와 원래 질문이 함께 담긴 딕셔너리를 만든다. RunnablePassthrough는 물이 들어온 그대로 나가는 유리 파이프처럼 원본 값을 변형 없이 하류로 흘려보낸다.

3단계를 더하면 다시 문제가 생긴다. 2단계 출력은 또 평범한 문자열이라 question 키가 사라지기 때문이다. 이때 파이썬 operator 모듈의 itemgetter를 쓴 또 하나의 dict 단계를 추가한다. {blog_post: 2단계_체인, question: itemgetter("question")}처럼 작성하면 itemgetter가 들어온 딕셔너리에서 지정한 키 하나만 뽑아 전달한다. 전체를 통과시키는 RunnablePassthrough와 달리 itemgetter는 키 하나만 골라내는 외과적 추출기다.

영상은 코드 리뷰 파이프라인으로 마무리한다. 1단계는 코드를 분석해 버그 목록을 만들고, 2단계는 코드와 이슈로 수정안을 제안하며, 3단계는 코드와 수정안으로 최종 보고서를 쓴다. dict 단계와 itemgetter, RunnablePassthrough를 분기마다 배치해 원본 코드 문자열이 필요한 모든 단계에 정확히 도달하게 만든다. 클래스 상속과 숨은 동작으로 데이터 흐름을 불투명하게 만들던 레거시 SequentialChain은 LangChain 0.3.0에서 제거되었다.

주요 인사이트

  • 순차 체인의 오류 대부분은 코드 버그가 아니라 어떤 변수를 어디로 보낼지 정의하지 않은 라우팅 누락에서 비롯된다. 코드를 쓰기 전에 모든 프롬프트의 입력 변수를 먼저 설계하면 원인 모를 변수 키 오류를 예방할 수 있다.
  • dict가 자동으로 RunnableParallel이 된다는 점은 많은 튜토리얼이 건너뛰는 핵심 통찰이다. 이 덕분에 여러 값을 동시에 만들어 하나의 딕셔너리로 묶어 다음 단계에 넘길 수 있다.
  • RunnablePassthrough는 전체를 통과시키고 itemgetter는 키 하나만 추출한다는 점에서 역할이 분명히 다르며, 필요한 정밀도에 따라 골라 써야 한다.
  • LCEL 체인을 단방향 데이터 흐름 그래프로 이해하면 단계 수가 늘어도 같은 방식으로 확장할 수 있다. 파이프는 앞으로만 흐르므로 상위 데이터가 필요하면 분기마다 명시적으로 연결해야 한다.

자주 묻는 질문

LangChain의 파이프 연산자는 왜 맥락을 잃나요?

파이프는 한 번에 입력 하나를 받아 출력 하나만 내보내기 때문에 직전 단계의 출력만 전달됩니다. 더 앞 단계의 데이터는 자동으로 따라오지 않아, 그 데이터가 필요한 하류 단계에서는 값이 사라진 것처럼 보입니다.

RunnablePassthrough와 itemgetter는 어떻게 다른가요?

RunnablePassthrough는 입력값을 변형 없이 그대로 전체 전달합니다. itemgetter는 들어온 딕셔너리에서 지정한 키 하나만 뽑아 그 값만 전달합니다.

파이프라인 안에 파이썬 dict를 넣으면 어떻게 되나요?

LCEL이 그 dict를 자동으로 RunnableParallel로 변환해, 같은 입력에 대해 각 값을 동시에 실행한 뒤 결과를 하나의 딕셔너리로 묶어 다음 단계로 넘깁니다.

레거시 SequentialChain은 아직 쓸 수 있나요?

영상에 따르면 레거시 SequentialChain 방식은 LangChain 0.3.0에서 제거되었습니다.

원문과 출처

이 글은 원본 영상의 자막을 바탕으로 한국어 독자를 위해 요약했습니다. 전체 맥락과 최신 정보는 원문에서 확인하세요.

YouTube 원본 영상 보기 ↗

관련 AI 소식

#LangChain#LCEL#RunnablePassthrough#itemgetter#LLM파이프라인