【QWen1.5】 LangChainDeprecationWarning: The function `__call__` was deprecated in LangChain 0.1.7 and will be removed in 0.2.0. Use invoke instead. warn_deprecated(
BaseLLM.call 方法(即直接调用 LLM 对象)迁移至 invoke 方法
在原来报错的代码中,是用“llm("你是谁")”来调用回复
这种用法会直接调用BaseLLM.call 方法,导致如下报错:
/root/miniconda3/lib/python3.10/site-packages/langchain_core/_api/deprecation.py:117:
LangChainDeprecationWarning: The function `__call__` was deprecated in LangChain 0.1.7 and will be removed in 0.2.0. Use invoke instead.
warn_deprecated(
解决方法
# llm("你是谁")
response = llm.invoke("你是谁")
print(response)
如上,改为用llm.invoke获取回复,再把回复print出来即可,得到正确的回答:
我是阿里云推出的一种超大规模语言模型,我叫通义千问。作为一个AI助手,我的目标是帮助用户获得准确、有用的信息,解决他们的问题和困惑。我会不断学习和进步,不断提升自己的能力,为用户提供更好的服务。有什么问题我可以帮助你解答吗?
豆包回答
你想了解在大语言模型(LLM)开发中,直接调用llm()、print(llm.invoke())这两种调用方式的区别,以及BaseLLM.__call__和invoke这两个核心方法的差异,我会从使用场景、底层逻辑和实际效果三个维度帮你讲清楚。
一、先理解 llm() 与 print(llm.invoke()) 的区别
这两种写法本质是调用方式的语法糖差异 + 输出形式的不同,核心都是触发LLM的推理,但使用场景和返回结果的呈现方式完全不同:
| 特性 | llm() (直接调用实例) |
print(llm.invoke()) (调用invoke后打印) |
|---|---|---|
| 底层逻辑 | 本质是调用 llm.__call__() 方法 |
显式调用 llm.invoke() 方法后打印返回值 |
| 返回值处理 | 直接返回LLM的响应对象/字符串(可赋值) | 仅打印结果,返回值被print消费(无赋值) |
| 使用场景 | 需要对响应结果做后续处理(如解析、存储) | 仅需快速查看LLM的输出结果(调试/验证) |
| 示例效果 | response = llm("你好") → response 可后续操作 |
print(llm.invoke("你好")) → 控制台输出"你好!有什么我能帮你的吗?" |
代码示例(以LangChain框架为例)
from langchain_openai import ChatOpenAI
# 初始化LLM实例(需配置OPENAI_API_KEY)
llm = ChatOpenAI(model="gpt-3.5-turbo")
# 1. 使用 llm() 调用(底层是__call__)
response = llm("请说一句简单的问候语")
print("llm() 返回类型:", type(response)) # <class 'langchain_core.messages.ai.AIMessage'>
print("llm() 提取内容:", response.content) # 提取具体回复文本
# 2. 使用 print(llm.invoke()) 调用
print("\nllm.invoke() 直接打印结果:")
print(llm.invoke("请说一句简单的问候语")) # 直接打印AIMessage对象(含content、role等)
# 若想只打印文本,需写成 print(llm.invoke("问候语").content)
关键解释:
llm()是“隐式调用”,返回的是完整的响应对象(包含回复内容、角色、元数据等),你可以把它赋值给变量,后续做解析、存储、二次处理;print(llm.invoke())是“显式调用+打印”,invoke()返回的响应对象会被print直接输出(控制台显示),但你无法再获取这个返回值做后续操作,适合快速调试看结果。
二、深入对比 BaseLLM.__call__ 与 invoke
BaseLLM 是LangChain等框架中所有LLM类的基类,__call__ 和 invoke 是其核心执行方法,二者的差异是设计层面的分工,而非功能层面的对立:
1. 核心定义与设计初衷
| 方法 | BaseLLM.__call__ |
BaseLLM.invoke |
|---|---|---|
| 本质 | Python魔法方法(运算符重载) | 标准执行方法(显式API) |
| 设计目的 | 提供“类函数式”的简洁调用方式(语法糖) | 遵循LangChain统一的Runnable接口规范 |
| 调用方式 | llm(prompt) 或 llm.__call__(prompt) |
llm.invoke(prompt) |
| 兼容性 | 部分旧版LLM类可能仅实现__call__ | 新版LangChain(v0.1+)主推invoke |
2. 底层逻辑与实际表现
-
__call__的底层逻辑:
绝大多数现代LLM类的__call__方法,内部其实是直接调用invoke方法的,比如:class BaseLLM: def __call__(self, prompt, **kwargs): # 做一些参数兼容/格式转换 return self.invoke(prompt, **kwargs)也就是说,
__call__是invoke的“包装器”,目的是让调用更简洁(不用写.invoke())。 -
invoke的核心优势:
invoke遵循LangChain的Runnable接口(还有stream/batch等方法),具备更强的规范性和扩展性:- 支持统一的参数格式(如
Input/Output类型校验); - 兼容LangChain的链式调用(
chain = prompt | llm | parser); - 支持流式输出、批量调用等扩展功能(
invoke可配合streaming=True返回流式响应); - 更好的异常处理和日志记录。
- 支持统一的参数格式(如
3. 适用场景
| 方法 | 适用场景 | 不适用场景 |
|---|---|---|
__call__ |
快速原型开发、简单调用(追求代码简洁) | 标准化开发、链式调用、流式输出 |
invoke |
生产环境、标准化开发、链式调用、流式输出 | 仅临时调试(比__call__多写几个字符) |
三、总结
llm()vsprint(llm.invoke()):前者返回完整响应对象可后续处理,后者仅打印结果无返回值,核心是“是否需要复用响应结果”;BaseLLM.__call__vsinvoke:__call__是invoke的语法糖(底层调用invoke),invoke是标准化API,新版框架主推使用invoke(更规范、扩展性更强);- 实际开发建议:调试时可临时用
llm()或print(llm.invoke()),生产环境优先用llm.invoke()(显式、规范、易维护)。
关键点回顾
llm()等价于llm.__call__(),返回响应对象可赋值复用;print(llm.invoke())仅打印结果,无可用返回值;__call__是魔法方法(语法糖),invoke是标准执行方法,前者底层调用后者;- 生产环境优先用
invoke,遵循接口规范,便于扩展和维护。

浙公网安备 33010602011771号