langchain核心组件 Model I/O(4)-chain

4 阅读2分钟

1.1 Runnable与LCEL

1)Runnable

Runnable 是 LangChain 中可以调用、批处理、流式传输、转换和组合的工作单元。

Runnable 接口是使用 LangChain 组件的基础,它在许多组件中实现,例如语言模型、输出解析器、检索器、编译的 LangGraph 图等。

Runnable 接口强制要求所有 LCEL 组件实现一组标准方法:

invoke / ainvoke

将单个输入转换为输出

batch / abatch

批量将多个输入转换为输出

stream / astream

从单个输入生成流式输出

为什么需要统一调用方式?

假设没有统一调用方式,每个组件调用方式不同,组合时需要手动适配:

 提示词渲染用 .format()

 模型调用用 .generate()

 解析器解析用 .parse()

 工具调用用 .run()

代码会变成:

prompt_text= prompt.format(topic="猫")  # 方法1

model_out= model.generate(prompt_text)  # 方法2

result = parser.parse(model_out)# 方法3

Runnable 统一调用方式:

#分步调用
prompt_text=prompt.invoke({"topic": "猫"})  # 方法1
model_out= model.invoke(prompt_text) # 方法2
result=parser.invoke(model_out)# 方法3
#LCEL管道式
chain = prompt |model | parser  #用管道符组合
result = chain.invoke({"topic": "猫"})  # 所有组件统一用invoke

无论组件的功能多复杂(模型/提示词/工具),调用方式完全相同。并且可以通过管道符 | 组合,自动处理类型匹配和中间结果传递。

2)LCEL

LangChain 表达式语言(LCEL,LangChain Expression Language)是一种从现有的Runnable 构建新的 Runnable 的声明式方法,用于声明、组合和执行各种组件(模型、提示、工具、函数等)。

我们称使用 LCEL 创建的 Runnable 为“链”,“链”本身就是 Runnable。

LCEL 两个主要的组合原语是 RunnableSequence 和 RunnableParallel。许多其他组合原语可以被认为是这两个原语的变体。

1.1 RunnableSequence 可运行序列

RunnableSequence 按顺序“链接”多个可运行对象,其中一个对象的输出作为下一个对象的输入。

LCEL重载了 | 运算符,以便从两个 Runnables 创建 RunnableSequence。

chain = runnable1| runnable2
#等同于
chain =RunnableSequence([runnable1, runnable2])

举例:提示模板➡️模型➡️输出解析器

import os
from langchain.chat_models import init_chat_model 
from langchain_core.prompts import PromptTemplate 
from langchain_core.output_parsers import StrOutputParser 

prompt_template= PromptTemplate( 
  template="讲一个关于{topic}的笑话", 
  input_variables=["topic"],
) 
llm = init_chat_model( 
  model="openai/gpt-oss-20b:free", 
  model_provider="openai", 
  base_url="https://openrouter.ai/api/v1", 
  api_key=os.getenv("OPENROUTER_API_KEY"),
) 
parser = StrOutputParser() 
chain = prompt_template | llm | parser resp = chain.invoke({"topic": "人工智能"})
print(resp)

1.2 RunnableParallel 可运行并行

RunnableParallel 同时运行多个可运行对象,并为每个对象提供相同的输入。

对于同步执行,RunnableParallel 使用 ThreadPoolExecutor 来同时运行可运行对象。

对于异步执行,RunnableParallel 使用 asyncio.gather 来同时运行可运行对象。

在 LCEL 表达式中,字典会自动转换为 RunnableParallel。

举例:

import os
from langchain.chat_models import init_chat_model
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables import RunnableParallel
from langchain_core.output_parsers import StrOutputParser 
llm = init_chat_model( 
  model="openai/gpt-oss-20b:free", 
  model_provider="openai", 
  base_url="https://openrouter.ai/api/v1", 
  api_key=os.getenv("OPENROUTER_API_KEY"),
) 
joke_chain
= ( PromptTemplate.from_template("讲一个关于{topic}的笑话") | llm | StrOutputParser())
poem_chain
= ( PromptTemplate.from_template("写一首关于{topic}的诗歌") | llm | StrOutputParser()) 
map_chain = RunnableParallel(joke=joke_chain, poem=poem_chain) 
resp = map_chain.invoke({"topic": "人工智能"})
print(resp)