Day 12:LangChain 流式输出——一行 for 循环的事
回顾 Day 5 的痛
原生 SDK 的流式输出要:判 delta 是否为 None、判 delta.content 是否为 None、处理只在第一个 chunk 出现的 role、自己拼 full_reply……
LangChain 把这些脏活都封装了。
完整代码
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
load_dotenv()
llm = ChatOpenAI(
model=os.getenv("YUMC_MODEL_NAME"),
api_key=os.getenv("YUMC_MODEL_API_KEY"),
base_url=os.getenv("YUMC_MODEL_BASE_URL"),
streaming=True, # 声明用流式模式
)
print("----流式输出测试")
for chunk in llm.stream("请给我讲一个关于程序员的笑话,要简短一点。"):
print(chunk.content, end="", flush=True)
print("\n----结束----")
没了。真的没了。
逐段拆解
① llm.stream(...)
LLM 对象自带 .stream() 方法,直接传字符串(或消息列表)就行。它是一个生成器,for 循环每轮拿到一个 chunk(一个 AIMessageChunk 对象)。
② chunk.content
对比原生 SDK 的 chunk.choices[0].delta.content——LangChain 已经帮你拆好包了,而且 content 为空时它就是空字符串 "",不用判 None(打印空字符串无副作用)。
③ streaming=True
在构造参数里声明支持流式。注意:对 OpenAI 系模型来说,调用 .stream() 时即使不写这个参数通常也能正常流式;但显式写上是个好习惯,部分集成场景依赖它。
想要完整回复?也是三行
full_reply = ""
for chunk in llm.stream("讲个笑话"):
full_reply += chunk.content
print(chunk.content, end="", flush=True)
# full_reply 现在就是完整文本,可以存历史、写库
LangChain 消息 vs 原生字典
顺便熟悉一下新面孔:原生 SDK 里消息是字典 {"role": "user", "content": "..."},LangChain 里是对象:HumanMessage、AIMessage、SystemMessage(明天正式用)。对象的好处是有类型提示、有方法,IDE 能自动补全。
今日踩坑点
- 对
chain用了.stream()传错结构:如果流式的是链,输入格式要和.invoke()一致(字典),不是裸字符串。 flush=True还是不能省:这是 Python 的 print 缓冲问题,跟用不用框架无关。- 以为 chunk 是字符串:它是消息块对象,要取
.content;直接 print 会看到对象表示。
今日小练习
- 必做:把 Day 10 的
chain = prompt | llm改成流式调用chain.stream({"user_input": "..."}),验证链也能流式。 - 进阶:流式输出时同步统计已输出的字符数,结束时打印"共输出 N 字符"。
明日预告
Day 13:回到 Day 6 的老话题——记忆。这次用 LangChain 的 Message 对象实现,顺便封装一个像样的 chat() 函数。
附录:完整练习代码
langchainTestStreaming.py
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
load_dotenv()
llm = ChatOpenAI(
model = os.getenv("YUMC_MODEL_NAME"),
api_key = os.getenv("YUMC_MODEL_API_KEY"),
base_url = os.getenv("YUMC_MODEL_BASE_URL"),
streaming = True
)
print("----流式输出测试")
for chunk in llm.stream("请给我讲一个关于程序员的笑话,要简短一点。"):
print(chunk.content,end= "",flush=True)
print("\n----结束----")
478



被折叠的 条评论
为什么被折叠?



