前言
学习大模型开发的朋友都知道,平时调用模型大多都是等全部结果出来才一次性返回,用着简单省心。但想要做出打字机实时输出、看清 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 全链路交互的重要基础。