【零基础入门 LLM 开发 · Day 11】:ChatOpenAI vs init_chat_model——一行换供应商

【零基础入门 LLM 开发 · Day 11】:ChatOpenAI vs init_chat_model------一行换供应商

场景

Day 10 起我们的代码都是这么开头的:

python 复制代码
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model=..., api_key=..., base_url=...)

直接实例化,直观明了。但它有个隐形约束:类名焊死了供应商 ------ChatOpenAI 只会说"OpenAI 协议"这一种话。哪天想试 Claude、Gemini 或本地模型,每个文件都要改 import 和构造代码。

最近的练习文件换成了另一种写法:init_chat_model。这篇讲清两者区别,顺便把常见供应商的接入写法一次备齐。

姿势一:ChatOpenAI 直连

python 复制代码
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model=os.getenv("YUMC_MODEL_NAME"),
    api_key=os.getenv("YUMC_MODEL_API_KEY"),
    base_url=os.getenv("YUMC_MODEL_BASE_URL"),  # 指向任何 OpenAI 兼容端点
    temperature=0.7,
)
  • 优点 :类型明确,IDE 补全参数一个不落;装的包也最少(langchain-openai 一个就够);
  • 局限:只会 OpenAI 协议。对"兼容端点"来说这恰恰不是缺点(见下文),但要接原生 Anthropic / Google 接口就得换类、换包。

姿势二:init_chat_model 工厂

python 复制代码
from langchain.chat_models import init_chat_model

model = init_chat_model(
    model=os.getenv("YUMC_MODEL_NAME"),
    model_provider="openai",        # 决定实际造出哪个类
    temperature=0,
    api_key=os.getenv("YUMC_MODEL_API_KEY"),
    base_url=os.getenv("YUMC_MODEL_BASE_URL"),
)

model_provider 是工厂的图纸 :"openai" → 内部实例化 ChatOpenAI,"anthropic" → ChatAnthropic......其余参数原样透传给对应的类。换供应商 = 改一个字符串。

验证一下工厂没骗你:

python 复制代码
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
print(type(model))   # <class 'langchain_openai.chat_models.base.ChatOpenAI'>
ChatOpenAI 直连 init_chat_model 工厂
本质 具体类 按字符串选类的工厂函数
换供应商 改 import + 构造代码 只改 model_provider(或配置)
IDE 补全 好 一般(返回类型是动态的)
依赖 只需对应一家的包 用哪家就得装哪家的包
适用 教学/demo、只用一家 多模型切换、通用工具

不同供应商的写法(速查表)

路线 A:官方集成包 ------每家一个 model_provider 值 + 一个要单独安装的包:

供应商 model_provider 需要安装 model 示例
OpenAI openai langchain-openai gpt-4o-mini
Anthropic anthropic langchain-anthropic claude-sonnet-4-5
Google google_genai langchain-google-genai gemini-2.0-flash
DeepSeek deepseek langchain-deepseek deepseek-chat
Ollama(本地) ollama langchain-ollama qwen2.5(本地已 pull 的模型名)
python 复制代码
model = init_chat_model("claude-sonnet-4-5", model_provider="anthropic")
# api_key 从环境变量 ANTHROPIC_API_KEY 自动读取,也可以显式传

路线 B:OpenAI 兼容协议 ------很多国产服务不提供官方集成包,但都提供"OpenAI 兼容接口",统统走 model_provider="openai" + 自家 base_url:

服务 base_url
智谱 GLM https://open.bigmodel.cn/api/paas/v4
Kimi(月之暗面) https://api.moonshot.cn/v1
通义千问(兼容模式) https://dashscope.aliyuncs.com/compatible-mode/v1
DeepSeek 官方 https://api.deepseek.com
你自己的 .env YUMC_MODEL_BASE_URL(本系列一直在用的就是这种)
python 复制代码
model = init_chat_model(
    model="glm-5.3-flash",
    model_provider="openai",                      # 协议是 OpenAI 的
    base_url="https://open.bigmodel.cn/api/paas/v4",  # 但地址是智谱的
    api_key=os.getenv("ZHIPU_API_KEY"),
)

本系列的 .env(YUMC_MODEL_*)就是路线 B:协议标准、地址自选。所以代码从 Day 1 到今天几乎没变过。

小技巧:新版还支持冒号简写,一行连供应商带模型名一起写:

python 复制代码
model = init_chat_model("openai:gpt-4o-mini")

怎么选?

  • 教学阶段 / 确定只用 OpenAI 系 :ChatOpenAI 直连------直观、补全友好;
  • 想随时切换模型对比效果 / 做通用工具 :init_chat_model------把供应商选择变成一行配置;
  • 两者可以混用:核心代码面向 LangChain 的统一消息/工具接口编程,初始化交给工厂。

今日踩坑点

  1. 没装对应的集成包 :init_chat_model(model_provider="anthropic") 但没装 langchain-anthropic,报 ModuleNotFoundError------工厂是按需导入的,图纸认了、零件没货。
  2. 兼容端点漏了 base_url :以为传了 api_key 就行,请求直奔官方 api.openai.com,拿着智谱的 key 报 401。路线 B 的 base_url 是命根子。
  3. 参数拼写错误被"透传" :init_chat_model(..., temperatre=0) 不报"参数不存在",而是把未知参数转发给底层类,最后在 API 调用时才炸:TypeError: unexpected keyword argument 'temperatre'------报错位置离案发现场很远(Day 14 的 methond 同款坑)。参数拼错先查构造处。
  4. 换了供应商 ≠ 行为一致 :bind_tools、with_structured_output 各家支持度不同(Day 14 的 json_schema 假装支持问题就是典型)。切了供应商,这些能力要重新验证。

今日小练习

  1. 必做:把 Day 10 的 ChatOpenAI 换成 init_chat_model,跑通同样的对话,print(type(model)) 亲眼看看工厂造出了什么。
  2. 进阶:写一个 load_model() 函数------供应商、模型名、密钥全部从 .env 读取,实现"不改一行代码换供应商"。
  3. 思考:把 base_url 改成一个不存在的地址,和直接删掉 base_url,分别报什么错?为什么报错不一样?

明日预告

Day 12:LangChain 流式输出------比 Day 5 手动拼 delta 简单得多,一行 for 搞定。


附录:完整练习代码

langchainTest4-tools2.py 的初始化段(tools 系列练习文件统一用这种写法)

python 复制代码
import os
from dotenv import load_dotenv
from langchain.chat_models import init_chat_model

load_dotenv()
model = init_chat_model(
    model=os.getenv("YUMC_MODEL_NAME"),
    model_provider="openai",
    temperature=0,
    api_key=os.getenv("YUMC_MODEL_API_KEY"),
    base_url=os.getenv("YUMC_MODEL_BASE_URL"),
)

换供应商实战:只动 .env,代码零修改

python 复制代码
import os
from dotenv import load_dotenv
from langchain.chat_models import init_chat_model

load_dotenv()

# .env 里配什么就用什么:
#   YUMC_MODEL_NAME=glm-5.3-flash
#   YUMC_MODEL_API_KEY=你的密钥
#   YUMC_MODEL_BASE_URL=https://open.bigmodel.cn/api/paas/v4
# 想换 Kimi?改这三行配置即可,下面的代码原封不动。
model = init_chat_model(
    model=os.getenv("YUMC_MODEL_NAME"),
    model_provider="openai",                     # 兼容协议走 openai
    api_key=os.getenv("YUMC_MODEL_API_KEY"),
    base_url=os.getenv("YUMC_MODEL_BASE_URL"),
)

response = model.invoke("用一句话介绍你自己")
print(response.content)
相关推荐
deli0071 小时前
撒下 200 个种子点,平面为什么自己长成蜂窝?Voronoi 图实验室
前端
Wang's Blog1 小时前
Java 中间件之 RabbitMQ 快速入门: MQ 常见技术选型对比
java·中间件·java-rabbitmq
King禅1 小时前
JavaScript 调试实战指南:从 console.log 到 DevTools 深度运用
javascript
蜗牛互联网1 小时前
Java Agent 工具调用的 allowlist、参数校验与调用预算
java·开发语言·人工智能·后端·oracle
大文说跨境1 小时前
多账号环境隔离方案技术选型:指纹浏览器、VPS 与云手机的三种架构对比
java·开发语言·前端
咕白m6251 小时前
使用 C# 将 TIFF 转换为 PDF
前端·c#
全栈项目管理程序猿1 小时前
ArcGIS JS 基础教程(28):图层渲染顺序管理
前端·javascript
huakoh1 小时前
MCP 工具报错走哪条通道:三条探针的最小复现检查
前端
骉马代驾1 小时前
代驾系统长连接实战(二):心跳、断线重连与消息补偿的完整实现
java