纲要
- 核心标准事件概览
invoke: 同步调用stream: 流式输出batch: 批量处理astream_events: 异步事件流with_structured_output: 结构化输出
- 环境准备与模型初始化
- 五种调用方式的完整实现
- 执行结果与行为对比
- 扩展实践路径
核心标准事件概览
LangChain 为大模型组件抽象了一组统一的调用接口,覆盖了从基础的同步请求到复杂的事件驱动流式处理等多种交互场景。下表总结了五种最常用的事件驱动方法,并对比其适用场景与返回类型。
| 事件方法 | 调用方式 | 适用场景 | 返回类型 |
|---|---|---|---|
invoke | 同步阻塞,返回完整结果 | 后台任务、批处理脚本 | AIMessage |
stream | 同步迭代,逐 token 产出 | 聊天机器人前端、实时反馈 | Iterator[chunk] |
batch | 并发发送多个请求 | 批量评估、数据增强 | list[AIMessage] |
astream_events | 异步流式,按事件类型精细控制 | 需要监听开始/结束/流式进度 | AsyncIterator[event] |
with_structured_output | 基于 Pydantic 模型的结构化输出 | 下游系统对接、JSON 解析 | Pydantic 实例 |
决策路径可以参考以下流程:
环境准备与模型初始化
本实践采用 OpenAI 的 GPT-3.5-turbo 作为示例模型,该模型成本较低,适合功能验证与调试。请先安装依赖并配置环境变量。
pip install langchain-openai pydantic
确保环境变量 OPENAI_API_KEY 已设置为有效的密钥。若使用本地部署的模型如 Ollama,可替换为 ChatOllama 并调整 base_url 参数,其余事件接口保持一致。
五种调用方式的完整实现
以下代码在一个完整的脚本中连续演示了 invoke、stream、batch、astream_events 和 with_structured_output 五种调用方式,涵盖了同步、异步、流式、批量和结构化输出等主流场景。
import os
import asyncio
from pydantic import BaseModel, Field
from langchain_openai import ChatOpenAI
# ---------- 初始化模型 ----------
llm = ChatOpenAI(
model="gpt-3.5-turbo",
temperature=0.7,
api_key=os.getenv("OPENAI_API_KEY"),
)
# ---------- 1. invoke:同步调用 ----------
print("=== 1. invoke 同步调用 ===")
response = llm.invoke("用一句话介绍 Python 语言")
print("完整回答:", response.content)
print("Token 用量:", response.usage_metadata)
print()
# ---------- 2. stream:流式输出 ----------
print("=== 2. stream 流式输出 ===")
print("模型输出: ", end="", flush=True)
for chunk in llm.stream("写一首关于编程的七言绝句"):
print(chunk.content, end="", flush=True)
print("\n")
# ---------- 3. batch:批量处理 ----------
print("=== 3. batch 批量处理 ===")
questions = [
"什么是上下文窗口?",
"Token 是什么?",
"工具调用有什么作用?"
]
results = llm.batch(questions)
for q, r in zip(questions, results):
print(f"Q: {q}\nA: {r.content}\n")
# ---------- 4. astream_events:异步事件流 ----------
async def demo_astream_events():
print("=== 4. astream_events 异步事件流 ===")
async for event in llm.astream_events("解释什么是深度学习", version="v2"):
kind = event["event"]
if kind == "on_chat_model_start":
print("[模型开始响应]")
elif kind == "on_chat_model_stream":
data = event["data"]["chunk"]
if data.content:
print(data.content, end="", flush=True)
elif kind == "on_chat_model_end":
print("\n[模型响应结束]")
output = event["data"]["output"]
if output.usage_metadata:
print("Token 用量:", output.usage_metadata)
asyncio.run(demo_astream_events())
print()
# ---------- 5. with_structured_output:结构化输出 ----------
print("=== 5. with_structured_output 结构化输出 ===")
class ProgrammingJoke(BaseModel):
"""程序员笑话"""
setup: str = Field(description="笑话的铺垫")
punchline: str = Field(description="笑话的包袱/笑点")
rating: int | None = Field(default=None, description="好笑程度 1-10")
structured_llm = llm.with_structured_output(ProgrammingJoke)
joke = structured_llm.invoke("给我讲一个编程相关的笑话")
print(f"铺垫: {joke.setup}")
print(f"笑点: {joke.punchline}")
print(f"评分: {joke.rating}")
将上述代码保存为 practice.py 并执行,即可在终端中依次观察五种事件的行为差异。
执行结果与行为对比
运行代码后,各方法的输出特征如下:
invoke:等待完整回复后一次性打印,适合无需中间反馈的离线处理。stream:逐字或逐 token 输出,模拟打字机效果,显著提升用户体验。batch:并发发送多个请求,按输入顺序返回对应结果,提升吞吐量。astream_events:在流式输出的前后触发明确定义的开始与结束事件,并上报 Token 用量等元数据。with_structured_output:直接返回Pydantic对象,无需手动解析JSON,避免格式错误,便于下游系统集成。
扩展实践路径
基于当前实现,可进一步探索以下方向:
- 模型替换:将
ChatOpenAI切换为ChatAnthropic(安装langchain-anthropic)或ChatOllama,验证事件接口的兼容性。 - 进度增强:为
batch集成tqdm进度条,优化大规模批处理的交互体验。 - 事件深度利用:在
astream_events中捕获on_retriever_start、on_tool_start等事件,实现分布式链路追踪或详细日志记录。 - 工具调用集成:结合
bind_tools,在stream模式下处理工具请求,构建具有自主决策能力的Agent交互流程。
API 速览
本实践涉及的 LangChain 核心 API 均继承自 BaseChatModel,其方法签名如下:
-
invoke(input: str | list[dict] | BaseMessage, config: dict | None = None) -> AIMessage
同步执行调用,返回完整的AIMessage对象,包含content和usage_metadata。 -
stream(input: str | list[dict] | BaseMessage, config: dict | None = None) -> Iterator[AIMessageChunk]
同步迭代返回,每次迭代产出一个AIMessageChunk,可用于实时展示部分生成内容。 -
batch(inputs: list[str | list[dict] | BaseMessage], config: dict | None = None) -> list[AIMessage]
并发处理多条输入,返回结果列表,顺序与输入一一对应。 -
astream_events(input: str | list[dict] | BaseMessage, version: str = "v2", config: dict | None = None) -> AsyncIterator[dict]
异步事件流,按事件类型(如on_chat_model_start、on_chat_model_stream、on_chat_model_end)触发回调,适用于复杂监听场景。 -
with_structured_output(output_schema: Type[BaseModel]) -> Runnable
返回绑定指定Pydantic模型的Runnable对象,该对象的invoke方法直接返回模型实例,无需手动解析。
完整 Demo 示例
以下提供一份可直接运行的完整脚本,涵盖所有五种事件的串行演示。运行方式与上文一致。
import os
import asyncio
from pydantic import BaseModel, Field
from langchain_openai import ChatOpenAI
# 初始化模型(确保 OPENAI_API_KEY 已设置)
llm = ChatOpenAI(
model="gpt-3.5-turbo",
temperature=0.7,
api_key=os.getenv("OPENAI_API_KEY"),
)
def demo_invoke():
print("=== invoke 同步调用 ===")
response = llm.invoke("用一句话介绍 Python 语言")
print("完整回答:", response.content)
print("Token 用量:", response.usage_metadata)
print()
def demo_stream():
print("=== stream 流式输出 ===")
print("模型输出: ", end="", flush=True)
for chunk in llm.stream("写一首关于编程的七言绝句"):
print(chunk.content, end="", flush=True)
print("\n")
def demo_batch():
print("=== batch 批量处理 ===")
questions = ["什么是上下文窗口?", "Token 是什么?", "工具调用有什么作用?"]
results = llm.batch(questions)
for q, r in zip(questions, results):
print(f"Q: {q}\nA: {r.content}\n")
async def demo_astream_events():
print("=== astream_events 异步事件流 ===")
async for event in llm.astream_events("解释什么是深度学习", version="v2"):
kind = event["event"]
if kind == "on_chat_model_start":
print("[模型开始响应]")
elif kind == "on_chat_model_stream":
data = event["data"]["chunk"]
if data.content:
print(data.content, end="", flush=True)
elif kind == "on_chat_model_end":
print("\n[模型响应结束]")
output = event["data"]["output"]
if output.usage_metadata:
print("Token 用量:", output.usage_metadata)
print()
def demo_structured_output():
print("=== with_structured_output 结构化输出 ===")
class ProgrammingJoke(BaseModel):
setup: str = Field(description="笑话的铺垫")
punchline: str = Field(description="笑话的包袱/笑点")
rating: int | None = Field(default=None, description="好笑程度 1-10")
structured_llm = llm.with_structured_output(ProgrammingJoke)
joke = structured_llm.invoke("给我讲一个编程相关的笑话")
print(f"铺垫: {joke.setup}")
print(f"笑点: {joke.punchline}")
print(f"评分: {joke.rating}")
if __name__ == "__main__":
demo_invoke()
demo_stream()
demo_batch()
asyncio.run(demo_astream_events())
demo_structured_output()
运行说明
- 确保
OPENAI_API_KEY环境变量已配置。 - 安装依赖:
pip install langchain-openai pydantic - 执行脚本:
python practice.py - 如使用本地
Ollama,请替换模型初始化部分为ChatOllama(model="llama2")。
技术点总结
- 演示了
LangChain的五种标准事件方法,覆盖同步、异步、流式、批量和结构化输出。 - 展示了
astream_events的事件监听与元数据提取能力。 - 体现了
Pydantic模型在结构化输出中的类型安全保障。
参考文档
官方文档
参考链接
总结
本文系统梳理了 LangChain 中五种核心标准事件驱动方法——invoke、stream、batch、astream_events 和 with_structured_output——的技术特性、适用场景及实现差异。通过一个完整的可运行示例,展示了如何在统一接口下灵活切换调用模式,从而适配不同交互需求。
文中强调了 astream_events 在异步精细化控制中的优势,以及 with_structured_output 与 Pydantic 配合在数据验证与下游集成中的工程价值。整体内容涵盖模型初始化、批量并发、流式响应、事件监听和类型安全的输出解析,构成一个面向 AI Agent 开发的基础技术闭环。
1050



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



