从 OpenRouter 迁移

替换模型 ID,核对供应商偏好、回退与费用差异。

保留 OpenAI SDK,替换连接配置与模型 ID;切流量前逐项处理 OpenRouter 专有选项。

 client = OpenAI(
-    base_url="https://openrouter.ai/api/v1",
-    api_key=os.environ["OPENROUTER_API_KEY"],
+    base_url="https://api.deepraxis.ai/openai/v1",
+    api_key=os.environ["PRAXIS_API_KEY"],
 )
-model = "openai/gpt-4o"
+model = "deepseek-flash"

1. 准备

需要 Python 3.10+、uv 和一个 Praxis Key。在控制台 → API Keys创建 Key,将它安全注入当前终端的 PRAXIS_API_KEY 环境变量;不要把 Key 写进代码或日志。保留原服务的配置与 Key,供回滚使用。以下命令在 macOS / Linux 的 Bash 中执行。

test -n "${PRAXIS_API_KEY:-}"

期望:退出码 0;退出码 1 表示变量未设置,先设置再继续。

2. 替换模型 ID

OpenRouter 选择Praxis 选择
openai/gpt-4o先用 deepseek-flash 跑通;这是另一个模型,不是别名
vendor/model从 Praxis 目录复制完整 ID,不能假设去掉前缀就可用
带 :nitro 后缀的 ID选不带后缀的目录 ID;不支持该后缀
openrouter/auto明确选择一个模型,或配置 models 回退列表

期望:client.models.list() 包含选定 ID。回退列表中的每个 ID 都必须是有效的 Praxis ID,并支持你调用的操作。

行为差异

OpenRouter 选项迁移处理
provider.order、provider.only、provider.ignore仅自带上游 Key(BYOK)可用;使用平台凭据时移除,否则返回 400 provider_selection_not_allowed
provider.allow_fallbacks、provider.sort无效果;移除并重新评估选路假设
provider.data_collection、provider.zdr无效果;请求被接受不代表这些策略已执行
models支持模型回退列表;替换每个 ID 并检查响应中的 model
provider.require_parameters: true对工具参数与已声明的采样参数进行支持检查;要求未声明支持的参数时返回 400;不支持的采样参数默认忽略

参数检查范围是工具参数与已声明的采样参数,不是供应商任意功能。准确范围见 Chat Completions 字段支持。如果应用依赖被忽略选项所控制的数据策略,应继续使用原服务,直到单独确认所需策略。

Chat 的 usage.cost 是实付金额;Responses 和 Messages 目前不返回该字段。收到 X-Praxis-Generation-Id 时,可按 生成记录 API 用 GET /model/v1/generation?id=生成ID 查费用(记录可能延迟几秒)。若响应没有该头,去控制台 → 用量与费用查本次调用;不要把响应正文的 id 或 X-Request-Id 当成生成 ID,也不要将缺失费用当成零。

不支持的操作与替代

vendor/model、:nitro、openrouter/auto 都不是受支持的模型选择方式,也不会自动映射。缺失的 OpenAI 端点见不支持清单与替代。具体操作与字段以 API 参考 为准,不要假设 OpenRouter 扩展也适用于 Responses。

3. 验证一次请求

先跑通不带供应商偏好的最小 Chat 请求:

unset HTTP_PROXY HTTPS_PROXY ALL_PROXY http_proxy https_proxy all_proxy
uv run -q --no-project --with openai --with anthropic python - <<'PY'
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.deepraxis.ai/openai/v1",
    api_key=os.environ["PRAXIS_API_KEY"],
    timeout=90.0,
    max_retries=0,
)
models = client.models.list()
assert "deepseek-flash" in {m.id for m in models.data}
raw = client.chat.completions.with_raw_response.create(
    model="deepseek-flash",
    messages=[{"role": "user", "content": "Reply OK."}],
    max_tokens=1024,
)
reply = raw.parse()
text = reply.choices[0].message.content
print("HTTP", raw.status_code)
print("X-Request-Id:", raw.headers.get("x-request-id"))
print("X-Praxis-Generation-Id:", raw.headers.get("x-praxis-generation-id"))
print(text)
assert raw.status_code == 200 and text and text.strip()
assert raw.headers.get("x-request-id")
PY

期望:退出码 0,输出 HTTP 200、非空正文(通常为 OK.)和 X-Request-Id。断言同时检查模型存在与真实回复;不是只检查能否连接。保留请求 ID 便于排查,不要记录 Key。示例会产生少量调用费用。

然后逐个加回应用需要的选项。期望:每次请求成功且返回预期模型;被忽略的字段不能作为策略生效的证据。

失败分支

实测报错处理
400 provider_selection_not_allowed平台凭据移除供应商选择;或先配置 BYOK 再选择上游
404,包含 does not exist将带厂商前缀、后缀或自动选择器的 ID 换成目录 ID
404 model_protocol_not_offered选择提供该操作的模型

4. 回滚

恢复 https://openrouter.ai/api/v1、原 OPENROUTER_API_KEY、原模型 ID 和保存的 OpenRouter 选项。重启客户端后跑原冒烟请求。不要把 Praxis Key 发给 OpenRouter。

期望:原请求返回可用正文与预期模型。Praxis 上已产生的调用费用仍保留。

API 参考 → · Cookbook:OpenAI SDK →

导出

本页内容