Ветвление и комбинирование цепочек
Урок про сложные потоки: параллельные ветки, проброс данных и встраивание своих функций.
RunnableParallel — компонент, который запускает несколько веток на одном входе и собирает их результаты в словарь.
Когда линейной цепочки мало
Часто данные нужно не просто прогнать по прямой, а разветвить: например, на одном входе одновременно посчитать краткое резюме и список ключевых слов. Или пробросить исходный вопрос дальше вместе с найденным контекстом. Для этого в LCEL есть несколько служебных Runnable.
| Компонент | Назначение |
RunnableParallel | несколько веток параллельно, результат — словарь |
RunnablePassthrough | пробрасывает вход дальше без изменений |
RunnableLambda | встраивает обычную Python-функцию в цепочку |
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
# на одном вопросе: пробросить сам вопрос и подмешать контекст
setup = RunnableParallel(
question=RunnablePassthrough(),
context=retriever, # вернёт релевантные документы
)
# дальше: setup | prompt | model | parserИдею «параллельных веток на одном входе» можно показать на чистом Python:
def parallel(x, branches):
return {name: fn(x) for name, fn in branches.items()}
result = parallel("langchain", {
"length": len,
"upper": str.upper,
"first": lambda s: s[0],
})
print(result)Вывод:
{'length': 9, 'upper': 'LANGCHAIN', 'first': 'l'}Как работает под капотом
RunnableParallel получает один вход и раздаёт его всем веткам, а их результаты складывает в словарь по ключам. RunnablePassthrough — это тождественная функция: вернуть вход как есть (удобно, когда нужно протащить исходные данные сквозь шаг, который их меняет). RunnableLambda оборачивает вашу функцию так, чтобы она стала полноценным звеном с invoke(). Именно эта тройка делает возможной классическую RAG-сборку, где вопрос идёт в retriever и одновременно сохраняется для промпта.
Частые ошибки
- Терять исходный ввод. Если шаг преобразует данные, а дальше нужен оригинал — пробрасывайте его через
RunnablePassthrough. - Путать словарь-результат. После
RunnableParallelследующий шаг получает словарь; ключи должны совпасть с плейсхолдерами промпта. - Прятать тяжёлую логику в
RunnableLambda. Лямбды удобны, но сложную обработку лучше вынести в именованную функцию.
Итог
RunnableParallelзапускает ветки параллельно и собирает словарь результатов.RunnablePassthroughпробрасывает вход без изменений.RunnableLambdaвстраивает обычную функцию в цепочку.- Эта тройка — основа RAG-сборки «вопрос + контекст → промпт».