ChatModels & LLMs

LangChain中的大模型组件主要分为ChatModels和LLMs两类,ChatModels支持OpenAI和LangChain两种消息格式、工具调用、结构化输出及多模态处理,适用于现代对话场景;而LLMs仅支持字符串输入输出,功能较单一,已逐渐被弃用。此外,LongChain 0.3版本后对依赖包进行了拆分,分为官方合作包(如ChatOpenAI)和社区开发包(如LangChain Community),前者由官方维护,适配主流模型,后者由社区贡献,灵活性较高但维护性较差。实际开发中推荐使用ChatModels和官方合作包以确保兼容性和稳定性。
- ChatModels具备工具调用能力(Tool Call / Function Call)并支持结构化输出如JSON/XML
- ChatModels支持多模态输入输出,包括文本、音频、图像等
- LLMs是早期版本遗留下来的模式,目前已逐渐被Chat Modules取代
- 通过函数名前缀判断模块类型:Chat开头的是ChatModels,LLM结尾的是llms
LangChain包相关的:
- 官方合作包:https://python.langchain.com/docs/integrations/providers/
- 社区开发包:https://python.langchain.com/docs/integrations/chat/
大模型的接入示例
OpenAI接入
1 | import os |
DeepSeek接入
1 | import os |
Anthropic接入
1 | import os |
标准参数、事件、与输入输出
学习了大模型组件的标准参数和事件,包括模型名称、随机度(temperature)、超时时间、输出长度限制等配置,以及调用模型的主要方法如Invoke、Stream、Batch和异步流式输出。通过合理设置这些参数和使用不同事件,可以提升应用的交互体验和功能实现。
标准参数
补全参数 (Completion Params)
这些参数主要用于控制生成文本的特性。
model: 要使用的 OpenAI 模型的名称,类型为str。temperature: 采样温度,类型为float。该值越高,生成文本的随机性越强;反之,值越低,生成文本的确定性越强。max_tokens: 要生成的最大 token 数量,类型为可选的int。这决定了生成文本的长度上限。logprobs: 是否返回每个生成 token 的对数概率,类型为可选的bool。这对于分析模型预测的置信度很有用。stream_options: 配置流式输出的选项,类型为Dict。例如,可以设置{"include_usage": True}来在流式传输时返回 token 使用情况。use_responses_api: 是否使用responsesAPI,类型为可选的bool。- stop:指定停止字符
客户端参数 (Client Params)
这些参数主要用于配置客户端与 OpenAI API 的交互方式。
timeout: 请求的超时时间,类型为Union[float, Tuple[float, float], Any, None]。可以是一个浮点数表示总超时时间,也可以是一个元组来分别指定连接和读取超时时间。max_retries: 最大重试次数,类型为可选的int。当请求失败时,客户端会尝试重新发送请求,此参数决定了最大重试次数。api_key: OpenAI API 密钥,类型为可选的str。如果未在此处传入,将从环境变量OPENAI_API_KEY中读取。base_url: API 请求的基础 URL,类型为可选的str。只有在使用代理或服务模拟器时才需要指定。organization: OpenAI 组织 ID,类型为可选的str。如果未传入,将从环境变量OPENAI_ORG_ID中读取。- rater_limiter:请求速率限制
注意:
- 标准参数只对本身API开发了相关参数的模型有用,比如有的模型本身没有指定的max_token,则其在LangChain中也无效
- 标准参数仅在官方合作包中强制要求,社区开发包不做强制要求
根据标准参数,大模型初始化
1 | import os |
标准事件
- invoke:模型主要调用方法,输入list,输出list
- stream:流式输出方法
- batch:批量模型请求方法
- bind_tools:在模型执行的时候绑定工具
- with_structured_output:给予invoke的结构化输出
其他有用事件
- ainvoke:异步调用模型方法
- astream:异步流式输出
- abatch:异步的批量处理
- astream_events:异步流事件,支持更细粒度的控制
- with_retry:调用失败时才重试
- with_fallback:失败恢复事件
- configurble_fields:模型运行时的运行参数,适用于复杂的应用开发场景
标准事件,代码示例:
1 | # 定义模型 |
标准事件之结构化输出 - with_structured_output,代码示例
1 | # 标准事件之结构化输出 - with_structured_output |
数据通信的格式
OpenAI Messages
- SystemMessage:用于传导对话的内容
- HumanMessage:用户输入的内容
- AIMessage:模型响应的内容
- 多模型
LangChain Messages
- SystemMessage:系统角色
- HumanMessage:用户角色
- AIMessage:应用助理角色
- AIMessageChunk:应用助理流式输出
- ToolMessage:工具角色
AIMessage
AI返回的数据
| 属性 | 标准化 | 描述 |
|---|---|---|
| content | 原生 | 通常为字符串,但也可以时内容块列表 |
| tool_calls | 标准化 | 与消息相关的工具调用 |
| invalid_tool_calls | 标准化 | 工具调用与消息相关的解析错误 |
| usage_metadata | 标准化 | 元数据(输入输出token数,总计token数等) |
| id | 标准化 | 消息唯一标识 |
| response_metadata | 原生 | 响应元数据(响应头、token计数等) |
注意:不同的大模型提供的内容属性并不相同目前行业暂无统一标准
几款主流大模型响应数据的字段对比
大模型的厂商都是提供详细的接口调用的详细说明,会有字段详细的说了,如果需要多不同大模型的协作,因此查看文档后,需要处理统一格式。
| 字段类别 | 字段名 | DeepSeek | OpenAI (ChatGPT) | 阿里云 (Qwen) | Anthropic (Claude) |
|---|---|---|---|---|---|
| 基本结构 | 响应结构 | status, code, message, data |
object, choices, usage |
object, choices, usage |
与OpenAI类似 |
| 唯一ID | id (在data内) |
id |
id |
id |
|
| 生成内容 | 回复内容 | generated_text (在data内) |
choices[index].message.content |
choices[index].message.content |
content (位于不同结构中) |
| 停止原因 | 未明确提及 | choices[index].finish_reason |
choices[index].finish_reason |
stop_reason |
|
| 角色 | 未明确提及 | choices[index].message.role (assistant) |
choices[index].message.role (assistant) |
role |
|
| 使用统计 | Token消耗 | token_count (在data内) |
usage.prompt_tokens, usage.completion_tokens, usage.total_tokens |
usage.prompt_tokens, usage.completion_tokens, usage.total_tokens |
需在请求中设置 extra_parameters 来获取 |
| 模型信息 | 模型名称 | 在请求中指定 | model |
model |
model |
| 系统指纹 | 未明确提及 | system_fingerprint |
system_fingerprint (常为null) |
未明确提及 | |
| 时间戳 | timestamp (ISO8601) |
created (Unix时间戳) |
created (Unix时间戳) |
未明确提及 | |
| 高级功能 | 工具调用 | 未明确提及 | tool_calls |
模型上下文窗口与token
大模型的上下文窗口是指模型一次可处理的最大文本长度,受限于计算复杂度、硬件显存和训练数据长度。窗口过长会导致内存和计算需求激增,并可能因注意力衰减影响长文效果。解决方式包括引入外挂记忆(如REG)、滑动窗口技术及新架构探索。Token是模型处理的基本单位,其信息密度高于字符,且不同模型支持的窗口长度不一,应用时需注意控制输入输出长度以避免溢出问题。
什么是上下文窗口
是大模型一次最多可以处理上下文的长度,根据模型有关,跟以下相关:
- 计算复杂度:Transformer架构自注意力机制计算复杂度O(n²),其中n是序列长度,当n增长时,内存和计算需求呈平方增长
- 硬件限制:GPU显存有限,处理长序列需要更多显存,序列越长模型响应时间越长
- 训练数据限制:预训练数据大多为短文本、长文本比较少,模型难以学习长距离依赖关系
- 注意衰减:随着序列长度增加,模型会对早期信息注意力下降,从而造成遗忘和长文质量不佳现象
模型的token
- token事大模型处理信息的基本单位,将文本转化为机器更容易处理的形式,token并非等同于字符或单词,1token不等于1汉子
- token可以是一个字一个词一句话一部分图片信息
- token具有更高的语言浓缩能力,比原始字符更高效地表达语义和上下文关系
- 给机器读的语言
- 不同模型对token的定义和切分方式有所不同,例如OpenAI中的一个token约等于4个英文字符,3/4个单词
- 应用中需要注意token不能超出模型上下文窗口的限制
token的监控与追踪
- 大多数模型支持token消耗的追踪,用于统计费用及优化性能。
- LangChain中可通过usage字段获取详细的token用量信息,包括输入、输出token数。
- 不同平台(如DeepSeek、OpenAI)的token元数据字段名称略有差异,但用途一致。
- 支持流式输出时的token追踪,尤其在OpenAI API中可以通过stream usage开启。
速率限制与缓存机制
在实际应用中,很多模型如DeepSeek对其API有速率限制,主要是因为用户量增长快导致API压力大,为防止服务不可用,各家都会进行限制。以OpenAI为例,不同用户类型和模型有不同的速率限制标准,如免费用户每分钟只能请求三次,付费用户则相对宽松。为应对速率限制,通常会引入缓存机制减少模型调用频率,同时也可以通过设置速率控制参数(如RateLimiter)来避免超出限制,从而提升系统稳定性和用户体验。
| 账户类型 | Text & Embedding(文本和嵌入) | Chat (聊天对话) | Edit (编辑) | Image (图像) | Audio (音频) |
|---|---|---|---|---|---|
| Free trial users(免费试用用户) | 3 RPM, 150,000 TPM | 3 RPM, 40,000 TPM | 3 RPM, 150,000 TPM | 5 images / min | 3 RPM |
| 按需付费用户 (前 48 小时) | 60 RPM, 250,000 TPM | 60 RPM, 60,000 TPM | 20 RPM, 150,000 TPM | 50 images / min | 50 RPM |
| 按量付费用户 (48 小时后) | 3,500 RPM, 350,000 TPM | 3,500 RPM, 90,000 TPM | 20 RPM, 150,000 TPM | 50 images / min | 50 RPM |
备注:
- RPM (Requests Per Minute):每分钟请求数。
- TPM (Tokens Per Minute):每分钟 Token 数。
graph TD
A[用户问题] --> B[是否相同]
B --> C(缓存层)
B --> D(LLM)
缓存层:
- 长期缓存
- 短期缓存
速率限制示例代码
langchain中的InMemoryRateLimiter(写入内存)只能限制单位时间内的请求数量, 无法处理根据请求大小来限制的情况
1 | import os |
大模型工具调用原理
大模型工具调用是指在应用开发中,让模型具备调用外部工具的能力,区别于普通使用方式。通过绑定工具(如数据库查询、天气API等),模型可根据用户问题判断是否需要调用工具,并生成结构化数据请求工具执行,获取实时信息或处理复杂任务(如数学运算),从而增强模型的实用性与准确性。工具调用扩展了模型的功能,使其能结合外部资源提供更精准的回答。
- 创建工具(如数据库工具)
- 将工具绑定到模型
- 模型判断某个输入问题需要调用工具
- 工具调用生成结构化数据
- 使用工具(查询数据库)
- 得到工具使用的结果(数据结果)
- 返回给大模型增强回答

- 工具调用允许大模型通过调用工具来响应提示词
- 事实是模型只是生成工具参数,并不直接运行
- 本质上是模型生成的一段特定的结构化数据
- 并不是所有的模型都支持工具调用

绑定工具的代码示例
两种方式:
大模型直接绑定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31import os
from pydantic import BaseModel, Field
from langchain_openai import ChatOpenAI
api_base = os.getenv("OPENAI_API_BASE")
api_key = os.getenv("OPENAI_API_KEY")
llm = ChatOpenAI(
temperature=0.0,
base_url=api_base,
api_key=api_key
)
#加法工具
class add(BaseModel):
"""Add two integers."""
a: int = Field(..., description="First integer")
b: int = Field(..., description="Second integer")
#乘法工具
class multiply(BaseModel):
"""Multiply two integers."""
a: int = Field(..., description="First integer")
b: int = Field(..., description="Second integer")
tools = [add,multiply] # 一个模型可以绑定多个工具的
llm_with_tools = llm.bind_tools(tools)
query="3乘以12是多少?"
llm_with_tools.invoke(query).tool_calls # 输出大模型调用的工具
使用@tool装饰器,注意:函数一定要有注释,这个会作为定义工具的描述
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27import os
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
api_base = os.getenv("OPENAI_API_BASE")
api_key = os.getenv("OPENAI_API_KEY")
llm = ChatOpenAI(
temperature=0.0,
base_url=api_base,
api_key=api_key
)
def multiply(a:int,b:int) -> int:
"""Multiply two numbers."""
return a*b
print(multiply.name)
print(multiply.description)
print(multiply.args)
print("********************************************")
tools = [multiply]
llm_with_tools = llm.bind_tools(tools)
query="3乘以12是多少?"
llm_with_tools.invoke(query).tool_calls
LangChain ModelsIO OutputParsers
LangChain已经可以轻松实现帮用户拿到大语言模型的输出,然而不难发现,前文介绍的模型调用,显示返回的内容通常是一个类(class)实例,其中包含了content以及其他一些额外的参数。
对于模型调用者来说,可能只关心content的内容,也就是模型对输入内容的回答,或者希望得到一个可操作的数据结构,比如JSON格式的数据。
OutputParsers的优势
LangChain设计的初衷之一,旨在让用户更便捷地使用大模型,所以为了解决输出内容格式化的问题。
通过使用LangChain提供的解析器,用户可以更轻松地获取模型的输出,并直接处理或操作所需的内容,而无需进行额外的转换或处理。
解析器类型
根据业务需求,开发者通常需要大模型返回一个结构化的数据,方便后续的逻辑可以根据这个数据进行进一步的处理。
然而不同的输入结果可能需要相对应的解析器来做处理,LangChain同样提供了几种常见的解析器类型:
- String解析器
- Json解析器
- Pydantic解析器
- 结构化输出解析器
- OpenAI函数输出解析器
实战示例
String解析器
LangChain提供了StrOutputParser,这是一个专门用来处理模型输出内容的解析器。当模型输出的内容是字符串格式的时候,StrOutputParser能够直接返回模型输出的content字符串内容。
这使得用户无需进行复杂的数据解析操作,可以直接获取模型输出的内容字符串,从而变更方便地进行后续处理或使用,代码示例如下:
1 | from langchain_core.messages import SystemMessage |
Json解析器
当模型输出的内容是一个JSON格式时,LangChain也提供了相应的解析器JsonOutputParser。该解析器能够根据JSON结构的内容,将其转换为Python对应的字典格式的数据,使得用户能够更方便地处理和操作模型输出的结果。代码示例如下:
1 | # @Time: 2025/2/6 10:43 |
Pydantic解析器
LangChain还提供了对Pydantic模型的解析器:PydanticOutputParser
LangChain的Pydantic解析器可以将模型输出的内容解析为Pydantic模型所定义的数据结构。这使得用户可以更加方便的使用Pydantic的功能,例如数据验证、序列化和反序列化等,代码示例如下:
1 | # @Time: 2025/2/6 10:43 |
结构化输出解析器
LangChain提供了一种自定义解析方案,即使用schema结构。用户可以根据需要定义自己的schema,并使用LangChain的StructuredOutputParser类来解析符合该schema的数据。
这种方式让用户能够更灵活地处理各种类型的模型输出数据,而无需依赖特定的数据验证库或框架。StructuredOutputParser为用户提供了一种通用的解析方式,使他们能够简单地将模型输出的数据转换为符合自定义schema的数据对象。代码如下
1 | # @Time: 2025/2/6 10:43 |
OpenAI函数输出解析器
LangChain支持解析OpenAI提供的函数调用,并提供了以下四种形式来处理输出结果:
- JsonOutputFunctionsParser:生成JSON格式的结果
- JsonKeyOutputFunctionsParser:指定JSON中某个key对应的value
- PydanticOutputFunctionsParser:解析Pydantic模型的结构
- PydanticAttrOutputFunctionsParser:直接输出模型中某个参数的值
Json格式
JsonOutputFunctionsParser 和 JsonKeyOutputFunctionsParser(key_name=”ad”)
1 | # @Time: 2025/2/6 10:43 |
Pydantic模型
PydanticOutputFunctionsParser(pydantic_schema=Advertisement) 和 PydanticAttrOutputFunctionsParser(pydantic_schema=Advertisement, attr_name=”ads”)
1 | # @Time: 2025/2/6 10:43 |