自定义模型

通过 ~/.pi/agent/models.json 添加自定义 Provider 和模型(Ollama、vLLM、LM Studio、代理等)。

目录

最小示例

对于本地模型(Ollama、LM Studio、vLLM),每个模型只需要 id

{
  "providers": {
    "ollama": {
      "baseUrl": "http://localhost:11434/v1",
      "api": "openai-completions",
      "apiKey": "ollama",
      "models": [{ "id": "llama3.1:8b" }, { "id": "qwen2.5-coder:7b" }]
    }
  }
}

apiKey 是必需的,但 Ollama 会忽略它,所以任意值均可。

完整示例

需要特定值时可覆盖默认值:

{
  "providers": {
    "ollama": {
      "baseUrl": "http://localhost:11434/v1",
      "api": "openai-completions",
      "apiKey": "ollama",
      "models": [
        {
          "id": "llama3.1:8b",
          "name": "Llama 3.1 8B (Local)",
          "reasoning": false,
          "input": ["text"],
          "contextWindow": 128000,
          "maxTokens": 32000,
          "cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
        }
      ]
    }
  }
}

文件在每次打开 /model 时重新加载。可在会话期间编辑,无需重启。

支持的 API

API说明
openai-completionsOpenAI Chat Completions(兼容性最广)
openai-responsesOpenAI Responses API
anthropic-messagesAnthropic Messages API
google-generative-aiGoogle Generative AI

在 Provider 级别设置 api(作为所有模型的默认值),或在模型级别设置(每个模型覆盖)。

Provider 配置

字段说明
baseUrlAPI 端点 URL
apiAPI 类型(见上表)
apiKeyAPI 密钥(见值解析)
headers自定义请求头(见值解析)
authHeader设为 true 自动添加 Authorization: Bearer <apiKey>
models模型配置数组
modelOverrides应用于此 Provider 内置模型的 per-model 覆盖

值解析

apiKeyheaders 字段支持三种格式:

  • Shell 命令: "!command" 执行命令并使用 stdout 输出
    "apiKey": "!security find-generic-password -ws 'anthropic'"
    "apiKey": "!op read 'op://vault/item/credential'"
  • 环境变量: 使用指定变量的值
    "apiKey": "MY_API_KEY"
  • 字面值: 直接使用
    "apiKey": "sk-..."

自定义请求头

{
  "providers": {
    "custom-proxy": {
      "baseUrl": "https://proxy.example.com/v1",
      "apiKey": "MY_API_KEY",
      "api": "anthropic-messages",
      "headers": {
        "x-portkey-api-key": "PORTKEY_API_KEY",
        "x-secret": "!op read 'op://vault/item/secret'"
      },
      "models": [...]
    }
  }
}

模型配置

字段必需默认值说明
id--模型标识符(传递给 API)
nameid模型选择器中的显示名称
apiProvider 的 api覆盖 Provider 的 API 类型
reasoningfalse是否支持扩展思考
input["text"]输入类型:["text"]["text", "image"]
contextWindow128000上下文窗口大小(token)
maxTokens16384最大输出 token
cost全部为零{"input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0}(每百万 token)

覆盖内置 Provider

通过代理路由内置 Provider,无需重新定义模型:

{
  "providers": {
    "anthropic": {
      "baseUrl": "https://my-proxy.example.com/v1"
    }
  }
}

所有内置 Anthropic 模型保持可用。现有的 OAuth 或 API 密钥认证继续工作。

要将自定义模型合并到内置 Provider 中,包含 models 数组:

{
  "providers": {
    "anthropic": {
      "baseUrl": "https://my-proxy.example.com/v1",
      "apiKey": "ANTHROPIC_API_KEY",
      "api": "anthropic-messages",
      "models": [...]
    }
  }
}

合并语义:

  • 内置模型保留
  • 自定义模型按 id 在 Provider 内进行 upsert
  • 如果自定义模型 id 与内置模型 id 匹配,自定义模型替换该内置模型
  • 如果自定义模型 id 是新的,则与内置模型并列添加

Per-model 覆盖

使用 modelOverrides 自定义特定内置模型,而无需替换 Provider 的完整模型列表。

{
  "providers": {
    "openrouter": {
      "modelOverrides": {
        "anthropic/claude-sonnet-4": {
          "name": "Claude Sonnet 4 (Bedrock Route)",
          "compat": {
            "openRouterRouting": {
              "only": ["amazon-bedrock"]
            }
          }
        }
      }
    }
  }
}

modelOverrides 支持每个模型的以下字段:namereasoninginputcost(部分)、contextWindowmaxTokensheaderscompat

行为说明:

  • modelOverrides 应用于内置 Provider 模型
  • 未知的模型 ID 会被忽略
  • 可以将 Provider 级别的 baseUrl/headersmodelOverrides 结合使用
  • 如果同时为 Provider 定义了 models,自定义模型在内置覆盖之后合并。具有相同 id 的自定义模型将替换被覆盖的内置模型条目

OpenAI 兼容性

对于部分兼容 OpenAI 的 Provider,使用 compat 字段:

{
  "providers": {
    "local-llm": {
      "baseUrl": "http://localhost:8080/v1",
      "api": "openai-completions",
      "compat": {
        "supportsUsageInStreaming": false,
        "maxTokensField": "max_tokens"
      },
      "models": [...]
    }
  }
}
字段说明
supportsStoreProvider 是否支持 store 字段
supportsDeveloperRole使用 developer 还是 system 角色
supportsReasoningEffort是否支持 reasoning_effort 参数
supportsUsageInStreaming是否支持 stream_options: { include_usage: true }(默认:true
maxTokensField使用 max_completion_tokens 还是 max_tokens
openRouterRoutingOpenRouter 路由配置,传递给 OpenRouter 用于模型/Provider 选择
vercelGatewayRoutingVercel AI Gateway 路由配置,用于 Provider 选择(onlyorder

示例:

{
  "providers": {
    "openrouter": {
      "baseUrl": "https://openrouter.ai/api/v1",
      "apiKey": "OPENROUTER_API_KEY",
      "api": "openai-completions",
      "models": [
        {
          "id": "openrouter/anthropic/claude-3.5-sonnet",
          "name": "OpenRouter Claude 3.5 Sonnet",
          "compat": {
            "openRouterRouting": {
              "order": ["anthropic"],
              "fallbacks": ["openai"]
            }
          }
        }
      ]
    }
  }
}

Vercel AI Gateway 示例:

{
  "providers": {
    "vercel-ai-gateway": {
      "baseUrl": "https://ai-gateway.vercel.sh/v1",
      "apiKey": "AI_GATEWAY_API_KEY",
      "api": "openai-completions",
      "models": [
        {
          "id": "moonshotai/kimi-k2.5",
          "name": "Kimi K2.5 (Fireworks via Vercel)",
          "reasoning": true,
          "input": ["text", "image"],
          "cost": {
            "input": 0.6,
            "output": 3,
            "cacheRead": 0,
            "cacheWrite": 0
          },
          "contextWindow": 262144,
          "maxTokens": 262144,
          "compat": {
            "vercelGatewayRouting": {
              "only": ["fireworks", "novita"],
              "order": ["fireworks", "novita"]
            }
          }
        }
      ]
    }
  }
}