07 · Provider 与模型接入
本章说明 pi-web 如何发现文本对话模型、如何接入内置 provider 与自定义 OpenAI-compatible 网关,以及设置页下拉列表的数据来源与过滤机制。
范围边界(先读):本章讲的
models.json/ModelRegistry只管文本对话模型——即 agent 在会话里生成回复所用的 LLM。AIGC 图像工具(image_generation/image_edit)与视觉工具(image_vision)的模型不走ModelRegistry,而是各自模块级的路由表(run-image-tool.ts的ROUTES、openrouter-models.ts、以及image_vision经ctx.modelRegistry挑视觉模型)。在models.json里配了 provider,也管不到图像/视觉模型——那套接入见 11-aigc-and-vision-tools.md。
1. 模型来源:两类 provider
| 类型 | 凭证存放 | 典型 provider |
|---|---|---|
| 内置 provider | ~/.pi/agent/auth.json(由 pi 登录写入) | anthropic、openai、google 等 |
| 自定义 provider | ~/.pi/agent/models.json(手动编写) | NewAPI 网关、本地推理服务、DashScope 等 |
两类 provider 均由 pi SDK 的 ModelRegistry 统一管理。ModelRegistry.getAvailable() 只返回有凭证的模型——内置 provider 凭证来自 auth.json,自定义 provider 凭证内嵌在 models.json 的 apiKey 字段。
相关入口:packages/server/src/config/model-options.ts:listModelOptions
const authStorage = AuthStorage.create(join(agentDir, "auth.json"));
const registry = ModelRegistry.create(authStorage, join(agentDir, "models.json"));
const models = registry.getAvailable();2. 内置 provider 接入(auth.json)
登录一次,凭证即持久化,无需额外配置:
pi # 按提示完成 OAuth / API key 设置登录后 ~/.pi/agent/auth.json 由 pi SDK 维护;pi-web 在运行时读取,不需要再设置 env 变量。
若要在不同机器或容器里免交互注入凭证,也可通过 env 变量透传(相关变量见 06-configuration.md):
ANTHROPIC_API_KEY=sk-ant-... pnpm dev
OPENAI_API_KEY=sk-... pnpm devenv 变量与 auth.json 叠加生效,优先级以 pi SDK 内部逻辑为准。
3. 自定义 OpenAI-compatible 网关(models.json)
自定义 provider 必须写在 ~/.pi/agent/models.json,不能写在 auth.json。
agent 配置目录默认为
~/.pi/agent,可经 envPI_CODING_AGENT_DIR覆盖(见lib/app/config.ts:resolveAgentDir);覆盖后models.json须放到对应目录下。
3.1 最小配置
{
"providers": {
"my-gateway": {
"name": "My Gateway",
"baseUrl": "https://example.com/v1",
"apiKey": "sk-...",
"api": "openai-completions",
"models": [
{
"id": "some-model",
"name": "Some Model",
"input": ["text"],
"contextWindow": 131072,
"maxTokens": 16384,
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
}
]
}
}
}必填字段:
| 字段 | 说明 |
|---|---|
baseUrl | OpenAI-compatible 端点前缀(到 /v1,不含 /chat/completions) |
apiKey | 网关鉴权 token |
api | 接入协议标识;OpenAI-compatible 的 chat completions 网关填 "openai-completions"(可在 provider 级或单条 model 级指定) |
models | 至少一条模型描述;id 为调用时使用的模型名 |
可选字段(cost、contextWindow、maxTokens)建议填写,供 pi SDK 成本估算使用;不填时 SDK 会使用 0 或默认值。
3.2 多 provider 示例
{
"providers": {
"newapi": {
"name": "NewAPI 网关",
"baseUrl": "https://newapi.example.com/v1",
"apiKey": "sk-newapi-...",
"api": "openai-completions",
"models": [
{
"id": "gpt-4o",
"name": "GPT-4o (via NewAPI)",
"input": ["text", "image"],
"contextWindow": 128000,
"maxTokens": 16384,
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
}
]
},
"local-llm": {
"name": "本地 Ollama",
"baseUrl": "http://localhost:11434/v1",
"apiKey": "ollama",
"api": "openai-completions",
"models": [
{
"id": "llama3.2",
"name": "Llama 3.2",
"input": ["text"],
"contextWindow": 32768,
"maxTokens": 4096,
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
}
]
}
}
}3.3 阿里云百炼 Token Plan 对话 provider
Token Plan 文本对话是独立的 OpenAI-compatible provider,须与官方 DashScope 分开登记:
{
"providers": {
"dashscope-token-plan": {
"name": "DashScope Token Plan",
"baseUrl": "https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",
"apiKey": "$DASHSCOPE_TOKEN_PLAN_API_KEY",
"api": "openai-completions",
"models": [
{
"id": "qwen3.7-max",
"name": "Qwen3.7 Max",
"reasoning": false,
"input": ["text"],
"contextWindow": 131072,
"maxTokens": 16384,
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
}
]
}
}
}$DASHSCOPE_TOKEN_PLAN_API_KEY 由 pi SDK 按环境变量解析;该 key 不可替代
DASHSCOPE_API_KEY。若运行 aigc-canvas-agent,保持其 model 省略,设置
~/.pi/agent/settings.json 的 defaultProvider / defaultModel 为上述 provider/model,
即可沿示例默认模型路径运行。
3.4 校验配置是否生效
pi --list-models输出包含 my-gateway 下的模型即为配置成功。该命令与 pi-web 读取的是同一份 ModelRegistry 数据,是最直接的校验手段。
没看到自定义模型? 多半是配置写错位置或必填字段缺失——排查清单见 23-troubleshooting-faq.md · 4.1 自定义 provider 鉴权 401。
4. 设置页模型下拉:数据来源与过滤
4.1 端点
设置页的 provider/model 可搜索下拉由前端调用以下端点驱动:
GET /api/config/models响应格式:
{
"providers": ["anthropic", "openai", "my-gateway"],
"models": [
{ "provider": "anthropic", "id": "claude-opus-4-5", "name": "Claude Opus 4.5" },
{ "provider": "my-gateway", "id": "some-model", "name": "Some Model" }
]
}服务端在 packages/server/src/config/config-routes.ts 挂载该路由(路径 /config/models 必须排在 /config/:domain 之前以避免被当成未知域)。
数据取自 listModelOptions(agentDir)(packages/server/src/config/model-options.ts),即进程内调用 ModelRegistry.getAvailable()——只有已配置凭证的模型才出现在下拉中。
4.2 隐藏指定 provider
通过 env 变量 PI_WEB_HIDE_PROVIDERS 可从下拉中剔除不想暴露的 provider:
PI_WEB_HIDE_PROVIDERS=anthropic,openai pnpm dev过滤逻辑在 packages/server/src/config/model-options-filter.ts:33(excludeProviders),精确匹配 provider 名(大小写敏感),同时从 providers 名单和 models 列表中剔除。PI_WEB_HIDE_PROVIDERS 为空时不过滤(零拷贝快路径)。/config/models 路由侧的调用入口见 lib/app/pi-handler.ts:447(在 listModelOptions 接缝里读 env 后套 excludeProviders)。
会话内 get_available_models RPC(GET /sessions/:id/models)也应用同一开关——经姊妹函数 excludeProviderModels(model-options-filter.ts:49)剔除,调用点在 packages/server/src/http/routes/query-routes.ts:126,保证下拉与运行时可选集一致。
4.3 新会话默认选中哪个 provider/model
设置页的 provider/model 下拉初始选中值来自两个 env 变量:
| 变量 | 作用 |
|---|---|
PI_WEB_DEFAULT_PROVIDER | 新会话初始选中的 provider |
PI_WEB_DEFAULT_MODEL | 新会话初始选中的模型 id |
二者由 resolveConfig 读入(lib/app/config.ts:92-93),作为 settings 域的 defaultProvider / defaultModel 默认值下发给前端下拉。它们只影响初始选中项,不改变可选集——被选的 provider/model 仍须真实存在于 getAvailable() 返回的清单里,否则下拉回退到首个可用项。完整变量说明见 06-configuration.md。
5. 真实案例与常见坑
5.1 NewAPI 网关
NewAPI 是典型的 OpenAI-compatible 聚合网关,api 字段固定填 "openai-completions",baseUrl 填到 /v1 前缀即可(网关内部再路由到各上游):
{
"providers": {
"newapi": {
"name": "NewAPI",
"baseUrl": "https://your-newapi-host/v1",
"apiKey": "sk-...",
"api": "openai-completions",
"models": [ ... ]
}
}
}5.2 DashScope 的 key 与端点绑定坑
DashScope(阿里云百炼)的图像生成 key 与服务端点强绑定:拿错端点对应的 key 会直接 401。这一坑由 AIGC 图像工具的实测踩出,端点常量见 packages/tool-kit/src/aigc/tools/image-generation.ts:40。
- 图像 API 走原生 DashScope 协议(
input/parameters结构),不是 OpenAI-compatible 的/images端点。 - 同步图像端点路径为
/api/v1/services/aigc/multimodal-generation/generation(base 默认指向 token plan 域https://token-plan.cn-beijing.maas.aliyuncs.com/api/v1,经 envDASHSCOPE_TOKENPLAN_BASE_URL可配)。 - 错误现象:图像生成请求返回 401,错误信息可能包含”渠道不存在”或空 model 名。
原因:token plan key(DASHSCOPE_API_KEY)对官方域 dashscope.aliyuncs.com 无效,必须打 token plan 末端;反之,官方控制台的 MAAS token 打 token plan 端点同样会 401。
解决方案:
- 确认 key 与端点配对:token plan key 配 token plan base,官方 key 配官方域,不能混用。
- 自定义 provider(或 AIGC 工具的 env)的 base/end-point 必须与所用 key 对应的服务端点匹配。
- 文本对话与图像生成建议分两个 provider 条目,分别配置对应 key。
注意:AIGC 与视觉工具用的 key 不止
auth.json/models.json两条路径。NEWAPI_API_KEY、SUFY_API_KEY、DASHSCOPE_API_KEY、端点覆盖DASHSCOPE_TOKENPLAN_BASE_URL,以及视觉默认模型PI_WEB_VISION_MODEL(格式provider/modelId)都是 AIGC/视觉专用的 env 变量,由 tool-kit 运行时展开、随 spawn 环境注入,与本章的文本模型接入是两套独立体系。清单见 06-configuration.md,语义见 11-aigc-and-vision-tools.md。
端点与 key 的完整说明见 11-aigc-and-vision-tools.md;401 现象的排查步骤见 23-troubleshooting-faq.md · 4.1 自定义 provider 鉴权 401。
6. 完整接入步骤
-
确认 pi 已登录(内置 provider):
pi --list-models # 能看到 anthropic/openai 等内置模型即可 -
编写
~/.pi/agent/models.json(自定义 provider,参见第 3 节示例)。 -
校验模型出现在列表中:
pi --list-models # 自定义 provider 的模型应出现 -
启动 pi-web(开发模式):
pnpm dev # dev-all.mjs:Vite 前端 :5173 + API :3000(/api 代理到 3000) -
在设置页确认下拉:浏览器打开 <http://localhost:5173> → Settings → 模型下拉 → 可搜索到自定义 provider 下的模型。
-
(可选)隐藏不想暴露的 provider:
PI_WEB_HIDE_PROVIDERS=anthropic pnpm dev
任一步出错(401、模型不出现、下拉为空),优先对照 23-troubleshooting-faq.md · 4. Provider / 模型问题。
相关链接
- 06-configuration.md — 完整 env 变量表,含
PI_WEB_DEFAULT_PROVIDER/PI_WEB_DEFAULT_MODEL - 13-config-ui.md — 设置页 provider/model 可搜索下拉的前端实现
- 11-aigc-and-vision-tools.md — AIGC 图像工具,DashScope 端点与 key 的详细说明
- 24-http-api-reference.md —
GET /api/config/models端点完整 API 说明 - 23-troubleshooting-faq.md — Provider 鉴权 401、模型不出现等常见故障排查