53 lines
3.2 KiB
Markdown
53 lines
3.2 KiB
Markdown
---
|
||
feature: "thinking"
|
||
scope: "Agent 思考功能(基于 GuidelineMiddleware 的前置辅助推理),在主回答前生成一次 <think> 内容"
|
||
updated_at: "2026-06-01"
|
||
status: active
|
||
---
|
||
|
||
# Thinking(思考功能)
|
||
|
||
## 当前状态
|
||
思考功能通过自定义的 **`GuidelineMiddleware`** 实现:在主 agent 执行前,先用业务指引 prompt 调一次模型做"思考",
|
||
把结果包成 `<think>...</think>` 标签并打上 `message_tag: "THINK"` 元数据,供前端识别/折叠展示。
|
||
|
||
> 重要:这是"主请求前的一次辅助请求",**不是** Qwen 模型内置的 reasoning/extended-thinking 模式,因此与具体模型无关,任何 LLM 都能用。对标 OpenAI o1 / Claude thinking,但实现更轻。
|
||
|
||
## 配置开关
|
||
| 层级 | 字段 | 默认 | 位置 |
|
||
|------|------|------|------|
|
||
| Agent 配置 | `enable_thinking: bool` | `False` | `agent/agent_config.py:26` |
|
||
| API 请求 | `enable_thinking: bool` | `False` | `utils/api_models.py:54` |
|
||
|
||
开启路径:V1 走请求体 `enable_thinking`,V2 走 bot 配置 `enable_thinking`。
|
||
中间件注册在 `agent/deep_assistant.py:294`:`if config.enable_thinking: middleware.append(GuidelineMiddleware(...))`。
|
||
|
||
## 核心文件
|
||
- `agent/guideline_middleware.py` — 思考主逻辑。`get_guideline_prompt`(行 53+)组装指引 prompt;`before_agent`/`abefore_agent` 调模型生成思考,包 `<think>` 标签并标 `THINK`(行 120-124 / 146-149)。
|
||
- `agent/deep_assistant.py:294-295` — 按 `enable_thinking` 注册中间件。
|
||
|
||
## 数据流
|
||
1. `before_agent` 加载指引(system prompt 中的 Guidelines 块)。
|
||
2. 从 system prompt 提取 guidelines / tool_description / scenarios / terms_list。
|
||
3. 组装 `guideline_prompt` = 业务规则 + 聊天历史 + **记忆上下文** + 工具描述 + 场景 + 术语分析。
|
||
4. 调模型一次:`SystemMessage(guideline_prompt)` + 用户最后一条消息 → 得到思考内容。
|
||
5. 内容包成 `<think>...</think>`,`additional_kwargs["message_tag"] = "THINK"`。
|
||
6. 追加一条空 `HumanMessage`(兼容"最后必须是 user 消息"的模型)。
|
||
7. 主 agent 继续执行,产出正式回答。
|
||
|
||
## 与记忆功能的耦合
|
||
`guideline_middleware.py:63` 读取 `config._mem0_context`(由 [[../memory/MEMORY|memory]] 的 `before_agent` 写入)。
|
||
即:思考阶段会把已召回的长期记忆纳入指引 prompt,从而基于记忆做更好的分析。
|
||
**顺序依赖**:memory 中间件需在 thinking 之前执行,`_mem0_context` 才有值。
|
||
|
||
## Gotchas(开发必读)
|
||
- **思考是非流式的**:思考内容在 `before_agent` 一次性完整生成,只有正式回答才流式输出。前端靠 `<think>` 标签 + `message_tag:"THINK"` 折叠展示。
|
||
- **额外一次模型调用**:每次开启都多打一次 LLM 请求,增加延迟和成本,按场景权衡。
|
||
- **不是模型原生 reasoning**:别误以为依赖 `enable_thinking` 透传给 Qwen,它是中间件层的自定义实现。
|
||
- **空 HumanMessage 收尾**:思考消息后会补一条空 user 消息,改消息列表处理逻辑时勿误删。
|
||
- **依赖记忆上下文顺序**:若调整中间件注册顺序,确认 memory 仍在 thinking 之前。
|
||
|
||
## 索引
|
||
- 设计决策:`decisions/`
|
||
- 变更历史:`changelog/`
|