LangChain 中的 Chat Model(聊天模型)
大型语言模型,也就是常说的LLM,本质上是机器学习模型,但在文本生成、翻译、摘要、问答这类语言任务上表现得相当出色。关键是它不需要针对每个具体场景都做专门的模型训练,这就让事情变得高效了很多。

现在我们接触到的LLM,大多是通过一个叫“聊天模型”的接口来使用的。它的逻辑很直观:输入是一系列消息,输出也是一条消息。
而且,最新一代的聊天模型能力已经远不止是聊天了——
- :不少主流聊天模型都自带一个工具调用API。这个API能让开发者做出一些丰富的应用,让AI可以和外部服务、API、数据库进行交互。它还能用来从非结构化的数据里提取结构化信息,干很多杂活。
工具调用
- :简单说,就是让聊天模型用一种固定的格式来回答,比如特定格式的JSON。这个功能在信息提取任务上非常实用。
结构化输出
- :现在大模型已经不只看文本了,还能处理图像、音频甚至视频。这就是常说多模态。不过,目前支持多模态输入的模型还算不上太多,而能输出多模态内容的就更少了。
多模态能力
LangChain 中聊天模型的特点
LangChain提供了一个统一接口,来处理不同服务商的聊天模型。更关键的是,它还额外给了一些功能,能帮我们监控、调试和优化用LLM做出来的应用。
- 集成了大量聊天模型服务商,比如:Anthropic、OpenAI、Ollama、Microsoft Azure、Google Vertex、Amazon Bedrock、Hugging Face、Cohere、Groq。具体支持哪些,可以去官网看:https://python.langchain.com/docs/integrations/chat/
- 同时支持LangChain自己的消息格式,也兼容OpenAI的格式。
- 提供了标准的工具调用API:把工具绑定到模型、访问模型发出的工具调用请求、再把工具结果返给模型,这些步骤都有统一的标准接口。
- 有专门的
with_structured_output方法,用来构造结构化输出。 - 对异步编程、高效批处理和流式API的支持也都很到位。
- 和LangSmith深度集成,可以用来监控和调试生产级的LLM应用。
- 还包括标准化的token用量管理、速率限制、缓存等实用功能。
顺便提一下,LangSmith是一个一站式平台,覆盖了LLM应用从开发到生产的所有阶段。我们可以用它来调试、协作、测试和监控应用。不过它并不是必选项。
集成
LangChain的聊天模型集成非常丰富,你可以自由选择不同服务商的模型。
具体分两类:
- :由LangChain和模型提供商自己维护。放在
官方模型
langchain-这样的包里,比如langchain-openai。 - :主要由社区贡献和支持,放在
社区模型
langchain-community包里。
LangChain给聊天模型命名有个规律:类名前面都会加上“Chat”,比如ChatOllama、ChatAnthropic、ChatOpenAI。受支持的模型列表可以看这里:https://python.langchain.com/docs/integrations/chat/
需要留个心眼:如果模型名称里没有“Chat”前缀,或者没有“LLM”后缀,那它通常是指那些不遵循聊天模型接口的旧模型。这种旧模型的接口很简单:输入字符串,输出字符串。
统一接口
LangChain的聊天模型都实现了BaseChatModel接口。因为BaseChatModel同时也继承了Runnable接口,所以聊天模型天然就支持标准的流式传输、异步编程和批量处理。
关键方法
聊天模型的核心操作都是围绕“消息”来展开的。几个常见的关键方法:
- :和聊天模型交互最主要的方法。输入消息列表,返回消息列表。
invoke
- :允许我们在模型生成过程中,以流式的方式拿到部分输出。
stream
- :把多个请求打包在一起发给模型,提高处理效率。
batch
- :把工具绑定到聊天模型,让它可以在执行时调用。
bind_tools
- :专为原生支持结构化输出的模型设计,是对invoke方法的一个封装。
with_structured_output
其他重要方法可以去BaseChatModel的官方API文档查找:https://python.langchain.com/api_reference/core/language_models/langchain_core.language_models.chat_models.BaseChatModel.html
输入和输出
现代LLM通过聊天模型接口交互,核心就是消息。每条消息通常会有一个角色标签,比如“system”、“human”、“assistant”,然后带一个或多个内容块,这些内容块可能是文本,也可能是图像、音频等。
LangChain支持两种消息格式:
- :LangChain自己的格式,默认使用。
LangChain消息格式
- :兼容OpenAI的格式。
OpenAI消息格式
聊天模型自带一组标准参数,用来控制它的行为:
- :你要用的模型名字或标识符,比如“gpt-3.5-turbo”或“gpt-4”。
model
- :控制输出的随机程度。值越高,输出越有创造性;值越低,输出越确定、越有条理。
temperature
- :限制回复的总token数。用来控制输出长度。
max_tokens
- :设置一个停止序列,让模型在生成到这个标记时停下来。
stop
- :如果请求因为网络超时、速率限制等问题失败,系统最多会尝试重新发送多少次。
max_retries
- :模型提供商的接口密钥。
api_key
- :API端点的基础URL。
base_url
- :用来控制请求频率,避免超出速率限制。是可选的。
rate_limiter
使用时有几个地方要小心:
- 标准参数只对暴露了这些功能的模型提供商有效。比如有的服务商不开放
max_tokens配置,那这个参数就用不了。 - 标准参数目前只在有独立集成包的模型里强制实施(比如
langchain-openai之类),在langchain-community里的模型并不强制。 ChatModel还接受一些集成本身特有的参数。想知道某个模型支持的所有参数,去看它的API文档就行了。
在后续文章中,我们会经常把“LLM”和“聊天模型”这两个词混着用。因为现在大多数现代LLM都是通过聊天模型接口暴露给用户的。不过,LangChain里确实还保留着老一代的LLM实现,它们不遵循聊天模型接口,而是用字符串输入、字符串输出的模式。这些模型一般不以“Chat”开头,而是可能以“LLM”结尾(比如OllamaLLM、AnthropicLLM)。但说实话,我们建议尽量别再用它们了。
上下文窗口
上下文窗口,就是聊天模型一次能处理的最大输入长度。虽然现在LLM的上下文窗口已经很大了,但这依然是一个开发时必须牢记的硬性限制。
输入超过窗口限制会怎样?模型可能处理不了整个输入,甚至直接报错。这对对话应用来说尤其关键,因为上下文窗口决定了模型在整场对话里能“记住”多少信息。开发者需要把输入控制在窗口范围内,才能保证对话连贯,不被限制卡住。输入大小以token为单位——token是模型处理内容时的基本单位。
Rate Limiter 速率限制
很多聊天模型提供商对单位时间内的请求数量有限制。一旦超出限制,我们就会收到一个速率限制的错误,然后得等一段时间才能继续发请求。
处理速率限制,有几种常见思路:
- :在初始化聊天模型时提供一个
主动间隔
rate_limiter参数,控制请求的发送频率。这个策略在给模型做性能基准测试时尤其有用。 - :如果已经收到速率限制错误,可以等一段时间再重试。每次失败都可以适当增加等待时间。
从错误中恢复
max_retries参数就是用来控制最大重试次数的。 - :如果一个模型被限了,就切换到另一个没有限制的模型上。
回退到其他模型
缓存
聊天模型API确实不便宜,所以不少人会想:能不能把以前的对话结果缓存起来?理论上,缓存能减少对服务商的请求,提高性能。但现实是,缓存聊天模型响应这件事非常复杂,需要小心对待。
关键是,如果把缓存建立在“精确匹配输入”的基础上,那在对话的前一两次交互之后,几乎不可能再命中缓存。想一想,有多少个对话会以完全相同的消息开始?连续三条完全相同的消息呢?概率微乎其微。
另一种做法是语义缓存——根据输入的含义而不是具体的文字来缓存。这个思路在某些场景下有效,但并不是银弹。原因在于,语义缓存在应用的关键路径上引入了一个额外的依赖(比如依赖嵌入模型把文本转成向量表示),而且也无法保证能100%准确捕捉输入的含义。
当然,在有些特定情况下,缓存确实有用。比如你有一个专门回答常见问题的聊天模型,把对高频问题的回复缓存起来,既能减轻模型服务商的负载,也能缩短用户的等待时间。
-
- 关于宇宙的好的网名有哪些
- 角色扮演 | 1
- 网名