🎯 课程主题
详细解析 invoke 返回的 AIMessage 对象结构,包括 content、response_metadata、id、usage_metadata、工具调用信息等字段的含义和使用方式。
📝 核心知识点
1. AIMessage 对象概览
- 概念说明:
invoke的返回值是一个AIMessage对象,包含模型回复的完整信息。 - 验证方式:
print(type(response))→<class 'langchain_core.messages.ai.AIMessage'>
2. 核心属性详解
content
- 类型:
str - 说明:模型返回给用户的文本回复内容,是最常用的字段。
- 获取方式:
response.content
additional_kwargs
- 说明:包含特定供应商的额外参数信息。
- 典型字段:
refusal(None表示正常回答,非None表示模型因安全原因拒绝回答)。
response_metadata
- 说明:响应的元数据,包含最丰富的信息,涵盖以下子类:
- Token 消耗信息:
token_usage对象,包含:completion_tokens:输出 token 数prompt_tokens:输入 token 数total_tokens:总 token 数completion_tokens_details:输出细节(含推理 token 数等,推理模型如 o1/o3 特有)
- 性能与延迟信息:
- token 间平均间隔(如 4ms)
- 首 token 生成时间
- 末 token 生成时间
- 请求到首字输出总时间等
- 模型信息:
model_name:使用的模型名称system_fingerprint:服务商指纹
- API 层信息:
id(API 响应的唯一标识) finish_reason:结束原因"stop":正常结束"length":因max_tokens限制而截断
- Token 消耗信息:
id
- 说明:LangChain 在本次调用过程中生成的唯一标识(区别于 API 层面的 id)。
工具调用信息
tool_calls:工具调用请求(后期讲解 Function Calling 时体现)。invalid_tool_calls:工具调用失败信息。
3. 美化输出的两种方式
- 仅查看 content:使用
response.pretty_print()或直接print(response.content)。 - 查看完整结构化信息:使用
rich库的print函数(可重命名为rprint避免与内置print冲突)。
🏗️ 架构与工作流
model.invoke(input)
│
▼
AIMessage 对象
│
├── .content → 文本回复(最常用)
├── .response_metadata → 元数据(token消耗、延迟、模型信息)
│ ├── .token_usage → 详细 token 消耗
│ ├── .model_name → 模型名称
│ ├── .finish_reason → 结束原因
│ └── ...
├── .additional_kwargs → 供应商特定参数(如 refusal)
├── .id → LangChain 内部唯一标识
├── .tool_calls → 工具调用信息(后期)
└── .invalid_tool_calls → 工具调用失败信息(后期)
💻 代码实战
from langchain.chat_models import init_chat_model
from langchain_core.messages import HumanMessage
model = init_chat_model(
model="gpt-4o-mini",
model_provider="openai",
base_url="https://api.closeai-asia.com/v1"
)
response = model.invoke([HumanMessage(content="2 + 3 * 2 等于多少?")])
# ----- 查看类型 -----
print(type(response)) # <class 'langchain_core.messages.ai.AIMessage'>
# ----- 获取文本回复 -----
print(response.content) # 计算结果
# ----- 使用 rich 库美化输出全量信息 -----
from rich import print as rprint
rprint(response)
# ----- 提取 response_metadata 中的关键信息 -----
metadata = response.response_metadata
print(f"模型名称: {metadata.get('model_name')}")
print(f"结束原因: {metadata.get('finish_reason')}")
# ----- 提取 token 消耗 -----
token_usage = response.response_metadata.get("token_usage", {})
print(f"输入 tokens: {token_usage.get('prompt_tokens')}")
print(f"输出 tokens: {token_usage.get('completion_tokens')}")
print(f"总计 tokens: {token_usage.get('total_tokens')}")
# ----- 仅查看 content(使用 pretty_print) -----
response.pretty_print()
⚠️ 常见问题与避坑指南
finish_reason为"length"表示输出被截断:当设置了max_tokens且模型输出达到限制时,回复不完整,需要增大max_tokens值。- 不同模型的
response_metadata结构可能不同:OpenAI、DeepSeek、千问等不同供应商返回的元数据字段名称和结构存在差异,提取时建议使用.get()方法并设置默认值。 - Token 消耗信息可能在
response_metadata.token_usage或response.usage_metadata中:取决于 LangChain 版本和模型 provider,实际开发中两者都可能出现。 - 推理模型(如 o1/o3)有额外的
reasoning_tokens:如果调用的不是推理模型,该字段为 0。
💡 个人总结与延伸
AIMessage 不仅是文本回复的容器,还承载了 token 消耗、延迟性能、供应商元数据等关键运维信息。在实际项目中,可以通过解析 response_metadata 实现 cost tracking(成本监控)、latency monitoring(延迟监控)等功能。rich 库是调试时查看 AIMessage 全貌的利器,推荐在开发阶段使用。后续章节涉及 Function Calling 时,tool_calls 字段将成为核心关注点。