Provider / Model
Provider 和 Model 定义了 AI 模型提供商和模型配置。
概述
OpenCode 支持多个 AI 提供商(如 Anthropic、OpenAI、Google 等),每个提供商可以提供多个模型。配置从 models.dev API 加载,也可以使用本地缓存。
定义位置
packages/opencode/src/provider/models.ts:13-77
Model 对象
表示单个 AI 模型的完整配置。
| 属性名 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 是 | 模型唯一标识符 |
name | string | 是 | 模型显示名称 |
family | string | 否 | 模型族(如 "claude-3.5") |
release_date | string | 是 | 发布日期(ISO 8601) |
attachment | boolean | 是 | 是否支持文件附件 |
reasoning | boolean | 是 | 是否支持推理 |
temperature | boolean | 是 | 是否支持温度参数 |
tool_call | boolean | 是 | 是否支持工具调用 |
interleaved | boolean | object | 否 | 支持交错内容(reasoning) |
cost | object | 否 | 定价信息 |
cost.input | number | - | 输入 Token 价格(每百万) |
cost.output | number | - | 输出 Token 价格(每百万) |
cost.cache_read | number | - | 缓存读取价格(每百万) |
cost.cache_write | number | - | 缓存写入价格(每百万) |
cost.context_over_200k | object | - | 超过 200K 上下文的定价 |
limit | object | 是 | 使用限制 |
limit.context | number | - | 上下文窗口大小(Token) |
limit.input | number | - | 最大输入 Token(可选) |
limit.output | number | - | 最大输出 Token |
modalities | object | 否 | 支持的模态 |
modalities.input | string[] | - | 输入模态列表 |
modalities.output | string[] | - | 输出模态列表 |
experimental | boolean | 否 | 是否为实验性功能 |
status | string | 否 | 状态:alpha/beta/deprecated |
options | Record<string, any> | 否 | 提供商特定选项 |
headers | Record<string, string> | 否 | 默认请求头 |
provider | object | 否 | 提供商信息 |
provider.npm | string | - | npm 包名 |
variants | Record<string, Record> | 否 | 模型变体配置 |
Provider 对象
表示 AI 提供商的配置。
| 属性名 | 类型 | 必填 | 说明 |
|---|---|---|---|
api | string | 否 | API 基础 URL |
name | string | 是 | 提供商名称 |
env | string[] | 是 | 需要的环境变量列表 |
id | string | 是 | 提供商唯一标识符 |
npm | string | 否 | npm 包名 |
models | Record<string, Model> | 是 | 提供的模型映射 |
TypeScript 类型定义
export type Model = {
id: string
name: string
family?: string
release_date: string
attachment: boolean
reasoning: boolean
temperature: boolean
tool_call: boolean
interleaved?:
| boolean
| {
field: "reasoning_content" | "reasoning_details"
}
cost?: {
input: number
output: number
cache_read?: number
cache_write?: number
context_over_200k?: {
input: number
output: number
cache_read?: number
cache_write?: number
}
}
limit: {
context: number
input?: number
output: number
}
modalities?: {
input: Array<"text" | "audio" | "image" | "video" | "pdf">
output: Array<"text" | "audio" | "image" | "video" | "pdf">
}
experimental?: boolean
status?: "alpha" | "beta" | "deprecated"
options?: Record<string, any>
headers?: Record<string, string>
provider?: {
npm: string
}
variants?: Record<string, Record<string, any>>
}
export type Provider = {
api?: string
name: string
env: string[]
id: string
npm?: string
models: Record<string, Model>
}
典型使用场景
1. 获取所有提供商
const providers = await ModelsDev.get()
for (const [providerId, provider] of Object.entries(providers)) {
console.log(`Provider: ${provider.name}`)
console.log(` Models: ${Object.keys(provider.models).length}`)
}
2. 获取特定提供商
const providers = await ModelsDev.get()
const anthropic = providers["anthropic"]
console.log(anthropic.name) // "Anthropic"
console.log(anthropic.models) // 模型映射
3. 查找模型
const providers = await ModelsDev.get()
const anthropic = providers["anthropic"]
const model = anthropic.models["claude-3-5-sonnet"]
console.log(model.name) // "Claude 3.5 Sonnet"
console.log(model.limit.context) // 200000
console.log(model.cost.input) // 3.0 (每百万 Token)
4. 计算成本
const model = anthropic.models["claude-3-5-sonnet"]
const costInfo = model.cost
const inputCost = (inputTokens / 1_000_000) * costInfo.input
const outputCost = (outputTokens / 1_000_000) * costInfo.output
const cacheCost = (cacheReadTokens / 1_000_000) * (costInfo.cache_read || 0)
const totalCost = inputCost + outputCost + cacheCost
5. 检查模型能力
const model = getModel("claude-3-5-sonnet")
if (model.reasoning) {
console.log("此模型支持推理")
}
if (model.attachment.tool_call) {
console.log("此模型支持文件输入")
}
if (model.tool_call) {
console.log("此模型支持工具调用")
}
6. 使用上下文超过 200K 的定价
const model = getModel("claude-3-5-sonnet")
const totalTokens = inputTokens + outputTokens + cacheTokens
const costInfo = totalTokens > 200_000 ? model.cost.context_over_200k : model.cost
const cost = calculateCost(costInfo, tokens)
7. 刷新模型列表
// 从 models.dev API 获取最新数据
await ModelsDev.refresh()
模型数据源
远程 API
默认从 https://models.dev/api.json 获取:
const json = await fetch("https://models.dev/api.json").then((x) => x.text())
return JSON.parse(json) as Record<string, Provider>
本地缓存
缓存到 ~/.opencode/cache/models.json:
const filepath = path.join(Global.Path.cache, "models.json")
// 读取缓存
const cached = await Bun.file(filepath)
.json()
.catch(() => {})
// 写入缓存
await Bun.write(filepath, await response.text())
内联数据
如果远程 API 失败,使用内联数据(通过 models-macro 生成)。
模型能力检查
Tool Call 支持
function supportsToolCall(model: Model): boolean {
return model.tool_call && model.attachment
}
Reasoning 支持
function supportsReasoning(model: Model): boolean {
return model.reasoning
}
模态支持
function supportsModality(model: Model, inputModality: string, outputModality: string): boolean {
if (!model.modalities) return false
return model.modalities.input.includes(inputModality) && model.modalities.output.includes(outputModality)
}
模型变体
某些模型支持变体,如不同的上下文窗口:
const model = providers["anthropic"].models["claude-3-5-sonnet"]
if (model.variants) {
console.log("Available variants:")
for (const [variantName, variantConfig] of Object.entries(model.variants)) {
console.log(` ${variantName}:`)
console.log(` Context: ${variantConfig.limit.context}`)
}
}
环境变量
Provider 可能需要以下环境变量:
| 提供商 | 环境变量示例 |
|---|---|
| Anthropic | ANTHROPIC_API_KEY |
| OpenAI | OPENAI_API_KEY |
GOOGLE_API_KEY | |
| Groq | GROQ_API_KEY |
| Together | TOGETHER_API_KEY |
模型状态
| 状态 | 说明 |
|---|---|
alpha | Alpha 测试版本 |
beta | Beta 测试版本 |
| (未设置) | 稳定版本 |
提供商示例
Anthropic
{
"name": "Anthropic",
"id": "anthropic",
"env": ["ANTHROPIC_API_KEY"],
"api": "https://api.anthropic.com",
"models": {
"claude-3-5-sonnet": {
"id": "claude-3-5-sonnet",
"name": "Claude 3.5 Sonnet",
"limit": {
"context": 200000,
"output": 8192
},
"cost": {
"input": 3.0,
"output": 15.0
}
}
}
}
OpenAI
{
"name": "OpenAI",
"id": "openai",
"env": ["OPENAI_API_KEY"],
"models": {
"gpt-4o": {
"id": "gpt-4o",
"name": "GPT-4o",
"limit": {
"context": 128000,
"output": 4096
}
}
}
}
定价示例
标准定价
{
"cost": {
"input": 3.0, // $3.00 每百万输入 Token
"output": 15.0, // $15.00 每百万输出 Token
"cache_read": 0.3, // $0.30 每百万缓存读取
"cache_write": 3.75 // $3.75 每百万缓存写入
}
}
超过 200K 上下文定价
{
"cost": {
"input": 3.0,
"output": 15.0
},
"context_over_200k": {
"input": 15.0, // 超过 200K 后输入价格提高
"output": 75.0, // 超过 200K 后输出价格提高
"cache_read": 1.5,
"cache_write": 18.75
}
}
变更历史
| 版本 | 变更内容 | 日期 |
|---|---|---|
| v1 | 初始 Model 架构 | - |
| v1.1 | 添加 context_over_200k 定价 | - |
| v1.2 | 添加 variants 支持 | - |
| v1.3 | 添加 modalities 支持 | - |