thinking_content_refactor_summary.md 5.8 KB

Thinking内容处理重构总结

重构目标

统一所有 <thinking></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 - 统一处理中心:

# 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
  • 所有相关功能会自动响应配置变化