18 自定义模型
18.1 自定义模型概述
通过 ~/.pi/agent/models.json 文件,可以添加自定义模型提供者和模型。这适用于:
- 本地模型(Ollama、LM Studio、vLLM)
- 自定义代理端点
- 企业内部部署的模型
- 任何 OpenAI/Anthropic/Google 兼容的 API
18.2 最小示例:Ollama
对于本地模型,每个模型只需要 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 是占位符(Ollama 忽略它)。但 Pi 要求有认证配置才会在 /model 中显示模型。对于无认证的本地服务器,保持一个 dummy 值即可。
18.2.1 OpenAI 兼容性调整
某些 OpenAI 兼容服务器不理解 developer 角色(用于推理模型)。对于这些提供者:
{
"providers": {
"ollama": {
"baseUrl": "http://localhost:11434/v1",
"api": "openai-completions",
"apiKey": "ollama",
"compat": {
"supportsDeveloperRole": false,
"supportsReasoningEffort": false
},
"models": [
{
"id": "gpt-oss:20b",
"reasoning": true
}
]
}
}
}compat 可设在提供者级别(应用于所有模型)或模型级别(覆盖特定模型)。
18.3 完整示例
当需要指定具体参数时:
{
"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
}
}
]
}
}
}models.json 每次打开 /model 时都会重新加载。你可以在会话中编辑文件,无需重启 Pi。
18.4 Google AI Studio 示例
使用 google-generative-ai API 和 baseUrl 添加 Google AI Studio 模型:
{
"providers": {
"my-google": {
"baseUrl": "https://generativelanguage.googleapis.com/v1beta",
"api": "google-generative-ai",
"apiKey": "$GEMINI_API_KEY",
"models": [
{
"id": "gemma-4-31b-it",
"name": "Gemma 4 31B",
"input": ["text", "image"],
"contextWindow": 262144,
"reasoning": true
}
]
}
}
}向 google-generative-ai API 类型添加自定义模型时,baseUrl 是必需的。
18.5 支持的 API
| API | 说明 |
|---|---|
openai-completions |
OpenAI Chat Completions(最通用) |
openai-responses |
OpenAI Responses API |
anthropic-messages |
Anthropic Messages API |
google-generative-ai |
Google Generative AI |
api 可设在提供者级别(所有模型的默认值)或模型级别(覆盖特定模型)。
18.6 提供者配置
| 字段 | 说明 |
|---|---|
baseUrl |
API 端点 URL |
api |
API 类型 |
apiKey |
可选 API 密钥配置 |
oauth |
动态 OAuth 提供者类型 |
headers |
自定义请求头 |
authHeader |
设为 true 自动添加 Authorization: Bearer <apiKey> |
models |
模型配置数组 |
modelOverrides |
对内置或扩展注册模型的逐模型覆盖 |
18.6.1 值解析(Value Resolution)
apiKey 和 headers 字段支持三种值形式:
Shell 命令(以 ! 开头):
{
"apiKey": "!security find-generic-password -ws 'anthropic'"
}{
"apiKey": "!op read 'op://vault/item/credential'"
}环境变量插值($ENV_VAR 或 ${ENV_VAR}):
{
"apiKey": "$MY_API_KEY"
}{
"apiKey": "${KEY_PREFIX}_${KEY_SUFFIX}"
}字面值:
{
"apiKey": "sk-..."
}转义规则:
| 语法 | 输出 |
|---|---|
$$ |
字面 $ |
$! |
字面 !(不触发命令执行) |
Shell 命令在请求时解析。Pi 不会为任意命令实现 TTL 或缓存逻辑。如果你的命令很慢或有限流,请用你自己的脚本包装所需的缓存/失败处理策略。
18.6.2 自定义 Headers
{
"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": []
}
}
}18.7 模型配置字段
| 字段 | 必需 | 默认值 | 说明 |
|---|---|---|---|
id |
✅ | — | 模型标识符(传递给 API) |
name |
❌ | id |
人类可读的模型标签 |
api |
❌ | 提供者的 api | 覆盖提供者的 API |
reasoning |
❌ | false |
是否支持扩展思考 |
thinkingLevelMap |
❌ | 省略 | 思考级别映射 |
input |
❌ | ["text"] |
输入类型:["text"] 或 ["text", "image"] |
contextWindow |
❌ | 128000 |
上下文窗口大小(token 数) |
maxTokens |
❌ | 16384 |
最大输出 token 数 |
cost |
❌ | 全零 | 每百万 token 费率 |
compat |
❌ | 提供者 compat | 兼容性覆盖 |
18.7.1 Cost Tiers(费用分层)
费用分层提供完整的替代费率,当总输入用量超过 inputTokensAbove 时应用于整个请求:
{
"cost": {
"input": 5,
"output": 30,
"cacheRead": 0.5,
"cacheWrite": 6.25,
"tiers": [
{
"inputTokensAbove": 272000,
"input": 10,
"output": 45,
"cacheRead": 1,
"cacheWrite": 12.5
}
]
}
}当多个 tier 匹配时,最高阈值的优先。
18.8 Thinking Level Map
使用 thinkingLevelMap 描述模型特定的思考控制。键是 Pi 的思考级别(off、minimal、low、medium、high、xhigh、max)。
值的三种状态:
| 值 | 含义 |
|---|---|
| 省略 | 标准级别通过 high 使用提供者默认映射;xhigh 和 max 不支持 |
string |
级别受支持,该值发送给提供者 |
null |
级别不受支持,被隐藏/跳过/钳制 |
示例:只支持 off、high 和 max 的模型:
{
"id": "deepseek-v4-pro",
"reasoning": true,
"thinkingLevelMap": {
"minimal": null,
"low": null,
"medium": null,
"high": "high",
"xhigh": null,
"max": "max"
}
}示例:思考无法关闭的模型:
{
"id": "always-thinking-model",
"reasoning": true,
"thinkingLevelMap": {
"off": null
}
}18.9 覆盖内置提供者
通过代理路由内置提供者,无需重定义模型:
{
"providers": {
"anthropic": {
"baseUrl": "https://my-proxy.example.com/v1"
}
}
}所有内置 Anthropic 模型保持可用。现有的 OAuth 或 API 密钥认证继续工作。
如需合并自定义模型到内置提供者,包含 models 数组:
{
"providers": {
"anthropic": {
"baseUrl": "https://my-proxy.example.com/v1",
"apiKey": "$ANTHROPIC_API_KEY",
"api": "anthropic-messages",
"models": [...]
}
}
}合并语义:
- 内置模型保留
- 自定义模型按 id 在提供者内 upsert
- 如果 id 与内置模型匹配,替换该内置模型
- 如果 id 是新的,添加到内置模型旁边
18.10 Per-model Overrides
使用 modelOverrides 自定义内置模型,而不替换提供者的完整模型列表:
{
"providers": {
"openrouter": {
"modelOverrides": {
"anthropic/claude-sonnet-4": {
"name": "Claude Sonnet 4 (Bedrock Route)",
"compat": {
"openRouterRouting": {
"only": ["amazon-bedrock"]
}
}
}
}
}
}
}modelOverrides 支持的字段:name、reasoning、thinkingLevelMap、input、cost(部分)、contextWindow、maxTokens、headers、compat。
18.10.1 扩展 OpenAI 上下文窗口
OpenAI GPT-5.6 Sol/Terra/Luna 默认使用 272K 上下文窗口(保持在短上下文定价层)。要使用 1.05M 上下文窗口:
{
"providers": {
"openai": {
"modelOverrides": {
"gpt-5.6-sol": {
"contextWindow": 1050000
}
}
}
}
}18.11 Anthropic Messages 兼容性
对于使用 api: "anthropic-messages" 的提供者或代理,使用 compat 控制 Anthropic 特定的请求兼容性:
{
"providers": {
"anthropic-proxy": {
"baseUrl": "https://proxy.example.com",
"api": "anthropic-messages",
"apiKey": "$ANTHROPIC_PROXY_KEY",
"compat": {
"supportsEagerToolInputStreaming": false,
"supportsLongCacheRetention": true,
"forceAdaptiveThinking": true,
"allowEmptySignature": true
},
"models": [
{
"id": "claude-opus-4-7",
"reasoning": true,
"input": ["text", "image"]
}
]
}
}
}| 字段 | 说明 | 默认值 |
|---|---|---|
supportsEagerToolInputStreaming |
是否接受 per-tool eager_input_streaming |
true |
supportsLongCacheRetention |
是否接受 Anthropic 长缓存保留 | true |
sendSessionAffinityHeaders |
是否发送 x-session-affinity |
自动检测 |
supportsCacheControlOnTools |
是否接受工具定义上的 cache_control |
true |
forceAdaptiveThinking |
是否发送 adaptive thinking | false |
allowEmptySignature |
是否重放空思考签名 | false |
supportsStrictTools |
是否接受严格 JSON-schema 工具定义 | false |
18.12 OpenAI 兼容性
对于部分 OpenAI 兼容的提供者,使用 compat 字段:
{
"providers": {
"my-openai-compat": {
"baseUrl": "https://api.example.com/v1",
"api": "openai-completions",
"compat": {
"supportsDeveloperRole": false,
"supportsReasoningEffort": true,
"maxTokensField": "max_tokens",
"requiresToolResultName": true,
"thinkingFormat": "qwen",
"cacheControlFormat": "anthropic"
},
"models": [...]
}
}
}大多数 OpenAI 兼容的提供者使用 openai-completions 即可工作。如果遇到问题,检查 compat 配置中的兼容性选项。