【自然语言处理与大模型】LangChainV1.0入门指南:核心组件Streaming

本文介绍LangChain支持的4中流式输出方式。流式输出让应用能够在 LLM 生成完整响应之前,就实时地将结果逐步返回给用户。这对于提升用户体验至关重要。LangChain 支持的流式模式:

模式 参数值 输出内容 使用场景
Agent Progress stream_mode="updates" 每个 agent step 后的状态更新 监控执行流程、调试
LLM Tokens stream_mode="messages" LLM 生成的每个 token(含元数据) 实时显示文本、UI渲染
Custom Updates stream_mode="custom" 用户自定义的任意数据 显示进度、工具执行状态
混合模式 stream_mode=["updates", "custom"] 元组 (mode, chunk) 需要多种流式数据

要想激活流式输出,请将invoke改成stream 或 astream,并指定stream_mode参数。

一、Agent Progress 模式

将stream方法里面传入stream_mode="updates",来开启Agent Progress模式。

python 复制代码
from langchain.agents import create_agent
from dotenv import load_dotenv

# 加载 .env 文件中的环境变量(如 API Key),override=True 确保覆盖已有的环境变量
load_dotenv(override=True)


# 定义一个普通的 Python 函数作为工具
def get_weather(city: str) -> str:
    """获取所给城市的天气"""

    return f"{city}现在是晴天"


# 创建 Agent 实例
agent = create_agent(
    model="deepseek-chat",  # 指定使用的模型,这里是 deepseek-chat
    tools=[get_weather]    # 将函数作为工具列表传入。
                            # LangChain 很智能,即使没有使用 @tool 装饰器,
                            # 它也能自动识别该函数的类型注解和文档字符串,将其封装为 Agent 可用的工具。
)


# --- 演示 1:打印原始的流式输出块 ---
print("--- 原始流式数据 ---")
for chunk in agent.stream(
    {"messages": [{"role": "user", "content": "长沙今天天气如何"}]}, # 输入用户消息
    stream_mode="updates"  # 指定流模式为 "updates",意味着只返回有更新的状态块
):
    print(chunk)  # 打印原始 chunk。你会看到每一行都是一个字典,包含 Agent 的中间步骤(如思考、调用工具)或最终回复。


# --- 演示 2:解析并美化输出 ---
print("\n--- 解析后的内容 ---")
for chunk in agent.stream(
    {"messages": [{"role": "user", "content": "长沙今天天气如何"}]},
    stream_mode="updates"
):
    # 遍历 chunk 字典中的键值对(通常是 Agent 的名称或步骤名称)
    for k, v in chunk.items():
        print(f'当前{k}输出:')
        
        # v['messages'] 是该步骤产生的消息列表
        # 我们取列表中最后一条消息 (-1) 的内容,这在 Agent 思考或回复时通常是最关键的部分
        print(f'{v["messages"][-1].content}')

二、LLM tokens模式

将stream方法里面传入stream_mode="messages",来开启LLM tokens模式,实现打字机效果。

python 复制代码
from langchain.agents import create_agent


# 定义一个普通的 Python 函数作为工具
def get_weather(city: str) -> str:
    """获取所给城市的天气"""

    # 这里模拟了返回结果
    return f"{city}现在是晴天"


# 创建 Agent 实例
agent = create_agent(
    model="deepseek-chat",
    tools=[get_weather],    # 当一个不使用 tool 装饰器的函数传入的时候也可以被当做工具
)

# 使用流式输出,stream_mode="messages" 会逐步生成消息对象
for token, metadata in agent.stream(
    {"messages": [{"role": "user", "content": "长沙今天天气如何"}]},
    stream_mode="messages",
):
    # metadata['langgraph_node'] 显示当前是由哪个节点产生的输出(如 agent 或 tools)
    print(f"node: {metadata['langgraph_node']}")
    
    # token.content_blocks 包含当前消息的具体内容块
    print(f"content: {token.content_blocks}")
    print("\n")

三、Custom Updates 模式

自定义模式的最佳使用场景就是将工具的输出内容也变成流式输出。

  • 在stream或astream方法里面传入 sream_mode="custom"
  • 使用 get_stream_writer() 从工具内部发送自定义更新
python 复制代码
from langgraph.config import get_stream_writer
python 复制代码
def get_weather(city: str) -> str:
    """ 获取指定城市的天气信息 """
    writer = get_stream_writer()  # 流式写入器

    # 自定义进度更新
    writer("正在访问网络"*20)  # 无论我加多长,这里面的内容并不会一个个蹦出来(无流式效果)
    writer(f"正在搜索{city}天气"*20)  # get_stream_writer是实现不同的writer之间的间隔停顿

    result = f"{city}现在是晴天"
    writer(result) # 但是可以通过这种方式来输出,或者使用混合模式
    return result   # return的结果是不会被输出的



agent_with_custom = create_agent(
    model='deepseek-chat',
    tools=[get_weather]
)


for chunk in agent_with_custom.stream(
    input={"messages": [{"role": "user", "content": "长沙今天天气如何"}]},
    stream_mode="custom"
):
    print(chunk)

【注】 如果在工具中添加 get_stream_writer(),该工具将无法在 LangGraph 执行上下文之外被调用。

python 复制代码
get_weather({"city": "长沙"})  # 报错

四、混合模式

可以同时使用多种流式模式,接收 (mode, chunk) 元组,传入一个列表stearm_mode=[]

python 复制代码
# --- 循环 1:直接打印原始输出,用于观察数据结构 ---

for chunk in agent_with_custom.stream(
    input={"messages": [{"role": "user", "content": "长沙今天天气如何"}]},
    # stream_mode 是一个列表,表示我们希望同时获取两种流数据:
    # "updates": 标准的节点更新数据(包含 Agent 的思考和回复)
    # "custom": 开发者自定义的输出数据(通常用于传递特定的 Token 计数、调试信息等)
    stream_mode=["updates", "custom"]
):
    # 打印原始 chunk 观察
    # 输出格式是一个元组,第一个元素是模式名称(如 "updates" 或 "custom")
    # 第二个元素是该模式下的具体数据内容
    print(chunk)


print("\n--- 解析并分类输出 ---\n")

# --- 循环 2:根据模式类型处理数据 ---

for chunk in agent_with_custom.stream(
    input={"messages": [{"role": "user", "content": "长沙今天天气如何"}]},
    stream_mode=["updates", "custom"]
):
    # chunk 是一个元组:(mode_name, mode_data)
    # 判断当前 chunk 属于哪种模式
    if chunk[0] == "custom":
        # 如果是 "custom" 模式,直接打印自定义数据(chunk[1])
        print(chunk[1])
    else:
        # 如果是 "updates" 模式(chunk[0] == "updates"),处理标准节点更新数据
        # chunk[1] 是一个字典,键是节点名称,值是节点数据
        for k, v in chunk[1].items():
            # 提取该节点最后一条消息的内容并打印,通常包含 Agent 的思考或最终回复
            print(v["messages"][-1].content)

如何让 Agent 同时以多种模式(这里是 updates 和 custom)进行流式输出。这在需要同时监控 Agent 的标准思考过程(updates)和获取自定义中间数据(custom)时非常有用。

相关推荐
C_心欲无痕2 小时前
前端如何实现 [记住密码] 功能
前端
qq_316837758 小时前
uni.chooseMedia 读取base64 或 二进制
开发语言·前端·javascript
Zoey的笔记本8 小时前
2026告别僵化工作流:支持自定义字段的看板工具选型与部署指南
大数据·前端·数据库
小二·8 小时前
Python Web 开发进阶实战:混沌工程初探 —— 主动注入故障,构建高韧性系统
开发语言·前端·python
gis开发8 小时前
【无标题】
java·前端·javascript
小二·8 小时前
Python Web 开发进阶实战:低代码平台集成 —— 可视化表单构建器 + 工作流引擎实战
前端·python·低代码
慧一居士9 小时前
Vite 中配置环境变量方法及完整示例
前端·vue.js
梦因you而美9 小时前
XPath 元素定位全方位技术文档
javascript·xpath·xpath定位
天意pt9 小时前
Idempotency 幂等性 - 点赞和投票功能
前端·javascript·express
weixin_4277716110 小时前
cursor 智能commit
前端