一文吃透 LangChain 流式输出:同步、异步、LCEL 链式穿透全解析

前言

学习大模型开发的朋友都知道,平时调用模型大多都是等全部结果出来才一次性返回,用着简单省心。但想要做出打字机实时输出、看清 AI 一步步思考干活的效果,那就必须用上流式输出啦。本文用通俗易懂的方式,先讲清流式和非流式的区别,再手把手教大家 LangChain 里同步、异步流式写法,还搭配 LCEL 链式实战,轻松学会实时流式交互,轻松做出丝滑流畅的 AI 对话效果。

1.流式输出和非流式输出

在计算机网络通信中,流式输出(Streaming Output)和非流式(Buffered Output)的核心区别在于数据的传输方式和响应时机。

  • 非流式输出:这种输出模式下,系统会等待所有的数据处理完毕,并将结果打包成一个完整的"数据块"后一次返回。

  • 流式输出:在流式输出模式下,允许服务端在生成数据的同时,将已经完成的部分实时发送给客户端。

我们在以往的LangChain组件和功能讲解演示,连接聊天模型的程序的输出大部分都是非流式输出,这不是因为模型输出是非流式的,恰恰相反,大模型推理输出天生就是流式逐个Token生成的,但是接口会默认封装成非流式,这是因为我们在日常后端开发时,大部分场景下不需要流式输出,而且非流式是简单通用可兼容的,就是标准的HTTP接口,所有的网关、代理、防火墙等都完美适配。

虽然非流式在后端开发时占大部分,但是在LangChainAI应用开发时,流式输出不仅重要,而且是刚需。这是因为LangChain开发运行的步骤比原生大模型调用时间更长,用户想要了解"黑盒"里的工作流程,了解模型的工作流程,流式输出会输出所有的中间步骤,从思考->动作->工具调用->观察->最终答案,这就是全链路流式输出。流式输出让我们在LangChain开发中,对模型调用的过程更加可控可见,不仅仅这些,流式输出的方式在AI相关的开发还存在许多优点。

2.流式调用方式

今天我们主要讲解的就是LangChain中聊天模型调用的流式输出,虽然我们前面提到"流式更复杂",但是在LangChain中,很多接口和模式都会解决复杂相关的问题,LangChain 提供两类标准流式接口:

2.1同步流式

  • .stream( ) 就是LangChain封装的同步流式接口,它是阻塞的。在 for 循环处理当前这个 chunk 时,代码不会往下执行。适用: 简单的命令行工具、自动化脚本。.stream( ) ⽅法返回⼀个迭代器,该迭代器在⽣成输出时同步产⽣输出消息块
python 复制代码
chunks = []
for chunk in model.stream("讲⼀个30字的笑话"):
	chunks.append(chunk)
	print(chunk.content, end="|", flush=True)

2.2异步流式

  • .astream( ) 是基于asyncio的异步流式接口,在等待网络传输下一个chunk的空隙,CPU可以处理其他任务。适用于生产环境的后端API。
python 复制代码
import asyncio

async def chat_async():
    # 使用 astream 处理异步生成器
    async for chunk in model.astream("写一段代码"):
        print(chunk.content, end="", flush=True)

asyncio.run(chat_async())

3.LCEL链式调用

我们用 LCEL 构建一个简单的链,该链结合了聊天模型和解析器,试验证流式处理在各个组件之间是否有效。还有在使用的时候不要忘了,只要使用了LCEL 拼出来的链也拥有Runnable的接口。

python 复制代码
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_template("讲一个关于{topic}的故事")
# 组装链条
chain = prompt | model | StrOutputParser()

# 此时 text 直接就是字符串碎片了
for text in chain.stream({"topic": "小黑猫"}):
    print(text, end="", flush=True)

通过代码样例我们明白了当你在LangChain AI应用开发中链式使用 | 管道符连接各个组件时,流式能力会自动穿透,核心组件是:StrOutputParser ,加了解析器,每次的chunk会自动提取content。StrOutputParser 会把消息块 → 变成纯文字碎片输出。用一个简单的类比就是模型吐出的结果是 "带包装的小零食" ,通过StrOutputParser就是 "拆掉包装,只给你吃里面的零食" 。专业点说就是基于 LCEL 管道符拼接的组件链,默认实现 Runnable 接口,具备天然流式穿透能力。搭配 StrOutputParser 可自动从流式消息块中提取文本内容,将结构化的消息对象转换为纯文字碎片,简化了流式结果的业务处理逻辑。


综上讲解不难看出,流式输出是 LangChain AI 应用开发中不可或缺的核心能力。无论是同步 stream() 适合简单脚本开发,还是异步 astream() 适配生产级后端服务,都能满足不同业务场景的流式交互需求。而依托 LCEL 管道特性,组件链路天然继承 Runnable 流式能力,再配合 StrOutputParser 完成消息块到纯文本碎片的自动转换,让我们无需关心底层复杂封装,即可轻松实现简洁、高效、可实时可视化的大模型流式开发。掌握流式输出原理与用法,也是后续搭建对话应用、智能问答、Agent 全链路交互的重要基础。

相关推荐
松就是我902982 小时前
LLM 代理服务实现原理文档
后端
fliter2 小时前
Rust 的承诺:不是没有复杂性,而是把复杂性放到你能看见的地方
后端
fliter2 小时前
Rust 模块和文件不是一回事:一次讲清 `mod`、`use`、`pub use`
后端
绯雾sama2 小时前
易扣AI (Go + CloudWeGo) 企业级AI智能体项目教程 第2章:后端项目用户模块搭建
后端
fliter2 小时前
半小时读懂 Rust:从语法符号到所有权思维
后端
fliter2 小时前
深入 Rust enum 的内存世界
后端
_Evan_Yao2 小时前
从“全量发布”到“小步快跑”:灰度发布的简单实践与学习路径
java·后端·学习
石小石Orz3 小时前
给Claude增加状态栏显示:claude-hud保姆级教程
前端·人工智能·后端