mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-16 06:05:07 +08:00
feat: 新增 thinking 注入配置支持,扩展设置管理与前端交互
新增 promptcompat 和 OpenAI shared 层的 thinking 注入逻辑, 完善配置系统的编解码与校验,更新设置管理 API 与前端 UI。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -68,6 +68,8 @@ DS2API 当前的核心思路,不是把客户端传来的 `messages`、`tools`
|
||||
[internal/prompt/messages.go](../internal/prompt/messages.go)
|
||||
- prompt 可见 tool history XML:
|
||||
[internal/prompt/tool_calls.go](../internal/prompt/tool_calls.go)
|
||||
- 最新 user 思考格式注入:
|
||||
[internal/promptcompat/thinking_injection.go](../internal/promptcompat/thinking_injection.go)
|
||||
- completion payload:
|
||||
[internal/promptcompat/standard_request.go](../internal/promptcompat/standard_request.go)
|
||||
|
||||
@@ -101,6 +103,14 @@ DS2API 当前的核心思路,不是把客户端传来的 `messages`、`tools`
|
||||
|
||||
## 5. prompt 是怎么拼出来的
|
||||
|
||||
OpenAI Chat / Responses 在标准化后、history split / current input file 之前,会默认执行 `thinking_injection` 增强。它参考 DeepSeek V4 “把控制指令放在 user 消息末尾更稳定”的用法,在最新 user message 后追加 `【思维链格式要求】...`,要求模型在 `<think>` 内按分析、构思、工具调用、XML 工具格式回顾这几个阶段组织思考。该开关默认启用,可通过 `thinking_injection.enabled=false` 关闭。
|
||||
|
||||
这段增强属于 prompt 可见上下文:
|
||||
|
||||
- 普通请求会直接出现在最终 `prompt` 的最新 user block 末尾。
|
||||
- 如果触发 `HISTORY.txt`,它会保留在 live context 的最新 user turn 中。
|
||||
- 如果触发 current input file,它会进入完整上下文文件中。
|
||||
|
||||
### 5.1 角色标记
|
||||
|
||||
最终 prompt 使用 DeepSeek 风格角色标记:
|
||||
@@ -236,7 +246,12 @@ OpenAI 文件相关实现:
|
||||
|
||||
## 9. 多轮历史为什么不会一直完整内联在 prompt
|
||||
|
||||
history split 现在全局强制开启;旧配置中的 `history_split.enabled=false` 会被忽略。默认从第 2 个 user turn 起就可能触发,仍可通过 `history_split.trigger_after_turns` 调整触发阈值。
|
||||
兼容层提供两种拆分策略:
|
||||
|
||||
- `history_split` 是轮次拆分,默认关闭;开启后默认从第 2 个 user turn 起触发,可通过 `history_split.trigger_after_turns` 调整阈值。
|
||||
- `current_input_file` 是独立拆分,默认开启;它用于把“完整上下文”合并进隐藏上下文文件。当最新 user turn 的纯文本长度达到 `current_input_file.min_chars`(默认 `0`)时,兼容层会上传一个文件名为 `IGNORE.txt` 的上下文文件,并在 live prompt 中只保留一个中性的 user 消息要求模型直接回答最新请求,不再暴露文件名或要求模型读取本地文件。
|
||||
|
||||
两个策略互斥,最多只能启用一个。如果两个开关都关闭,请求会直接透传,不上传 `HISTORY.txt` 或 current input file。
|
||||
|
||||
相关实现:
|
||||
|
||||
@@ -244,8 +259,10 @@ history split 现在全局强制开启;旧配置中的 `history_split.enabled=
|
||||
[internal/config/store_accessors.go](../internal/config/store_accessors.go)
|
||||
- 历史拆分:
|
||||
[internal/httpapi/openai/history/history_split.go](../internal/httpapi/openai/history/history_split.go)
|
||||
- 当前输入转文件:
|
||||
[internal/httpapi/openai/history/current_input_file.go](../internal/httpapi/openai/history/current_input_file.go)
|
||||
|
||||
触发后行为:
|
||||
history split 触发后行为:
|
||||
|
||||
1. 旧历史消息被切出去。
|
||||
2. 旧历史会被重新序列化成一个文本文件。
|
||||
@@ -273,6 +290,20 @@ history split 现在全局强制开启;旧配置中的 `history_split.enabled=
|
||||
- `prompt` 里的 live context
|
||||
- `ref_file_ids` 指向的 history transcript file
|
||||
|
||||
当前输入转文件启用并触发时,不会同时启用 history split,也不会上传 `HISTORY.txt`。上传文件的真实文件名是 `IGNORE.txt`,文件内容是完整 `messages` 上下文;它仍会先用 OpenAI 消息标准化和 DeepSeek 角色标记序列化,再包进 `IGNORE` 文件边界里:
|
||||
|
||||
```text
|
||||
[uploaded filename]: IGNORE.txt
|
||||
[file content end]
|
||||
|
||||
<|begin▁of▁sentence|><|System|>...<|User|>...<|Assistant|>...<|Tool|>...<|User|>...
|
||||
|
||||
[file name]: IGNORE
|
||||
[file content begin]
|
||||
```
|
||||
|
||||
开启后,请求的 live prompt 不再直接内联完整上下文,而是保留一个 user role 的短提示,提示模型基于已提供上下文直接回答最新请求;上传后的 `file_id` 会进入 `ref_file_ids`。
|
||||
|
||||
## 10. 各协议入口的差异
|
||||
|
||||
### 10.1 OpenAI Chat / Responses
|
||||
|
||||
Reference in New Issue
Block a user