한 단계의 인자를 다음 단계로 그대로 넘기기
한 단계의 인자를 다음 단계로 그대로 넘기기 (How to pass through arguments from one step to the next)
여러 단계로 이루어진 체인을 구성하다 보면, 이전 단계의 데이터를 그대로 보존해서 나중 단계의 입력으로 써야 할 때가 있어요. RunnablePassthrough는 바로 그 역할을 하는 클래스예요. 보통 RunnableParallel과 함께 써서 체인의 나중 단계로 데이터를 통과시켜 줍니다.
출처: 공식문서
사전 준비
이 가이드를 따라가려면 다음 개념에 익숙해져 있으면 좋아요.
- LangChain Expression Language (LCEL)
- 러너블 이어 붙이기 (Chaining runnables)
- 러너블 병렬 실행 (Calling runnables in parallel)
- 커스텀 함수 (Custom functions)
동작 방식
예시를 먼저 볼게요. 아래 코드에서 runnable은 passed와 modified라는 두 키를 가진 RunnableParallel이에요.
%pip install -qU langchain langchain-openai
import os
from getpass import getpass
if "OPENAI_API_KEY" not in os.environ:
os.environ["OPENAI_API_KEY"] = getpass()
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
runnable = RunnableParallel(
passed=RunnablePassthrough(),
modified=lambda x: x["num"] + 1,
)
runnable.invoke({"num": 1})
passed 키는 RunnablePassthrough()로 호출했기 때문에 입력 {'num': 1}을 그대로 통과시켜요. 반면 modified 키는 람다로 x["num"] + 1을 계산하므로 값이 2가 됩니다. 이렇게 해서 같은 입력을 "그대로 두는 키"와 "변형하는 키"로 나눠 쓸 수 있어요.
검색(RAG) 예시
좀 더 실무에 가까운 예시를 볼게요. RunnablePassthrough를 RunnableParallel과 함께 체인에서 사용해 프롬프트 입력을 적절히 포맷하는 패턴이에요.
from langchain_community.vectorstores import FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
vectorstore = FAISS.from_texts(
["harrison worked at kensho"], embedding=OpenAIEmbeddings()
)
retriever = vectorstore.as_retriever()
template = """Answer the question based only on the following context:
{context}
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
model = ChatOpenAI()
retrieval_chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| model
| StrOutputParser()
)
retrieval_chain.invoke("where did harrison work?")
여기서 prompt가 기대하는 입력은 "context"와 "question" 키를 가진 map이에요. 그런데 사용자 입력은 질문 하나뿐이죠. 그래서 retriever로 컨텍스트를 얻고, 사용자 질문은 "question" 키 아래로 그대로 통과시키는 거예요. 바로 이 지점에서 RunnablePassthrough가 사용자 질문을 그대로 prompt와 모델로 전달해 주는 역할을 합니다.
다음 단계
이제 체인을 따라 흐르는 데이터를 포맷하기 위해 데이터를 통과시키는 방법을 배웠어요. 더 배우고 싶다면 이 섹션의 다른 러너블 how-to 가이드를 확인해 보세요.