refactor(observability): 简化 ChatService 日志,避免与 Hook 重复
## 改动内容
### 修改前:重复的日志
```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 和工具调用的可观测日志
```
This commit is contained in:
@@ -188,13 +188,8 @@ public class ChatService {
|
|||||||
* @return AI 回复
|
* @return AI 回复
|
||||||
*/
|
*/
|
||||||
public String executeChat(ReactAgent agent, String question) throws GraphRunnerException {
|
public String executeChat(ReactAgent agent, String question) throws GraphRunnerException {
|
||||||
logger.info("========================================");
|
|
||||||
logger.info("========== Agent 执行开始 ==========");
|
|
||||||
logger.info("========================================");
|
logger.info("========================================");
|
||||||
logger.info("📝 用户问题: {}", question);
|
logger.info("📝 用户问题: {}", question);
|
||||||
logger.info("----------------------------------------");
|
|
||||||
|
|
||||||
logger.info("🚀 执行 ReactAgent.call() - 自动处理工具调用");
|
|
||||||
|
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
var response = agent.call(question);
|
var response = agent.call(question);
|
||||||
@@ -202,19 +197,8 @@ public class ChatService {
|
|||||||
|
|
||||||
String answer = response.getText();
|
String answer = response.getText();
|
||||||
|
|
||||||
logger.info("========================================");
|
logger.info("⏱️ 总耗时: {} ms", duration);
|
||||||
logger.info("========== Agent 执行完成 ==========");
|
logger.info("📏 输出长度: {} 字符", answer.length());
|
||||||
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("========================================");
|
logger.info("========================================");
|
||||||
|
|
||||||
return answer;
|
return answer;
|
||||||
|
|||||||
Reference in New Issue
Block a user