# Thinking内容处理重构总结 ## 重构目标 统一所有 `` 标签的处理逻辑,避免重复代码,确保 `DISPLAY_RESULT_THINKING` 参数在整个系统中的一致性控制。 ## 重构前的问题 ### 1. 重复的处理逻辑 在多个文件中都有 `_remove_thinking_content()` 函数的重复实现: - `agent/tools/sql_generation.py` - `agent/tools/summary_generation.py` - `citu_app.py` - `customllm/base_llm_chat.py` ### 2. 多重处理问题 某些场景下thinking内容被多次处理: - **ask() API**: `customllm/base_llm_chat.py:generate_summary()` 已经处理,但 `citu_app.py` 又重复处理 - **ask_agent() API**: `agent/tools/summary_generation.py` 处理后,`customllm/base_llm_chat.py:generate_summary()` 又处理一次 ### 3. 处理遗漏 `agent/tools/sql_generation.py` 中的解释性文本可能包含thinking内容,但没有被处理。 ## 重构方案 ### 核心原则 **统一在最底层处理** - 只在 `customllm/base_llm_chat.py` 中处理thinking内容,其他地方不再重复处理。 ### 架构合理性 - `customllm/base_llm_chat.py` 是所有LLM响应的**统一出口** - 无论是 `ask()` API 还是 `ask_agent()` API,最终都会调用到这里 - 在数据源头处理thinking内容,确保一致性 ## 具体修改内容 ### 1. 保留的处理逻辑 **`customllm/base_llm_chat.py`** - 统一处理中心: ```python # generate_sql() 方法中处理解释性文本 if not DISPLAY_RESULT_THINKING: explanation = self._remove_thinking_content(explanation) # generate_summary() 方法中处理摘要内容 if not display_thinking: summary = self._remove_thinking_content(summary) # chat_with_llm() 方法中处理聊天对话内容 if not DISPLAY_RESULT_THINKING: response = self._remove_thinking_content(response) # generate_question() 方法中处理问题生成内容 if not DISPLAY_RESULT_THINKING: response = self._remove_thinking_content(response) # generate_rewritten_question() 方法中处理问题合并内容 if not DISPLAY_RESULT_THINKING: rewritten_question = self._remove_thinking_content(rewritten_question) # generate_plotly_code() 方法中处理图表代码生成内容 if not DISPLAY_RESULT_THINKING: plotly_code = self._remove_thinking_content(plotly_code) ``` ### 2. 移除的重复代码 #### `agent/tools/sql_generation.py` - ❌ 移除 `_remove_thinking_content()` 函数定义 - ❌ 移除 `from app_config import DISPLAY_RESULT_THINKING` 导入 - ❌ 移除所有thinking内容处理逻辑 - ✅ 依赖 `customllm/base_llm_chat.py` 中的统一处理 #### `agent/tools/summary_generation.py` - ❌ 移除 `_process_thinking_content()` 函数 - ❌ 移除 `import app_config` 导入 - ❌ 移除thinking内容处理调用 - ✅ 依赖 `customllm/base_llm_chat.py:generate_summary()` 中的统一处理 #### `citu_app.py` - ❌ 移除 `_remove_thinking_content()` 函数定义 - ❌ 移除 `DISPLAY_RESULT_THINKING` 导入 - ❌ 移除所有thinking内容处理调用 - ✅ 直接使用已处理的结果 ## 调用链路分析 ### ask() API 调用链路 ``` citu_app.py:ask_full() → vn.ask() → customllm/base_llm_chat.py:ask() → customllm/base_llm_chat.py:generate_summary() # ✅ 在这里统一处理thinking → 返回到 citu_app.py # ✅ 使用已处理的结果 ``` ### ask_agent() API 调用链路 ``` citu_app.py:ask_agent() → agent/citu_agent.py:process_question() → agent/tools/summary_generation.py:generate_summary() # ✅ 不再处理thinking → 内部调用 vn.generate_summary() → customllm/base_llm_chat.py:generate_summary() # ✅ 在这里统一处理thinking → 返回到 agent 层 # ✅ 使用已处理的结果 → 最终返回到 citu_app.py ``` ### SQL生成解释性文本处理 ``` agent/tools/sql_generation.py:generate_sql() → vn.generate_sql() → customllm/base_llm_chat.py:generate_sql() # ✅ 在这里统一处理thinking → 保存到 vn.last_llm_explanation # ✅ 已处理的解释性文本 → 返回到 agent 层 # ✅ 使用已处理的结果 ``` ## 配置参数控制 ### DISPLAY_RESULT_THINKING 参数作用范围 当 `DISPLAY_RESULT_THINKING = False` 时,以下所有内容的thinking标签都会被自动移除: 1. **摘要生成**: `customllm/base_llm_chat.py:generate_summary()` 2. **SQL生成解释性文本**: `customllm/base_llm_chat.py:generate_sql()` 3. **聊天对话**: `customllm/base_llm_chat.py:chat_with_llm()` 4. **问题生成**: `customllm/base_llm_chat.py:generate_question()` 5. **问题合并**: `customllm/base_llm_chat.py:generate_rewritten_question()` 6. **图表代码生成**: `customllm/base_llm_chat.py:generate_plotly_code()` 7. **API返回结果**: 所有通过Vanna实例返回的内容 ## 测试验证 创建了测试脚本 `test_thinking_control.py` 来验证: 1. **thinking内容移除功能**: 测试各种thinking标签格式的正确移除 2. **配置集成**: 验证配置参数的正确导入和使用 3. **Vanna实例**: 验证实际Vanna实例的thinking处理功能 ## 优势总结 ### 1. 避免重复处理 - 消除了多重处理导致的潜在问题 - 减少了性能开销 ### 2. 统一控制点 - 只需要在一个地方维护thinking处理逻辑 - 配置参数的影响范围清晰明确 ### 3. 架构简化 - 移除了大量重复代码 - 降低了维护复杂性 ### 4. 一致性保证 - 所有thinking内容处理都遵循相同的逻辑 - 避免了不同处理方式导致的不一致问题 ## 后续维护 ### 新增LLM响应处理时 - 只需要在 `customllm/base_llm_chat.py` 中添加thinking处理 - 不需要在其他地方重复实现 ### 修改thinking处理逻辑时 - 只需要修改 `customllm/base_llm_chat.py` 中的 `_remove_thinking_content()` 方法 - 修改会自动影响所有使用场景 ### 配置参数调整时 - 只需要修改 `app_config.py` 中的 `DISPLAY_RESULT_THINKING` 值 - 所有相关功能会自动响应配置变化