在构建基于大模型的应用时,模型列表往往是变动的。服务提供商会不定期上线新模型、下线旧模型,或者调整权限范围。如果客户端把可用模型写死在配置文件里,一旦服务端发生变化就会出现调用失败。Model List API 提供了一种标准化的查询方式,让程序能够在运行时获取当前账号或平台下真正可用的模型清单。

这个接口通常以 HTTP GET 请求的形式暴露,比如 /v1/models。调用方只需要在请求头中携带鉴权信息,就能拿到一个 JSON 响应。响应里最关键的字段是 data,它是一个数组,每个元素代表一个模型。不同服务商的字段命名可能有细微差异,但 id、object、created、owned_by 这些基础字段比较常见。理解这些字段的含义,是后续做过滤和路由的前提。
Model List API 的基本请求与响应结构
先来看一个最简单的 curl 调用。假设平台提供的模型列表端点是 https://api.ipipp.com/v1/models,鉴权方式为 Bearer Token,那么命令行可以这样写:
curl https://api.ipipp.com/v1/models \ -H "Authorization: Bearer $API_KEY"
这里把 api.ipipp.com 换成你自己的服务商域名,$API_KEY 替换成实际密钥。返回的响应大致如下:
{
"object": "list",
"data": [
{
"id": "gpt-4o",
"object": "model",
"created": 1715367049,
"owned_by": "openai"
},
{
"id": "gpt-4o-mini",
"object": "model",
"created": 1715367049,
"owned_by": "system"
}
]
}
从响应可以看出,data 数组中的每个对象都包含一个 id,它才是调用聊天补全或文本生成接口时需要传入的 model 参数值。很多开发者会误以为 owned_by 表示模型归属的组织,可以直接拿来做权限判断,但实际可用性还需要结合当前 API Key 的授权范围。之前遇到过一种情况:data 里列出了某个模型,但真正调用时却返回 404,原因是该模型只在部分地域开放,列表接口返回的是全局池。这个细节在后面的过滤策略中会再次提到。
如果用 Python 来调用,可以把响应解析成字典,提取模型 ID 列表。下面是一个基于 requests 库的最小实现:
import requests
API_KEY = "your_api_key"
BASE_URL = "https://api.ipipp.com/v1"
def get_model_ids():
headers = {
"Authorization": f"Bearer {API_KEY}"
}
resp = requests.get(f"{BASE_URL}/models", headers=headers, timeout=10)
resp.raise_for_status()
payload = resp.json()
return [item["id"] for item in payload.get("data", [])]
if __name__ == "__main__":
models = get_model_ids()
print(models)
这段代码把模型 ID 整理成了 Python 列表,方便后续在业务逻辑中判断某个模型是否存在。注意 raise_for_status() 会在 HTTP 状态码异常时抛出错误,实际项目中往往需要捕获并用日志记录,而不是让程序直接崩溃。
动态获取模型列表的工程实践与缓存策略
硬编码模型名的问题在早期阶段可能不明显,但当模型版本迭代加快,比如某个模型从 gpt-4o 升级到 gpt-4o-2024-11-20 时,把所有调用方配置都改一遍就会很麻烦。通过 Model List API 动态获取,可以把变化限制在服务端,客户端每次启动或定期刷新即可。不过每次都请求列表接口也会带来额外的延迟和配额消耗,所以需要引入缓存。
常见做法是把模型列表缓存在内存中,设置一个过期时间,比如十分钟。过期后再次请求远端,如果远端暂时不可用,就继续使用旧缓存,保证核心推理功能不中断。下面是一个带缓存的实现:
import time
import requests
class ModelCatalog:
def __init__(self, api_key, base_url="https://api.ipipp.com/v1", ttl=600):
self.api_key = api_key
self.base_url = base_url
self.ttl = ttl
self._cache = None
self._last_fetch = 0
def fetch_models(self, force=False):
now = time.time()
if not force and self._cache is not None and (now - self._last_fetch) < self.ttl:
return self._cache
headers = {"Authorization": f"Bearer {self.api_key}"}
try:
resp = requests.get(f"{self.base_url}/models", headers=headers, timeout=10)
resp.raise_for_status()
data = resp.json().get("data", [])
self._cache = [item["id"] for item in data]
self._last_fetch = now
except requests.RequestException as exc:
if self._cache is None:
raise RuntimeError("无法获取模型列表且无可用缓存") from exc
# 保留旧缓存,继续对外提供服务
return self._cache
catalog = ModelCatalog(api_key="your_api_key")
print(catalog.fetch_models())
这个类把远端请求和缓存逻辑封装在一起,调用方只需要关心 fetch_models() 返回什么。缓存时间 TTL 可以根据业务需要调整:如果模型上新频率高,可以设短一些,比如 60 秒;如果稳定,可以设到 3600 秒。关键点在于失败时不要覆盖已有的缓存数据,这样才能在服务商 API 抖动时保持应用可用。
还有一种更精细的做法是把缓存放到 Redis 等分布式存储中,让多个服务实例共享同一份模型列表,避免每个实例各自请求造成不必要的压力。缓存键可以设计成 model_list:all,值用 JSON 序列化后的列表。更新时可以后台定时任务刷新,或者采用惰性加载加短过期时间。无论是内存缓存还是分布式缓存,核心思想都一样:动态获取不是每次业务调用都去拉列表,而是有节奏地同步远端变化。
处理分页、过滤与权限限制
部分服务商的 Model List API 支持分页参数,例如 limit 和 after。如果不处理分页,可能只拿到前几十个模型,后面真正需要的模型却被漏掉。以某平台的返回格式为例,响应里可能带有一个 has_more 字段和 last_id 字段,调用方需要循环请求直到 has_more 为 false。下面给出一个通用的分页拉取函数:
import requests
def fetch_all_models(api_key, base_url="https://api.ipipp.com/v1"):
headers = {"Authorization": f"Bearer {api_key}"}
models = []
params = {"limit": 100}
url = f"{base_url}/models"
while True:
resp = requests.get(url, headers=headers, params=params, timeout=10)
resp.raise_for_status()
payload = resp.json()
data = payload.get("data", [])
models.extend(item["id"] for item in data)
if not payload.get("has_more"):
break
last_id = data[-1]["id"]
params["after"] = last_id
return models
这段代码通过 after 游标不断向后翻页,直到 has_more 不再是 true。不同服务商的分页参数名称可能不同,有的用 page 和 page_size,有的用 offset。接入前一定要先查看官方 API 文档,确认请求参数和响应字段。
除了分页,过滤同样重要。有些模型虽然出现在列表里,但可能因为账号套餐限制、地域限制或功能未开放而无法调用。如果直接展示给用户,容易造成误导。建议在获取列表后,根据本地规则或额外探测进行二次过滤。例如可以维护一个黑名单,把已知下线的模型 ID 过滤掉;或者根据模型 ID 的前缀判断其类型,只保留文本生成类模型,排除向量模型、微调模型等。过滤后的列表才是真正适合当前业务的可用模型集合。
权限限制方面,有些服务商在列表接口中并不会明确标出哪些模型对当前 API Key 可用,而是靠调用时返回的错误码来体现。一个更稳妥的思路是:启动时拉取列表,然后对候选模型逐个发送最小化的探测请求,比如调用一次 models/{id} 或极短 token 的补全请求。虽然会增加一些请求量,但能提前发现隐藏的权限问题。在流量较大的生产环境中,可以把探测结果缓存在配置中心,按小时更新。
跨平台适配与安全注意事项
如果应用需要同时接入多个大模型服务商,比如 OpenAI、Anthropic、国内的一些模型平台,Model List API 的响应结构和鉴权方式会有差异。可以设计一个适配层,为每个服务商实现统一的 get_models() 接口,屏蔽底层字段差异。例如将不同响应统一转换成如下标准结构:包含 id、provider、available 的列表。这样上层业务逻辑不用关心原始 JSON 长什么样。
安全方面,API Key 绝对不能硬编码在源码或客户端中,特别是移动端和前端应用。获取模型列表的请求需要由服务端代理完成,前端只拿过滤后的结果。即使在后端,也要把 API Key 放在环境变量或密钥管理服务中。下面是一个从环境变量读取密钥的示例:
import os
import requests
def fetch_models_from_env():
api_key = os.environ.get("MODEL_API_KEY")
if not api_key:
raise ValueError("环境变量 MODEL_API_KEY 未设置")
base_url = os.environ.get("MODEL_API_BASE", "https://api.ipipp.com/v1")
headers = {"Authorization": f"Bearer {api_key}"}
resp = requests.get(f"{base_url}/models", headers=headers, timeout=10)
resp.raise_for_status()
return [item["id"] for item in resp.json().get("data", [])]
这样既能避免密钥泄露,也方便在不同部署环境切换配置。另外,请求模型列表时建议设置合理的超时时间和重试次数,例如使用 requests.adapters.HTTPAdapter 挂载重试策略,或者用 tenacity 库做装饰器重试。网络抖动在跨国服务商中并不少见,一次失败不应影响整个应用启动。
最后提醒一点:Model List API 返回的模型 ID 可能带有日期后缀,例如 gpt-4o-2024-08-06。在记录日志、做监控或成本统计时,建议保留原始 ID,不要随意裁剪。否则后续排查问题时很难定位到具体模型版本。通过动态获取列表,你可以把这些版本变化同步到内部管理后台,让团队成员及时知道哪些模型已经可用。
Model List API动态获取模型列表模型列表接口修改时间:2026-09-29 11:18:42