2.3 Runnable 核心方法详解(invoke/ainvoke、batch/abatch、stream/astream 等)
2.3.1 引言
Runnable 协议作为 LangChain 1.2.7 版本的核心执行层抽象,其核心方法提供了同步/异步、单条/批量、完整/流式的全场景执行能力。这些方法遵循统一的接口设计规范,确保所有实现 Runnable 协议的组件(模型、链、工具等)具备一致的调用体验。本节将从基础定义、参数详解、实战案例、进阶技巧到最佳实践,系统拆解 invoke/ainvoke、batch/abatch、stream/astream 六大核心方法,同时覆盖方法间的差异与适用场景。
2.3.2 环境准备与依赖说明
<2.3.2.1> 版本约束(强制要求)
Bash
# 核心依赖(严格指定版本)
pip install langchain==1.2.7 langchain-core==1.2.7
# 辅助依赖(匹配1.2.7版本兼容性)
pip install langchain-openai==1.1.7 langchain-community==0.4.1 langchain-classic==1.0.1
# 其他依赖(最新稳定版)
pip install openai==1.13.3 python-dotenv==1.0.1
<2.3.2.2> 基础导入模板
python
import os
from dotenv import load_dotenv
from langchain_core.runnables import RunnablePassthrough, RunnableLambda
from langchain_openai import ChatOpenAI
from langchain_core.outputs import ChatResult
# 加载环境变量(OpenAI API密钥)
load_dotenv()
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")
# 初始化示例组件(所有案例基于此组件演示)
llm = ChatOpenAI(
model="gpt-3.5-turbo",
temperature=0.7,
max_tokens=512
)
2.3.3 同步核心方法:invoke / batch
<2.3.3.1> invoke:单条输入同步执行
方法定义(LangChain 1.2.7 源码规范)
python
def invoke(
self,
input: Input,
config: RunnableConfig | None = None,
**kwargs: Any
) -> Output:
"""
同步执行单条输入,返回完整结果
:param input: 输入数据(支持 dict、str、Message 等,取决于组件类型)
:param config: 执行配置(RunnableConfig 类型,包含回调、标签、元数据等)
:param kwargs: 额外参数(模型参数、执行参数,会覆盖组件初始化配置)
:return: 组件输出结果(类型由组件定义,如 ChatResult、str 等)
"""
关键参数详解
| 参数 | 类型 | 说明 |
|---|---|---|
| input | Input(泛型) | 必须参数,输入格式需与组件兼容(如 ChatOpenAI 要求输入为 list[BaseMessage] 或 str) |
| config | Optional[RunnableConfig] | 可选配置,支持 tags(标签)、metadata(元数据)、callbacks(回调函数)等 |
| **kwargs | Any | 动态参数,支持模型参数(如 stop、temperature)和执行参数(如 timeout) |
实战案例(独立可运行)
python
# 案例1:基础字符串输入
result1 = llm.invoke("请解释 LangChain Runnable 的核心作用")
print("案例1输出(字符串输入):", result1.content)
# 案例2:Message 类型输入(更精准的对话控制)
from langchain_core.messages import HumanMessage, SystemMessage
messages = [
SystemMessage(content="你是技术文档助手,回答简洁专业"),
HumanMessage(content="Runnable.invoke 与直接调用模型的区别是什么?")
]
result2 = llm.invoke(messages)
print("案例2输出(Message输入):", result2.content)
# 案例3:通过 kwargs 覆盖组件初始化参数
result3 = llm.invoke(
"生成3条Python性能优化建议",
temperature=0.2, # 覆盖初始化的 0.7
max_tokens=300 # 覆盖初始化的 512
)
print("案例3输出(参数覆盖):", result3.content)
# 案例4:带 config 配置(标签与回调)
from langchain_core.callbacks import ConsoleCallbackHandler
config = {
"tags": ["runnable-demo", "invoke-method"],
"metadata": {"user_id": "test-001"},
"callbacks": [ConsoleCallbackHandler()] # 控制台打印执行日志
}
result4 = llm.invoke("LangChain 1.2.7 中 Runnable 的优势", config=config)
print("案例4输出(带配置):", result4.content)
注意事项
-
input格式需严格匹配组件要求,否则抛出ValidationError -
**kwargs中的参数优先级:调用时传入 > 组件初始化 > 全局默认 -
config中的callbacks支持自定义回调(如日志记录、性能监控),需实现BaseCallbackHandler接口 -
同步方法会阻塞当前线程,适用于单条、低延迟的执行场景
<2.3.3.2> batch:多条输入批量同步执行
方法定义(LangChain 1.2.7 源码规范)
python
def batch(
self,
inputs: List[Input],
config: Optional[Union[RunnableConfig, List[RunnableConfig]]] = None,
return_exceptions: bool = False,
chunk_size: Optional[int] = None,
**kwargs: Any
) -> List[Output]:
"""
同步批量执行多条输入,返回结果列表
:param inputs: 输入列表,每个元素格式需与组件兼容
:param config: 全局配置或配置列表(与 inputs 长度一致)
:param return_exceptions: 是否返回异常(False 直接抛出,True 异常对象存入结果列表)
:param chunk_size: 批处理分片大小(None 表示单次处理所有输入)
:param kwargs: 全局额外参数(适用于所有输入)
:return: 输出结果列表,顺序与 inputs 一致
"""
关键参数详解
| 参数 | 类型 | 说明 |
|---|---|---|
| inputs | List[Input] | 必须参数,多条输入的列表(长度≥1) |
| config | Optional[Union[RunnableConfig, List[RunnableConfig]]] | 可选配置:单个配置(全局生效)或配置列表(逐条对应输入) |
| return_exceptions | bool | 可选参数(默认False),True时异常不中断执行,异常对象存入结果列表 |
| chunk_size | Optional[int] | 可选参数,大列表分片处理(如 inputs 长度1000,chunk_size=100 分10批) |
| **kwargs | Any | 全局参数,所有输入共享(如统一设置 temperature=0.5) |
实战案例(独立可运行)
python
# 案例1:基础批量输入(无个性化配置)
batch_inputs = [
"解释 Python 装饰器的作用",
"说明 HTTP 1.1 与 HTTP 2.0 的区别",
"列举3种常见的数据库索引类型"
]
batch_results1 = llm.batch(batch_inputs)
for idx, result in enumerate(batch_results1):
print(f"案例1-第{idx+1}条输出:", result.content)
# 案例2:逐条配置(config 为列表)
configs = [
{"tags": ["batch-demo", "input-1"], "metadata": {"priority": "high"}},
{"tags": ["batch-demo", "input-2"], "metadata": {"priority": "medium"}},
{"tags": ["batch-demo", "input-3"], "metadata": {"priority": "low"}}
]
batch_results2 = llm.batch(batch_inputs, config=configs)
for idx, result in enumerate(batch_results2):
print(f"案例2-第{idx+1}条输出:", result.content)
# 案例3:异常处理(return_exceptions=True)
invalid_inputs = [
"解释 RESTful API", # 有效输入
12345, # 无效输入(类型错误)
"什么是微服务架构" # 有效输入
]
# 返回异常对象,不中断执行
batch_results3 = llm.batch(invalid_inputs, return_exceptions=True)
for idx, result in enumerate(batch_results3):
if isinstance(result, Exception):
print(f"案例3-第{idx+1}条:异常 - {type(result).__name__}: {str(result)}")
else:
print(f"案例3-第{idx+1}条输出:", result.content)
# 案例4:大列表分片处理(chunk_size)
large_inputs = [f"生成第{i}条Python学习路径" for i in range(10)] # 10条输入
# 分2批处理(每批5条)
batch_results4 = llm.batch(large_inputs, chunk_size=5, temperature=0.3)
for idx, result in enumerate(batch_results4):
print(f"案例4-第{idx+1}条输出:", result.content[:50] + "...") # 截断输出
注意事项
-
inputs列表中若存在无效输入,默认会抛出第一个异常,需通过return_exceptions=True捕获所有异常 -
chunk_size用于优化大批量输入的内存占用和API调用频率(如第三方模型API的QPS限制) -
当
config为列表时,长度必须与inputs一致,否则抛出ValueError -
批量方法的执行效率高于循环调用
invoke(减少网络开销和初始化成本)
2.3.4 异步核心方法:ainvoke / abatch
<2.3.4.1> ainvoke:单条输入异步执行
方法定义(LangChain 1.2.7 源码规范)
python
async def ainvoke(
self,
input: Input,
config: Optional[RunnableConfig] = None,
**kwargs: Any
) -> Output:
"""
异步执行单条输入,返回完整结果(需在异步上下文调用)
:param input: 输入数据(与 invoke 格式一致)
:param config: 执行配置(与 invoke 一致)
:param kwargs: 额外参数(与 invoke 一致)
:return: 组件输出结果(与 invoke 一致)
"""
关键特性
-
基于 Python
asyncio实现,非阻塞执行,适用于高并发场景 -
方法签名与
invoke完全一致,仅增加async关键字,降低学习成本 -
支持异步回调(
AsyncCallbackHandler),需配合异步上下文使用
实战案例(独立可运行)
python
import asyncio
# 定义异步执行函数
async def async_invoke_demo():
# 案例1:基础异步调用
result1 = await llm.ainvoke("用异步方式解释 ainvoke 的优势")
print("案例1输出:", result1.content)
# 案例2:带异步回调
from langchain_core.callbacks import AsyncConsoleCallbackHandler
async_config = {
"tags": ["async-demo", "ainvoke-method"],
"callbacks": [AsyncConsoleCallbackHandler()] # 异步回调
}
result2 = await llm.ainvoke(
"LangChain 异步方法的底层实现原理",
config=async_config,
temperature=0.4
)
print("案例2输出:", result2.content)
# 案例3:并发执行多个 ainvoke(核心优势)
task1 = llm.ainvoke("生成10个Python异步编程技巧")
task2 = llm.ainvoke("解释 async/await 的工作机制")
task3 = llm.ainvoke("对比同步与异步的性能差异")
# 并发执行,等待所有任务完成
results = await asyncio.gather(task1, task2, task3)
for idx, result in enumerate(results, 1):
print(f"案例3-任务{idx}输出:", result.content[:40] + "...")
# 运行异步函数
asyncio.run(async_invoke_demo())
注意事项
-
必须在异步上下文(
async def函数)中通过await调用,否则抛出RuntimeWarning -
异步回调需实现
AsyncCallbackHandler接口,不可混用同步回调类 -
适用于高并发场景(如Web服务接口),可避免线程阻塞导致的性能瓶颈
-
异常处理需使用
try/except包裹await语句,捕获异步异常
<2.3.4.2> abatch:多条输入批量异步执行
方法定义(LangChain 1.2.7 源码规范)
python
async def abatch(
self,
inputs: List[Input],
config: Optional[Union[RunnableConfig, List[RunnableConfig]]] = None,
return_exceptions: bool = False,
chunk_size: Optional[int] = None,
**kwargs: Any
) -> List[Output]:
"""
异步批量执行多条输入,返回结果列表(需在异步上下文调用)
:param inputs: 输入列表(与 batch 格式一致)
:param config: 全局配置或配置列表(与 batch 一致)
:param return_exceptions: 是否返回异常(与 batch 一致)
:param chunk_size: 批处理分片大小(与 batch 一致)
:param kwargs: 全局额外参数(与 batch 一致)
:return: 输出结果列表(与 batch 一致)
"""
关键特性
-
结合批量处理与异步并发的优势,适用于大规模高并发场景
-
分片处理(
chunk_size)在异步场景中可控制并发数,避免资源耗尽 -
与
batch接口完全对齐,迁移成本低
实战案例(独立可运行)
python
import asyncio
async def async_batch_demo():
# 案例1:基础异步批量调用
batch_inputs = [
"解释 Kafka 的消息投递机制",
"说明 Redis 的数据持久化方式",
"列举5种常见的微服务通信协议"
]
batch_results1 = await llm.abatch(batch_inputs)
for idx, result in enumerate(batch_results1):
print(f"案例1-第{idx+1}条输出:", result.content[:50] + "...")
# 案例2:分片异步批量(控制并发数)
large_inputs = [f"生成第{i}条云原生技术知识点" for i in range(8)] # 8条输入
# 分4批,每批2条(控制并发数为2)
batch_results2 = await llm.abatch(
large_inputs,
chunk_size=2,
temperature=0.2,
return_exceptions=True
)
for idx, result in enumerate(batch_results2):
if isinstance(result, Exception):
print(f"案例2-第{idx+1}条:异常 - {str(result)}")
else:
print(f"案例2-第{idx+1}条输出:", result.content[:40] + "...")
# 案例3:混合同步与异步批量(通过 Runnable 组合)
from langchain_core.runnables import RunnableSequence
# 定义同步处理函数(格式化输入)
def format_input(input_text: str) -> List[HumanMessage]:
return [HumanMessage(content=f"技术详解:{input_text}")]
# 构建链:同步格式化 + 异步批量执行
chain = RunnableLambda(format_input) | llm
chain_inputs = ["Docker", "Kubernetes", "Istio"]
chain_results = await chain.abatch(chain_inputs)
for idx, result in enumerate(chain_results):
print(f"案例3-第{idx+1}条输出:", result.content[:50] + "...")
# 运行异步函数
asyncio.run(async_batch_demo())
注意事项
-
chunk_size在异步场景中直接控制并发任务数(如chunk_size=5表示同时执行5个异步任务) -
大规模异步批量(如输入数>100)需合理设置
chunk_size,避免触发API速率限制或本地资源耗尽 -
异常处理逻辑与
batch一致,但需在异步函数内使用try/except捕获 -
与
Runnable组合使用时,同步组件会自动适配异步执行流程(LangChain 1.2.7 内置适配逻辑)
2.3.5 流式核心方法:stream / astream
<2.3.5.1> stream:同步流式输出
方法定义(LangChain 1.2.7 源码规范)
python
def stream(
self,
input: Input,
config: Optional[RunnableConfig] = None,
**kwargs: Any
) -> Iterator[OutputChunk]:
"""
同步流式输出结果片段(迭代器形式)
:param input: 输入数据(与 invoke 格式一致)
:param config: 执行配置(与 invoke 一致)
:param kwargs: 额外参数(支持 `stream_options` 等流式专用参数)
:return: 结果片段迭代器(每个元素为 OutputChunk 类型)
"""
关键特性
-
流式输出:结果分片段返回,无需等待完整响应,降低交互延迟
-
迭代器接口:通过
for循环迭代获取片段,支持实时处理(如前端渲染) -
片段类型:
OutputChunk包含content(内容)、metadata(元数据)、type(片段类型)等属性
实战案例(独立可运行)
python
# 案例1:基础流式输出(文本片段迭代)
print("案例1:基础流式输出")
for chunk in llm.stream("详细解释 LangChain 流式输出的应用场景"):
print(chunk.content, end="", flush=True) # 实时打印,不换行
print("\n" + "-"*50)
# 案例2:流式片段元数据解析
print("案例2:流式片段元数据")
for chunk in llm.stream(
"生成5条数据可视化的最佳实践",
config={"tags": ["stream-demo"]},
stream_options={"include_usage": True} # 启用使用量统计(部分模型支持)
):
print(f"内容片段:{chunk.content}")
print(f"片段类型:{chunk.type}")
print(f"元数据:{chunk.metadata}")
print("-"*30)
# 案例3:流式结果拼接(获取完整结果)
print("案例3:流式结果拼接")
full_content = []
for chunk in llm.stream("LangChain stream 方法的底层实现原理"):
full_content.append(chunk.content)
print(chunk.content, end="", flush=True)
complete_result = "".join(full_content)
print(f"\n完整结果:{complete_result}")
# 案例4:流式与 Runnable 组合
from langchain_core.runnables import RunnableParallel
# 定义并行链:同时流式输出两个结果
parallel_chain = RunnableParallel(
task1=llm.stream,
task2=RunnableLambda(lambda x: f"总结:{x}") | llm.stream
)
input_text = "解释 MLOps 的核心流程"
print("案例4:并行流式输出")
for key, chunk in parallel_chain.stream(input_text):
print(f"[{key}] {chunk.content}", end="", flush=True)
print("\n")
注意事项
-
流式方法返回的是迭代器,需通过
for循环或next()方法获取片段,不可直接打印迭代器对象 -
stream_options参数为模型专用(如 OpenAI 支持include_usage、logprobs等),需根据模型文档配置 -
流式输出过程中不可中断迭代(除非捕获
StopIteration),否则可能导致连接泄漏 -
适用于实时交互场景(如聊天机器人、实时日志展示),需配合前端或终端的流式渲染逻辑
<2.3.5.2> astream:异步流式输出
方法定义(LangChain 1.2.7 源码规范)
python
async def astream(
self,
input: Input,
config: Optional[RunnableConfig] = None,
**kwargs: Any
) -> AsyncIterator[OutputChunk]:
"""
异步流式输出结果片段(异步迭代器形式)
:param input: 输入数据(与 stream 格式一致)
:param config: 执行配置(与 stream 一致)
:param kwargs: 额外参数(与 stream 一致)
:return: 异步结果片段迭代器(需通过 async for 迭代)
"""
关键特性
-
结合异步非阻塞与流式输出的优势,适用于高并发实时场景(如异步Web服务)
-
异步迭代器:通过
async for循环迭代,支持并发处理多个流式任务 -
与
stream接口完全对齐,仅迭代方式不同(async forvsfor)
实战案例(独立可运行)
python
import asyncio
async def async_stream_demo():
# 案例1:基础异步流式输出
print("案例1:基础异步流式输出")
async for chunk in llm.astream("异步流式输出的核心优势是什么?"):
print(chunk.content, end="", flush=True)
print("\n" + "-"*50)
# 案例2:并发异步流式任务
async def stream_task(prompt: str, task_name: str):
print(f"\n案例2 - {task_name} 开始:")
async for chunk in llm.astream(prompt):
print(f"[{task_name}] {chunk.content}", end="", flush=True)
print(f"\n案例2 - {task_name} 结束")
# 并发执行两个异步流式任务
task1 = stream_task("解释异步迭代器的工作原理", "任务1")
task2 = stream_task("列举3种异步流式处理框架", "任务2")
await asyncio.gather(task1, task2)
# 案例3:异步流式结果拼接与处理
print("\n案例3:异步流式结果拼接")
full_content = []
async for chunk in llm.astream(
"LangChain astream 与 stream 的差异对比",
temperature=0.3
):
full_content.append(chunk.content)
print(chunk.content, end="", flush=True)
complete_result = "".join(full_content)
print(f"\n完整结果:{complete_result}")
# 运行异步函数
asyncio.run(async_stream_demo())
注意事项
-
必须通过
async for迭代异步流式迭代器,不可使用普通for循环 -
并发处理多个异步流式任务时,需通过
asyncio.gather或任务组管理,避免并发数过高 -
异步流式输出的异常需在
async for循环内通过try/except捕获 -
适用于异步Web框架(如 FastAPI)的实时响应场景,需配合异步响应对象(如
StreamingResponse)
2.3.6 核心方法对比与适用场景
| 方法 | 执行模式 | 输入数量 | 输出形式 | 核心适用场景 | 性能特点 |
|---|---|---|---|---|---|
| invoke | 同步 | 单条 | 完整结果 | 单条请求、低并发、需立即获取结果 | 简单直接,阻塞线程 |
| ainvoke | 异步 | 单条 | 完整结果 | 高并发单条请求、异步服务 | 非阻塞,支持高并发 |
| batch | 同步 | 多条 | 结果列表 | 批量处理、低并发批量任务 | 批量优化,减少开销 |
| abatch | 异步 | 多条 | 结果列表 | 高并发批量任务、大规模处理 | 异步并发+批量优化,效率最高 |
| stream | 同步 | 单条 | 片段迭代器 | 实时交互、同步终端展示 | 低延迟,实时反馈 |
| astream | 异步 | 单条 | 异步片段迭代器 | 高并发实时交互、异步Web服务 | 非阻塞+实时反馈,支持高并发 |
2.3.7 进阶实践:最佳实践与架构扩展
<2.3.7.1> 配置透传最佳实践
Runnable 核心方法的 config 参数支持全局配置透传,结合 LangChain 1.2.7 的上下文管理机制,可实现:
-
全链路标签追踪 :通过
tags标记请求来源,用于日志分析和链路追踪 -
统一回调管理:全局注册回调函数,监控所有方法的执行状态(开始、结束、异常)
-
动态元数据注入 :通过
metadata传递用户信息、请求ID等上下文数据
python
# 全局配置示例(适用于所有核心方法)
from langchain_core.callbacks import BaseCallbackHandler
from langchain_core.runnables import RunnableConfig
class CustomCallback(BaseCallbackHandler):
"""自定义回调函数(监控执行生命周期)"""
def on_chain_start(self, serialized: dict, inputs: dict, **kwargs):
print(f"[回调] 执行开始 - 组件:{serialized['name']},输入:{inputs.keys()}")
def on_chain_end(self, outputs: dict, **kwargs):
print(f"[回调] 执行结束 - 输出长度:{len(str(outputs))}")
# 全局统一配置
global_config: RunnableConfig = {
"tags": ["production", "runnable-best-practice"],
"metadata": {"app_name": "langchain-demo", "env": "prod"},
"callbacks": [CustomCallback()]
}
# 所有核心方法共享配置
# 1. invoke 用全局配置
result_invoke = llm.invoke("配置透传示例", config=global_config)
# 2. batch 用全局配置
batch_results = llm.batch(["配置透传1", "配置透传2"], config=global_config)
# 3. stream 用全局配置
for chunk in llm.stream("配置透传3", config=global_config):
pass
<2.3.7.2> 性能优化指南
-
批量方法优化:
-
大批量输入优先使用
batch/abatch,避免循环调用invoke/ainvoke -
根据API QPS限制调整
chunk_size(如 OpenAI 免费版 QPS=3,chunk_size=3) -
启用
return_exceptions=True避免单条输入异常导致批量任务失败
-
-
异步方法优化:
-
高并发场景优先使用
ainvoke/abatch/astream,避免线程池耗尽 -
异步批量任务通过
chunk_size控制并发数(推荐值:CPU核心数×2 + 1) -
避免在异步方法内执行同步阻塞操作(如
time.sleep),需使用asyncio.sleep
-
-
流式方法优化:
-
实时交互场景优先使用
stream/astream,减少用户等待感 -
流式输出时避免频繁IO操作(如打印、数据库写入),可批量缓存片段后处理
-
大文本输出场景使用流式方法,避免内存占用过高
-
<2.3.7.3> 可扩展性设计(自定义 Runnable 方法重写)
当自定义 Runnable 组件时,需遵循 1.2.7 版本的协议规范,重写核心方法时需注意:
-
方法签名一致性:严格遵循官方方法的参数定义(输入、输出、配置参数)
-
异步同步适配 :若重写
invoke,建议同时重写ainvoke(或依赖默认实现) -
配置透传完整性 :确保
config参数在自定义逻辑中正确传递和使用 -
异常处理标准化 :统一抛出
LangChainException及其子类,便于上层捕获
python
from langchain_core.runnables import Runnable
from langchain_core.exceptions import LangChainException
from typing import Any, Iterator, Optional, List
class CustomRunnable(Runnable):
"""自定义 Runnable 示例(重写核心方法)"""
def invoke(
self,
input: str,
config: Optional[RunnableConfig] = None,
**kwargs: Any
) -> str:
try:
# 自定义同步逻辑
if not isinstance(input, str):
raise ValueError("输入必须为字符串")
return f"自定义处理结果:{input.upper()}"
except Exception as e:
raise LangChainException(f"invoke 执行失败:{str(e)}") from e
async def ainvoke(
self,
input: str,
config: Optional[RunnableConfig] = None,
**kwargs: Any
) -> str:
# 自定义异步逻辑(可调用同步逻辑并包装为异步)
return await asyncio.get_event_loop().run_in_executor(
None, self.invoke, input, config, **kwargs
)
def stream(
self,
input: str,
config: Optional[RunnableConfig] = None,
**kwargs: Any
) -> Iterator[str]:
# 自定义流式逻辑
result = self.invoke(input, config, **kwargs)
for char in result:
yield char # 逐字符流式输出
# 测试自定义 Runnable
custom_runnable = CustomRunnable()
# 调用核心方法
print("自定义 Runnable invoke:", custom_runnable.invoke("test input"))
# 异步调用
async def test_ainvoke():
print("自定义 Runnable ainvoke:", await custom_runnable.ainvoke("async test"))
asyncio.run(test_ainvoke())
# 流式调用
print("自定义 Runnable stream:", end="")
for chunk in custom_runnable.stream("stream test"):
print(chunk, end="", flush=True)
<2.3.7.4> 错误处理最佳实践
-
分层异常捕获:
-
顶层:捕获
LangChainException(所有LangChain组件的基础异常) -
中层:捕获方法特定异常(如
ValidationError输入格式错误、APIError第三方API错误) -
底层:捕获通用异常(如
ValueError、TypeError)
-
-
批量方法异常处理:
-
关键任务:
return_exceptions=False,快速失败并排查问题 -
非关键任务:
return_exceptions=True,记录异常并继续执行其他输入
-
-
流式方法异常处理:
-
同步流式:在
for循环内捕获StopIteration和自定义异常 -
异步流式:在
async for循环内捕获StopAsyncIteration和自定义异常
-
python
# 异常处理示例
try:
# 1. 输入格式错误
invalid_input = {"text": "错误格式"}
llm.invoke(invalid_input) # 抛出 ValidationError
except ValueError as e:
print(f"输入格式错误:{str(e)}")
except Exception as e:
print(f"其他异常:{str(e)}")
# 2. 批量方法异常处理(关键任务)
try:
critical_inputs = ["有效输入", 123, "另一个有效输入"]
llm.batch(critical_inputs, return_exceptions=False) # 抛出第一个异常
except Exception as e:
print(f"批量任务失败:{str(e)}")
# 执行回滚逻辑
# 3. 流式方法异常处理
try:
for chunk in llm.stream(12345): # 无效输入
print(chunk.content, end="")
except Exception as e:
print(f"\n流式执行失败:{str(e)}")