From 7c8758d7fabcb199b32e5bc874fc32497060d3d9 Mon Sep 17 00:00:00 2001 From: zhuyongxin Date: Thu, 25 Jun 2026 17:24:59 +0800 Subject: [PATCH] =?UTF-8?q?refactor(observability):=20=E7=AE=80=E5=8C=96?= =?UTF-8?q?=20ChatService=20=E6=97=A5=E5=BF=97=EF=BC=8C=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E4=B8=8E=20Hook=20=E9=87=8D=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 改动内容 ### 修改前:重复的日志 ```java // ChatService.executeChat() logger.info("========== Agent 执行开始 =========="); logger.info("📝 用户问题: {}", question); logger.info("🚀 执行 ReactAgent.call() - 自动处理工具调用"); // ... Agent 执行 ... logger.info("========== Agent 执行完成 =========="); logger.info("⏱️ 执行耗时: {} ms", duration); logger.info("📤 最终输出内容:"); // 打印完整答案 ``` **问题**: - 与 `AgentLoggingHook` 的日志重复 - 日志过于冗长 - Hook 已经覆盖了 Agent 的思考过程 --- ### 修改后:精简的日志 ```java // ChatService.executeChat() - 只保留最外层框架 logger.info("========================================"); logger.info("📝 用户问题: {}", question); // ... Agent 执行(Hook 负责内部日志)... logger.info("⏱️ 总耗时: {} ms", duration); logger.info("📏 输出长度: {} 字符", answer.length()); logger.info("========================================"); ``` **优势**: - 职责清晰:ChatService 只记录最外层信息 - 避免重复:思考过程由 Hook 负责 - 更简洁:减少噪音日志 --- ## 日志分层 | 层级 | 负责类 | 职责 | |------|--------|------| | **外层框架** | `ChatService` | 用户问题、总耗时、输出长度 | | **思考过程** | `AgentLoggingHook` | 每轮思考、模型决策、消息流转 | | **工具执行** | `LookupKnowledgeTool` | L0/L1 检索、工具参数/返回 | --- ## 日志输出对比 ### 修改前(重复冗长) ``` ======================================== ========== Agent 执行开始 ========== ← ChatService ======================================== 📝 用户问题: 支付为什么会失败? ← ChatService ---------------------------------------- 🚀 执行 ReactAgent.call() ← ChatService *** [Agent 思考] 第 1 轮思考开始 ← Hook ... *** [Agent 思考] 第 1 轮思考完成 ← Hook >>> [工具调用] lookup_knowledge ← Tool ... <<< [工具返回] lookup_knowledge ← Tool *** [Agent 思考] 第 2 轮思考开始 ← Hook ... *** [Agent 思考] 第 2 轮思考完成 ← Hook ======================================== ========== Agent 执行完成 ========== ← ChatService (重复) ======================================== ⏱️ 执行耗时: 1523 ms ← ChatService 📤 最终输出内容: ← ChatService 根据知识库的记录...(完整答案) ← ChatService (太长) ======================================== ``` --- ### 修改后(清晰简洁) ``` ======================================== 📝 用户问题: 支付为什么会失败? ← ChatService (简洁) *** [Agent 思考] 第 1 轮思考开始 ← Hook ... *** [Agent 思考] 第 1 轮思考完成 ← Hook >>> [工具调用] lookup_knowledge ← Tool ... <<< [工具返回] lookup_knowledge ← Tool *** [Agent 思考] 第 2 轮思考开始 ← Hook ... *** [Agent 思考] 第 2 轮思考完成 ← Hook *** [Agent 思考] 这是最终答案 ← Hook (已说明) ⏱️ 总耗时: 1523 ms ← ChatService (简洁) 📏 输出长度: 456 字符 ← ChatService (摘要) ======================================== ``` **改进**: - ✅ 去掉重复的"开始/完成"标记 - ✅ 不再打印完整答案(通过 HTTP 响应已返回) - ✅ Hook 已说明"这是最终答案" - ✅ 日志更紧凑,信噪比更高 --- ## 设计原则 ### 1. 单一职责 - **ChatService**:顶层编排,只记录执行框架 - **Hook**:Agent 内部状态,记录思考过程 - **Tool**:工具执行细节,记录检索过程 ### 2. 避免重复 - 不在多处打印相同信息 - Hook 已说明"最终答案",ChatService 不再重复 ### 3. 信息密度 - 关键信息:保留(用户问题、耗时、长度) - 冗余信息:删除(重复标题、完整答案) --- ## 查看日志 ```bash # 完整日志 tail -f logs/application.log # 只看框架 tail -f logs/application.log | grep "📝\|⏱️\|📏" # 只看思考过程 tail -f logs/application.log | grep "Agent 思考" # 只看工具调用 tail -f logs/application.log | grep "工具调用\|工具返回" ``` --- ## 提交历史 ``` 当前 refactor(observability): 简化 ChatService 日志,避免与 Hook 重复 b3ea6e2 feat(observability): 添加 Agent 思考过程日志 Hook 8890cd2 feat(observability): 增强 Agent 和工具调用的可观测日志 ``` --- .../superbiz/agent/service/ChatService.java | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/superbiz/agent/service/ChatService.java b/src/main/java/com/superbiz/agent/service/ChatService.java index d42c126..cb04185 100644 --- a/src/main/java/com/superbiz/agent/service/ChatService.java +++ b/src/main/java/com/superbiz/agent/service/ChatService.java @@ -188,13 +188,8 @@ public class ChatService { * @return AI 回复 */ public String executeChat(ReactAgent agent, String question) throws GraphRunnerException { - logger.info("========================================"); - logger.info("========== Agent 执行开始 =========="); logger.info("========================================"); logger.info("📝 用户问题: {}", question); - logger.info("----------------------------------------"); - - logger.info("🚀 执行 ReactAgent.call() - 自动处理工具调用"); long startTime = System.currentTimeMillis(); var response = agent.call(question); @@ -202,19 +197,8 @@ public class ChatService { String answer = response.getText(); - logger.info("========================================"); - logger.info("========== Agent 执行完成 =========="); - logger.info("========================================"); - logger.info("⏱️ 执行耗时: {} ms", duration); - logger.info("📏 最终输出长度: {} 字符", answer.length()); - logger.info("----------------------------------------"); - logger.info("📤 最终输出内容:"); - if (answer.length() > 1000) { - logger.info("{}", answer.substring(0, 1000)); - logger.info("... (已截断,总长度: {} 字符)", answer.length()); - } else { - logger.info("{}", answer); - } + logger.info("⏱️ 总耗时: {} ms", duration); + logger.info("📏 输出长度: {} 字符", answer.length()); logger.info("========================================"); return answer;