dsh-openrouter-guardrails:按 OpenRouter guardrails 收窄模型选择器

前言

在 DeepSeek Harness(DSH)里走 OpenRouter 路由时,模型选择器默认展示内置目录中的全部对话模型(例如在 0.2.2-rc.1 里约 396 个)。若你的 API Key 受 OpenRouter guardrails 限制,只能使用其中少数几个,列表里仍会显示整本目录;选到不在白名单里的模型会在请求阶段收到 403。Claude Code、pi 等工具会只展示 Key 实际可用的模型,DSH 在讨论 deepseek-harness#12355 中也曾被问到同样的问题。下面介绍社区插件 dsh-openrouter-guardrails(维护者 EamonnLiu,目录分类 admin-security),它通过 OpenRouter 的 GET /api/v1/models/user 拉取当前 Key 在 guardrails、隐私与提供商偏好过滤后的模型列表,并写回 profile,使选择器与真实权限一致。

这是什么

dsh-openrouter-guardrails 是 DSH 的一个 Cordis 插件(package.json 版本 0.1.0,MIT 许可证)。它不改变你的 apiKeyEnv、baseURL、headers 等路由配置,只通过 DSH 的设置服务更新两类数据:

  • providers.openrouter.models:内置目录里已描述、且 Key 允许使用的模型,以 { id } 形式写入,继承目录中的协议等元数据(例如 OpenRouter 上的 Claude 仍保持 anthropic-messages)。
  • providers.openrouter-guardrails:对目录中尚未收录、但 Key 允许使用的新模型,单独声明一条 openai-completions 路由;选择器里分组显示为默认名 OpenRouter (new models)。当没有这类模型时,该路由会被移除。

每次写入前由 llm-pi-ai 校验;无法服务的写入会被整体拒绝,profile 保持原样。

安装前后对比

安装前 安装后
openrouter 列出内置全量目录 openrouter 列出目录中、且 Key 允许的模型
比内置目录更新的允许模型不会出现 它们出现在第二组 OpenRouter (new models)

环境与前置条件

  • DeepSeek Harness:>=0.2.2-rc.1 且 <0.3.0(见插件 engines.dsh)。
  • 已在 Settings → Models 中配置 OpenRouter 路由,并设置 API Key(例如 profile 中存在 providers.openrouter 且 apiKeyEnv: OPENROUTER_API_KEY)。
  • Node:>=22.19(插件开发与测试环境要求,随 DSH 插件运行时由宿主提供)。

插件以当前 DSH 进程权限运行;安装前建议在 GitHub 上查看源码与 MIT 许可证,确认行为符合你的安全策略。

安装与启用

先在 DSH 中配好 OpenRouter 路由与 Key,再安装插件。官方安装方式如下。

桌面端:Plugins 页面 → 从 github:EamonnLiu/dsh-openrouter-guardrails 安装。

CLI / Web profile:

dsh plugin --profile <profile> add github:EamonnLiu/dsh-openrouter-guardrails

插件加载后会在数秒内执行第一次同步,模型选择器会随之更新。

运行时机与请求行为

插件在以下情况会调用一次 /models/user(请求发往你所配置路由的 baseURL,例如区域端点 https://eu.openrouter.ai/api/v1 也会应用该区域过滤):

  1. 启动时,在 llm-pi-ai 加载完成前会短暂重试;
  2. 路由凭证(apiKeyEnv 对应环境变量)变更时;
  3. 每隔 6 小时定时刷新。

插件自身的写操作不会再次触发同步,因此不会形成请求循环。

可选配置

在 cordis.patch.yml 里插件条目(id: openrouter-guardrails)下可改以下字段(均为可选):

字段 默认 含义
provider openrouter 要收窄的 llm-pi-ai 路由
extraProvider openrouter-guardrails 本插件为「目录外新模型」占用的路由 id
extraDisplayName OpenRouter (new models) 该路由在选择器中的显示名
intervalHours 6 刷新间隔(小时)
timeoutMs 30000 /models/user 请求超时
startupGraceMs 30000 启动时等待 llm-pi-ai 的时长

若 OpenRouter 路由本身已设置 api,则所有允许模型都会落在该路由上,不会创建第二条 openrouter-guardrails 路由。

状态与排错

每次执行结果会写入 ~/.dsh/cache/openrouter-guardrails.json(或 $DSH_HOME/cache/…),包含原因与写入的模型 id,不包含 Key。常见 reason:

  • route-missing:未配置 providers.openrouter
  • no-key:未配置 apiKeyEnv 或环境变量未设置
  • unauthorized:OpenRouter 返回 401/403,未改 profile
  • fetch-failed:网络或非 2xx,未改 profile
  • empty-result:Key 下无可服务模型,未改 profile
  • model-overrides-present:路由同时有 modelOverrides 与 models 列表,llm-pi-ai 不允许
  • extra-route-conflict:extraProvider 与内置目录中的提供商 id 冲突
  • settings-write-failed:llm-pi-ai 拒绝写入,详见 detail

已知限制:若允许使用的模型全部不在内置目录中,openrouter 路由无法被收窄为空列表(空 models 在 llm-pi-ai 中表示「整本目录」);这些模型仍会出现在第二组路由下。

不要与 dsh-openrouter-sync-models 同时启用,二者都会写 providers.openrouter.models。

适用场景与注意

适合已在 OpenRouter 控制台或企业策略里为 Key 配置了 guardrails、希望 DSH 模型选择与 Claude Code / pi 行为一致的用户。不适合需要同步「全量 OpenRouter 目录」而非「Key 允许列表」的场景(那是另一类插件的职责)。

卸载时需先移除插件,再手动删除 providers.openrouter 下的 models 以及 providers.openrouter-guardrails 路由(Settings → Models 或编辑 cordis.patch.yml);插件无法区分卸载与热重载,因此不能自动清理。

链接

经过上面的步骤,DSH 在保留你原有 OpenRouter 路由配置的前提下,用 OpenRouter 官方过滤接口对齐模型列表,减少在选择器里点到 403 的情况。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye