Model I/O - 模型调用

4、不同平台的模型调用实战

4.1 通过 CloseAI 代理调用 OpenAI

CloseAI 提供与 OpenAI 完全兼容的 API 接口,只需替换 base_url 。

.env 配置:

OPENAI_API_KEY=sk-你的CloseAI密钥
OPENAI_BASE_URL=https://api.closeai-asia.com/v1

1.代码示例:

from langchain_openai import ChatOpenAI
from dotenv import load_dotenv

load_dotenv()

# 无需手动传参,自动读取环境变量 OPENAI_API_KEY 和 OPENAI_BASE_URL
llm = ChatOpenAI(model="gpt-4o-mini")

response = llm.invoke("你好,介绍一下LangChain")
print(response.content)

要点:CloseAI 的接口和 OpenAI 完全一致,代码无需任何适配。 langchain-openai 包会自动识别 OPENAI_API_KEY 和 OPENAI_BASE_URL 这两个环境变量。

4.2 直连 DeepSeek

DeepSeek 的 API 兼容 OpenAI 接口格式,可以直接使用 ChatOpenAI 。

1.env 配置:

DEEPSEEK_API_KEY=sk-你的DeepSeek密钥
DEEPSEEK_BASE_URL=https://api.deepseek.com/v1

2.代码示例:

import os
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv

load_dotenv()

# DeepSeek 兼容 OpenAI 接口,直接用 ChatOpenAI 即可
llm = ChatOpenAI(
    model="deepseek-chat",    # DeepSeek-V3.2
    api_key=os.getenv("DEEPSEEK_API_KEY"),
    base_url=os.getenv("DEEPSEEK_BASE_URL"),
)

response = llm.invoke("用一句话解释什么是大语言模型")
print(response.content)

提示:DeepSeek 也提供了专用的 langchain-deepseek 包( uv add langchain-deepseek ),用法类似。但由于 DeepSeek 兼容 OpenAI 格式,直接用 ChatOpenAI 更简单,不需要多装一个包。

4.3 硅基流动调用开源模型

硅基流动聚合了 50+ 开源模型(DeepSeek、Qwen、GLM 等),同样兼容 OpenAI 接口格式。

.env 配置:

SILICONFLOW_API_KEY=sk-你的硅基流动密钥
SILICONFLOW_BASE_URL=https://api.siliconflow.cn/v1

1.代码示例:

import os
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv

load_dotenv()

# 硅基流动的模型名称格式:厂商/模型名
llm = ChatOpenAI(
    model="Qwen/Qwen3-8B",
    api_key=os.getenv("SILICONFLOW_API_KEY"),
    base_url=os.getenv("SILICONFLOW_BASE_URL"),
)
response = llm.invoke("什么是量子计算?")
print(response.content)

省钱技巧:硅基流动新用户送 2000 万 Token,部分模型(如 Qwen3-8B)完全免费,非常适合学习阶段使用。

4.4 接入不兼容 OpenAI 格式的平台

4.1 ~ 4.3 的平台都兼容 OpenAI 格式,所以直接用 ChatOpenAI 就能搞定。但 Anthropic(Claude)和Google(Gemini)有自己的 API 格式,需要用对应的专用类,或者用 2.4 节介绍的 init_chat_model统一管理:

from langchain.chat_models import init_chat_model
from dotenv import load_dotenv
import os
load_dotenv()

# 一个函数搞定所有提供商,通过 model_provider 参数区分
llm_openai = init_chat_model("gpt-5.4-nano-2026-03-17",
model_provider="openai", api_key=os.getenv("OPENAI_API_KEY"), base_url=os.getenv("OPENAI_BASE_URL"))
llm_claude = init_chat_model("claude-opus-4-7",
model_provider="anthropic", api_key=os.getenv("ANTHROPIC_API_KEY"), base_url=os.getenv("ANTHROPIC_BASE_URL"))
llm_gemini = init_chat_model("gemini-3.1-flash-lite-preview",
model_provider="google_genai", api_key=os.getenv("GEMINI_API_KEY"), base_url=os.getenv("GEMINI_BASE_URL"))

# 调用方式完全一致
for name, llm in [("OpenAI", llm_openai), ("Claude", llm_claude), ("Gemini", llm_gemini)]:
    response = llm.invoke("用一句话介绍你自己")
    print(f"{name}: {response.content}")

4.5 各平台接入速查表

平台 用哪个类 模型名称示例 环境变量
OpenAI(CloseAI代理) ChatOpenAI gpt-4o-mini OPENAI_API_KEY + OPENAI_BASE_URL
DeepSeek ChatOpenAI deepseek-chat DEEPSEEK_API_KEY + DEEPSEEK_BASE_URL
硅基流动 ChatOpenAI Qwen/Qwen3-8B SILICONFLOW_API_KEY + SILICONFLOW_BASE_URL
Anthropic ChatAnthropic claude-sonnet-4-20250514 ANTHROPIC_API_KEY
Google ChatGoogleGenerativeAI gemini-2.5-flash GOOGLE_API_KEY
Ollama (本地) chat0llama qwen3.5:4b 无需API Key

发现规律了吗? 凡是兼容 OpenAI 接口格式的平台(DeepSeek、硅基流动 等),都可以直接用ChatOpenAI ,只需改 base_url 和 api_key 。这就是标准化接口的威力。

5、调用本地模型

5.1 Ollama介绍

Ollama是一个开源项目,用于在本地运行大语言模型。

特点:

  • 支持多种开源模型(Llama、Qwen、DeepSeek等)
  • 一键下载和运行
  • 适合原型开发和本地测试
  • 提供OpenAI兼容的API

5.2 Ollama安装

Windows系统:

访问 https://ollama.com/download

下载并安装.exe文件

Linux系统:

curl -fsSL https://ollama.com/install.sh | sh 

5.3 模型下载和运行

# 下载并运行模型(首次使用会自动下载)
ollama run qwen3.5:4b
# 列出已下载的模型
ollama list
# 查看模型信息
ollama show qwen3.5:4b

5.4 使用LangChain调用Ollama

# uv add langchain-ollama
from langchain_ollama import ChatOllama

# 基本用法
ollama_llm = ChatOllama(model="qwen3.5:4b", base_url="http://localhost:11434")
response = ollama_llm.invoke("你好,介绍一下你自己")
print(response.content)

6、高级主题

6.1 多模态输入

支持图像、音频等多模态输入:

import base64
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage

llm = ChatOpenAI(model="gpt-4o")  # 需要使用支持视觉语言的模型(VLM模型:视觉语言模型 LLM 模型)
# 视觉模型:只能看懂图片的内容(OCR---yolox yolo-v8)
# 视觉语言模型:即能看懂图片内容 也能把看到的内容输出出来(VLM:各个平台都有各种各样的视觉模型)

# 读取图片
with open("image.jpg", "rb") as f:
    image_data = f.read()

message = HumanMessage(content=[
    {"type": "text", "text": "描述这张图片"},
    {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64, {base64.b64encode(image_data).decode()}}]

# type:image_url :既支持远程可以访问的图片地址 也支持本地图片(不能把本地图片路径丢给它 本地图片内容)
response = llm.invoke([message])
print(response.content)

1.扩展:Base64 编码

概念: 将二进制数据编码为可打印文本,常用于在文本协议(如 JSON)中传输二进制数据。

编码原理: 原始二进制每个字节可以是 0-255 中的任意值,其中很多是不可打印的控制字符,无法直接放进 JSON。Base64 将每 3 个字节(24 比特)切分为 4 组(每组 6 比特),每组对应 64 个可打印字符之一(A-Z、a-z、0-9、+、/)。如果末尾不足 3 个字节,用 = 填充。

import base64
# 编码
with open("image.png", "rb") as f:
    binary_data = f.read()

2.bytes: 原始二进制

base64_bytes = base64.b64encode(binary_data)    # bytes: Base64 编码后仍是 bytes 类型
base64_string = base64_bytes.decode("utf-8")    # str: 转成字符串
(Python 类型要求)
# .decode("utf-8") 的作用:
# Python 的 b64encode 返回 bytes 类型,但 JSON/f-string 需要 str 类型
# 因为 Base64 输出全是 ASCII 字符,所以这里只是做类型转换,不涉及字符编码解读
# 解码
binary_data = base64.b64decode(base64_string)

3.在 VLM 中的应用:

原始图片(二进制)
|
▼ base64.b64encode()
Base64 字符串:"iVBORw0KGgoAAAANSUhEUgAA..."
|
▼ 拼接为 Data URL
"data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAA..." 
| | | |
| | | | — 实际的图片数据
| | | — 编码方式
| — 媒体类型(告诉 API 这是 JPEG 图片)
— Data URL 协议前缀

6.2 速率限制

import time
from langchain_openai import ChatOpenAI
from langchain_core.rate_limiters import InMemoryRateLimiter

rate_limiter = InMemoryRateLimiter(
    requests_per_second=0.1,    # 10 秒才产生 1 个令牌    也即10 秒只能发1 个请求
    check_every_n_seconds=0.1,    # 每 0.1 秒检查一下“桶里有没有令牌可以用”
)

llm = ChatOpenAI(
    model="gpt-4o-mini",
    rate_limiter=rate_limiter,
)

def test_rate_limit(n=3):
    print("开始时间:", time.strftime("%X"))
    last = time.time()
    for i in range(n):
    t0 = time.time()
    resp = llm.invoke(f"第 {i} 次调用,简单回一句话就行")
    t1 = time.time()
    print(
    f"调用 {i} 完成,耗时 {t1 - t0:.2f}s, "
    f"距上次调用结束间隔 {t1 - last:.2f}s"
)
last = t1
test_rate_limit(3) 

6.3 Token使用追踪

from langchain_core.callbacks import get_usage_metadata_callback
llm = ChatOpenAI(model="gpt-4o-mini")

with get_usage_metadata_callback() as cb:
    llm.invoke("你好")
    llm.invoke("再见")

print(cb.usage_metadata)
    # {
    # 'input_tokens': 总输入token数,
    # 'output_tokens': 总输出token数,
    # 'total_tokens': 总token数
    # }

6.4 模型配置文件

查看模型的能力和限制:

llm = ChatOpenAI(model="gpt-4o")
print(llm.profile)
# {
#    'max_input_tokens': 128000,
#    'image_inputs': True,
#    'tool_calling': True,
#    'structured_output': True,
#    ...
# } 

6.5 提示词缓存(Prompt Caching)

6.5.1 什么是提示词缓存?

当你反复用同一段很长的系统提示词(System Prompt)调用模型时,模型每次都要重新"读"这段提示词,消耗时间和 token 费用。提示词缓存让模型服务商在服务器端缓存这段已处理的提示词,后续调用直接复用,跳过重复计算。

第1次调用:
[系统提示词 3000字] + [用户问题] → 模型处理全部内容 → $ 全价计费
第2次调用(缓存命中):
[系统提示词 3000字 ← 已缓存,跳过] + [用户问题] → 模型只处理新内容 → $ 大幅省钱

关键认知:这里的"缓存"发生在模型服务商的服务器上,不是你本地硬盘上的某个文件。你的项目目录里不会多出 cache.sqlite 之类的东西。

6.5.2 不同平台的缓存机制

平台 缓存方式 你需要做什么 省多少
OpenAI 全自动 什么都不用做,OpenAI 自动识别相同前缀并缓存 缓存命中的 token 费用减半
Anthropic 显式标记 用中间件告诉 API "这段可以缓存" 缓存命中的 token 费用降低 90%
1.OpenAI — 自动缓存(零配置)
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
# 不需要任何额外配置
# OpenAI 会自动识别:如果连续多次请求的前缀(如系统提示词)相同,
# 服务器会复用已计算的 KV cache,减少延迟和费用
response = llm.invoke("你好")

你在代码层面看不到"缓存存在哪"或"命中率多少",只能通过费用账单感知到缓存生效了。

2.Anthropic — 显式缓存(需要中间件)
from langchain_anthropic import ChatAnthropic, AnthropicPromptCachingMiddleware

llm = ChatAnthropic(
    model="claude-sonnet-4-20250514",
    # 中间件会自动把长的系统提示词标记为"可缓存"
    middleware=[AnthropicPromptCachingMiddleware()]
)

# 第1次调用:全价(缓存写入)
# 第2次及之后:缓存命中,token 费用降低 90%
response = llm.invoke("你好")

AnthropicPromptCachingMiddleware 的作用是:按照 Anthropic 的 API 规范,将系统提示词等长文本片段包装成带 cache_control 标记的请求,告诉 Anthropic 服务器"这段内容可以缓存"。缓存的存储和命中完全由 Anthropic 服务端负责,LangChain 只负责标记。

6.5.4 提示词缓存 vs 本地缓存

这是两个完全不同的东西,不要混淆:

维度 提示词缓存 (Prompt Caching) 本地缓存 (LLM Cache)
缓存位置 模型服务商的服务器 你本地的内存/磁盘/Redis
缓存什么效果 已计算的提示词中间状态 (KV cache)减少 token 费用和延迟 完整的"问题→回答"键值对相同问题完全不调 API,零费用
你能控制吗 不能 完全由你控制
本节讲的 √ 是这个 ✕ 不是这个

如果你需要"相同问题直接从本地返回、完全不打 API"的缓存,那是 LangChain 的 LLMCache 机制(如 InMemoryCache 、 SQLiteCache ),属于另一个话题。

7、小结

本节介绍了Model I/O中的模型调用部分:

7.1 已学内容

主题 核心要点
Model I/O概述 Prompts → Models → Output Parsers 三部分
初始化模型 init_chat_model 或特定包的类
消息类型 SystemMessage, HumanMessage, AlMessage, ToolMessage
调用方式 invoke, ainvoke, stream, batch
平台接入 CloseAI代理、DeepSeek、硅基流动、init_chat_model统一切换
本地模型 Ollama等框架
高级特性 多模态、速率限制、Token追踪

7.2 统一接口优势

# 同样的代码,只需更换初始化方式即可切换模型
llm = init_chat_model("gpt-4o-mini", model_provider="openai")
llm = init_chat_model("claude-sonnet-4-6", model_provider="anthropic")
llm = init_chat_model("gemini-2.5-flash", model_provider="google")
llm = ChatOllama(model="qwen2.5:7b")  # 本地模型
# 调用方式完全一致
response = llm.invoke("你好")

7.3 参考资料

LangChain Models 官方文档

LangChain Messages 文档

Ollama 官网

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐