## 需求 希望增加**模型开关**:在面板里对上游模型目录中的**每个模型**单独启用 / 禁用。被禁用的模型应当: 1. 从 `GET /v1/models` 返回列表中**隐藏**; 2. 对该模型的请求**直接拒绝**(不进入选号、不消耗账号额度),并返回明确的 OpenAI 兼容错误。 ## 现状(已核对:当前无此能力) 仓库中与「模型」相关的管控目前只有三类,**均为被动或只读,没有人工开关**: | 现有能力 | 位置 | 性质 | |---|---|---| | 模型级自动冷却 | `internal/pool/modelcooldown.go`、`internal/pool/modelview.go` | 上游 `429 code=6004` / 11102 触发的**被动避让**,非人工开关 | | 模型锁池视图 | 面板「账号池」下方「模型锁池」表、`GET /status` 的 `model_locks` | **只读**:展示哪些模型被锁、解锁倒计时,不可操作 | | 模型与档位查询 | 面板「模型与档位」视图 | **只读**信息(倍率 / 思考档 / 上下文 / 最大输出),支持筛选排序 | | 非对话模型过滤 | `internal/upstream/client.go` `nonChatModel()` | **代码硬编码**过滤,不可配置 | 具体核对结论: - `GET /v1/models`(`internal/server/handler.go:277` → `modelList()` `internal/server/handler.go:357`)是**纯动态透传**——上游目录给什么就返回什么(`cn:` / `global:` 前缀),无任何白名单 / 黑名单过滤; - `cmd/server/config.go` 全部配置段(`panel` / `logging` / `server` / `cooldown` / `schedule` / `global` / `upstream` / `features` / `prompt` / `upstash` / `pool` / `session_sticky`)中**没有任何 `models` 相关键**(`config.example.json` 同); - 全仓检索 `model_enabled` / `allow_models` / `disabled_models` / `模型开关` 等标识**零命中**; - 现有最近似粒度的开关是**账号级「禁用」**与 **realm 级 `global.enabled`**,都无法按模型细分。 ## 期望行为 1. **配置驱动**:新增 `models` 配置段(建议 `disabled_models`,**默认空数组 = 行为与现状完全一致**,对老配置零影响——符合仓库既有的「缺省不改变老行为」约定,参见 `config.go` 中 `CheckinEnabled` / `IncludeDisabledInTasks` 的注释); 2. **`/v1/models` 过滤**:被禁模型不出现在返回列表中(注意保持 `cn:` / `global:` 前缀协议与 `resolveModel` 对称); 3. **请求侧拦截**:命中禁用模型的请求在**选号前**直接拒绝,不消耗账号额度。`internal/server/handler.go:538` 的 `realm, bareModel := resolveModel(peek.Model)` 是唯一入口,适合作拦截点; 4. **面板可视化**:「模型与档位」视图目前是纯查询表,可在此为每行加一个开关列(或新增独立「模型管理」视图),直接读写上述配置; 5. **热生效**:建议复用 `internal/livecfg` 的不可变快照机制——`SanitizeFingerprints` / `RecordClientInfo` 就是现成先例(读路径深、热改需求强),避免要求重启进程。 ## 设计建议与注意点 - **推荐「黑名单(disabled)」而非「白名单(enabled)」**:模型目录是动态拉取的,上游随时新增模型;白名单语义会让新模型默认不可用,且老配置升级后行为翻转。黑名单默认空则天然向后兼容。 - **key 建议用「realm + 裸模型名」**:与 `ModelLockRow` / `modelCooldowns` 现有口径一致——同名模型在 `cn` 与 `global` 两域各自独立计数。 - **隐藏与拦截建议同时做**:仅从 `/v1/models` 隐藏,仍会让写死模型名的客户端继续消耗额度(这与 issue #102「能调用却不在列表」是同一类不一致,只是方向相反)。 - **错误响应建议 OpenAI 兼容**(如 `404 model_not_found`,或 `400` + 明确文案),与现有错误风格保持一致。 ## 使用场景 - 上游按 UA / 账号下发了一批自己用不到的模型(如 `gpt-6-luna` 等桌面端家族),不希望它们污染客户端模型选择器; - 某模型实测输出被静默钳制、或积分倍率偏高,想临时下线避免误用; - 多协议客户端只认固定几个模型,想收敛列表。 --- > 说明:以上现状均基于 `main` 分支当前代码核对(`config.example.json` 与各 `internal/` 包)。如已有相关计划或设计取舍,欢迎指正;如方向可行,我这边也可以尝试提 PR。
Activity
misakano7545 commentedon Oct 20, 2026
等价能力已经有了,形态是「黑名单」而不是「逐模型勾选」。
现状
models.hidden(面板「设置 → 模型黑名单」):cn:/global:前缀 → 只隐藏该域;GET /v1/models不列(modelList过滤);model_unavailable,不进选号、不消耗额度;也就是说你的三个诉求(列表隐藏 / 请求拒绝 / 明确错误)都满足了,差的只是 UI 形态:现在是一行逗号分隔的输入框,不是模型列表上的勾选框。
顺带
反向的需求(把客户端固定的模型名映射到真实模型)也做了:
models.aliases,比如"claude-opus-4=glm-5.2",出站/选号/账本用真实名,响应回显客户端原发名。上游 10-12 之后没再提交,27 个 PR 待 review;这些问题我在自己的 fork 里持续跟进并已修掉大半:https://github.com/misakano7545/workbuddy2api-panel 。交流群:https://t.me/wb2api
linguo2625469 commentedon Oct 21, 2026
已实现:#225(models.hidden 模型黑名单:/v1/models 过滤 + 点名请求 400 拒绝,热生效)。(本条处置由 AI 辅助完成。)