模型支持协议扩展参数,用于关闭思考模式

DeepSeek 现役的 v4 系列全部默认开启思考模式,没有单独的非思考型模型
可换;官方给的关闭方式是在请求里带 thinking={"type":"disabled"}。

ai_models 表早有 extra_json 字段但从未接线,这里接通:模型配置里的
JSON 对象会合并进每次调用的请求体,因此任何协议级参数都能在管理端
配置,不必改代码。合并不会覆盖 model/messages/max_tokens/temperature/
stream —— 预算和结构由代码掌握,重试逻辑才不会被配置绕过。
写入前校验 JSON,避免非法值存进 JSON 列后每次调用才报错。

线上模型已配置为关闭思考:同一会话下由 10133 ms / 1024 输出 tokens、
回复被截断,变为 669 ms / 10 tokens、回复完整。max_tokens 相应回调至 512。

管理端模型表单新增「协议参数」输入框(该目录尚未纳入版本库,仅已发布)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-09-04 11:19:17 +08:00
co-authored by Claude Opus 5
parent 812d8032e1
commit 151834caac
3 changed files with 116 additions and 9 deletions
+19 -2
View File
@@ -68,6 +68,10 @@ type aiModel struct {
IsDefault bool `json:"isDefault"`
APIKey string `json:"-"`
HasAPIKey bool `json:"hasApiKey"`
// Provider-specific request fields, merged into the call body. This is how a
// model that thinks by default is asked not to, without a code change:
// {"thinking":{"type":"disabled"}}.
Extra map[string]any `json:"extra,omitempty"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
}
@@ -169,6 +173,19 @@ func aiRequestMaxTokens(req aiChatRequest, model aiModel) int {
return 256
}
// aiWithExtra adds the model's configured protocol fields to a request body.
// It never overwrites what the caller set: the structural fields and the budget
// this code reasons about stay under this code's control.
func aiWithExtra(model aiModel, body map[string]any) map[string]any {
for key, value := range model.Extra {
if _, taken := body[key]; taken {
continue
}
body[key] = value
}
return body
}
// One retry, with enough room for the thinking plus a short answer, and a cap
// so a misconfigured model cannot bill an unbounded completion.
func aiRetryMaxTokens(current int) int {
@@ -242,13 +259,13 @@ func (p openAIProvider) Chat(ctx context.Context, req aiChatRequest) (aiChatResu
}
raw, err := aiPostJSON(ctx, p.client, aiEndpoint(p.base, "/chat/completions"),
map[string]string{"Authorization": "Bearer " + p.model.APIKey},
map[string]any{
aiWithExtra(p.model, map[string]any{
"model": p.model.ModelName,
"messages": messages,
"max_tokens": aiRequestMaxTokens(req, p.model),
"temperature": aiRequestTemperature(req, p.model),
"stream": false,
})
}))
if err != nil {
return aiChatResult{}, err
}