qwen_agent/.features/thinking/MEMORY.md
2026-06-01 11:51:21 +08:00

53 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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/`