签到成功

知道了

CNDBA社区CNDBA社区

大模型(LLM)中 Runnable 概念及使用方式

2025-09-11 21:58 310 0 转载 大模型
作者: dave

在大语言模型(LLM)应用开发框架(特别是 LangChain)中,Runnable 是一个核心抽象概念,它统一了所有可以被“调用”或“执行”的组件的接口,使得链式调用、组合、并行、日志、流式传输等操作成为可能。


🧩 一、Runnable 是什么?

Runnable 是 LangChain 中的一个协议(Protocol)或接口(Interface),它定义了对象必须实现的方法,最核心的是:

  • invoke(input, config):同步调用
  • ainvoke(input, config):异步调用
  • stream(input, config):流式输出
  • astream(input, config):异步流式输出
  • batch(inputs, config):批量调用
  • abatch(inputs, config):异步批量调用

✅ 任何实现了这些方法的对象,都可以被称为 Runnable,并可以被组合、嵌套、装饰。


🎯 二、Runnable 的作用

  1. 统一接口
    无论是 PromptTemplate、LLM、Chain、Agent、Tool 还是自定义函数,只要包装成 Runnable,就可以用相同方式调用。http://www.cndba.cn/dave/article/131716http://www.cndba.cn/dave/article/131716http://www.cndba.cn/dave/article/131716http://www.cndba.cn/dave/article/131716

  2. 链式组合(Chaining)
    使用 | 操作符将多个 Runnable 串联起来,构建复杂流程:http://www.cndba.cn/dave/article/131716

    chain = prompt | llm | output_parser
    
  3. 并行执行(Parallel)
    使用 RunnableParallel 或字典方式并行执行多个分支:

    from langchain_core.runnables import RunnableParallel
    
    chain = RunnableParallel({
        "summary": prompt1 | llm,
        "translation": prompt2 | llm
    })
    
  4. 流式支持(Streaming)
    支持逐 Token 输出,适用于聊天机器人、实时响应等场景。http://www.cndba.cn/dave/article/131716

  5. 配置与上下文传递(config)
    支持传入 config 参数,用于传递回调函数(callbacks)、元数据(metadata)、运行 ID(run_id)等,便于日志、监控、追踪。http://www.cndba.cn/dave/article/131716

  6. 批处理(Batch)
    支持一次处理多个输入,提高吞吐量。

  7. 中间件与装饰(RunnableLambda, RunnablePassthrough 等)
    可插入自定义逻辑、数据透传、条件分支等。http://www.cndba.cn/dave/article/131716


🛠️ 三、如何使用 Runnable

1. 基础使用:调用 LLM

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4")

# invoke 同步调用
result = llm.invoke("你好,介绍一下你自己")
print(result.content)

# ainvoke 异步调用
import asyncio
async def main():
    result = await llm.ainvoke("你好")
    print(result.content)

asyncio.run(main())

2. 链式调用(Chaining)

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

prompt = ChatPromptTemplate.from_template("请写一首关于{topic}的诗")
llm = ChatOpenAI()
output_parser = StrOutputParser()

# 组合成链
chain = prompt | llm | output_parser

# 调用
poem = chain.invoke({"topic": "春天"})
print(poem)

3. 并行调用(Parallel)

from langchain_core.runnables import RunnableParallel

chain = RunnableParallel({
    "poem": prompt | llm | output_parser,
    "fact": lambda x: f"关于{x['topic']}的冷知识:它很美"
})

result = chain.invoke({"topic": "海洋"})
print(result)
# 输出: {'poem': '...', 'fact': '关于海洋的冷知识:它很美'}

4. 自定义 Runnable(使用 RunnableLambda)

from langchain_core.runnables import RunnableLambda

def reverse_text(input_str):
    return input_str[::-1]

reverse_runnable = RunnableLambda(reverse_text)

result = reverse_runnable.invoke("hello")
print(result)  # 输出: "olleh"

5. 流式输出(Streaming)

for chunk in llm.stream("讲个笑话"):
    print(chunk.content, end="", flush=True)

6. 批量处理(Batch)

inputs = ["讲个笑话", "写首诗", "推荐电影"]
results = llm.batch(inputs)

for res in results:
    print(res.content)

7. 使用 RunnablePassthrough 透传数据

from langchain_core.runnables import RunnablePassthrough

chain = (
    {"topic": RunnablePassthrough()}
    | prompt
    | llm
    | output_parser
)

result = chain.invoke("秋天")
print(result)

📦 四、哪些对象是 Runnable?

LangChain 中几乎所有组件都是 Runnable:http://www.cndba.cn/dave/article/131716

类型 示例
LLM / ChatModel ChatOpenAI, ChatAnthropic
PromptTemplate ChatPromptTemplate
OutputParser StrOutputParser
Chains LLMChain, SequentialChain
Tools / Agents Tool, AgentExecutor
自定义函数 RunnableLambda
数据透传 RunnablePassthrough
并行/分支 RunnableParallel

📈 五、Runnable 的优势总结

特性 说明
统一接口 所有组件调用方式一致
可组合 使用 ` ` 轻松构建复杂链
可并行 多任务同时执行
可流式 支持逐 Token 输出
可批处理 高效处理多个输入
可配置 支持 callbacks、metadata 等
可扩展 易于包装自定义逻辑

✅ 六、最佳实践建议

  1. 优先使用 | 构建链,而不是旧式 LLMChain
  2. 使用 RunnableLambda 包装自定义函数
  3. 利用 RunnableParallel 提高并行效率
  4. 流式输出提升用户体验(如 Web 聊天)
  5. 配置 config 实现日志、追踪、监控

📚 参考文档


总结:Runnable 是 LangChain 2.0+ 的核心抽象,它让 LLM 应用开发像搭积木一样灵活、可组合、可扩展。掌握 Runnable,是构建现代 LLM 应用的关键一步。

http://www.cndba.cn/dave/article/131716

用户评论
* 以下用户言论只代表其个人观点,不代表CNDBA社区的观点或立场
dave

dave

关注

人的一生应该是这样度过的:当他回首往事的时候,他不会因为虚度年华而悔恨,也不会因为碌碌无为而羞耻;这样,在临死的时候,他就能够说:“我的整个生命和全部精力,都已经献给世界上最壮丽的事业....."

  • 2297
    原创
  • 3
    翻译
  • 606
    转载
  • 198
    评论
  • 访问:9117881次
  • 积分:4504
  • 等级:核心会员
  • 排名:第1名
精华文章
    最新问题
    查看更多+
    热门文章
      热门用户
      推荐用户
        Copyright © 2016 All Rights Reserved. Powered by CNDBA · 皖ICP备2022006297号-1·

        QQ交流群

        注册联系QQ