|
|
@@ -654,6 +654,22 @@ class AgentRunner:
|
|
|
token_count = estimate_tokens(history)
|
|
|
max_tokens = compression_config.get_max_tokens(config.model)
|
|
|
|
|
|
+ # 压缩评估日志
|
|
|
+ progress_pct = (token_count / max_tokens * 100) if max_tokens > 0 else 0
|
|
|
+ msg_count = len(history)
|
|
|
+ img_count = sum(
|
|
|
+ 1 for msg in history
|
|
|
+ if isinstance(msg.get("content"), list)
|
|
|
+ for part in msg["content"]
|
|
|
+ if isinstance(part, dict) and part.get("type") in ("image", "image_url")
|
|
|
+ )
|
|
|
+ print(f"\n[压缩评估] 消息数: {msg_count} | 图片数: {img_count} | Token: {token_count:,} / {max_tokens:,} ({progress_pct:.1f}%)")
|
|
|
+
|
|
|
+ if token_count > max_tokens:
|
|
|
+ print(f"[压缩评估] ⚠️ 超过阈值,触发压缩流程")
|
|
|
+ else:
|
|
|
+ print(f"[压缩评估] ✅ 未超阈值,无需压缩")
|
|
|
+
|
|
|
if token_count > max_tokens and self.trace_store and goal_tree:
|
|
|
# 使用本地 head_seq(store 中的 head_sequence 在 loop 期间未更新,是过时的)
|
|
|
if head_seq > 0:
|
|
|
@@ -662,12 +678,21 @@ class AgentRunner:
|
|
|
)
|
|
|
filtered_msgs = filter_by_goal_status(main_path_msgs, goal_tree)
|
|
|
if len(filtered_msgs) < len(main_path_msgs):
|
|
|
+ filtered_tokens = estimate_tokens([msg.to_llm_dict() for msg in filtered_msgs])
|
|
|
+ print(
|
|
|
+ f"[Level 1 压缩] 消息: {len(main_path_msgs)} → {len(filtered_msgs)} 条 | "
|
|
|
+ f"Token: {token_count:,} → ~{filtered_tokens:,}"
|
|
|
+ )
|
|
|
logger.info(
|
|
|
"Level 1 压缩: %d -> %d 条消息 (tokens ~%d, 阈值 %d)",
|
|
|
len(main_path_msgs), len(filtered_msgs), token_count, max_tokens,
|
|
|
)
|
|
|
history = [msg.to_llm_dict() for msg in filtered_msgs]
|
|
|
else:
|
|
|
+ print(
|
|
|
+ f"[Level 1 压缩] 无可过滤消息 ({len(main_path_msgs)} 条全部保留, "
|
|
|
+ f"completed/abandoned goals={sum(1 for g in goal_tree.goals if g.status in ('completed', 'abandoned'))})"
|
|
|
+ )
|
|
|
logger.info(
|
|
|
"Level 1 压缩: 无可过滤消息 (%d 条全部保留, completed/abandoned goals=%d)",
|
|
|
len(main_path_msgs),
|
|
|
@@ -675,6 +700,7 @@ class AgentRunner:
|
|
|
if g.status in ("completed", "abandoned")),
|
|
|
)
|
|
|
elif token_count > max_tokens:
|
|
|
+ print("[压缩评估] ⚠️ 无法执行 Level 1 压缩(缺少 store 或 goal_tree)")
|
|
|
logger.warning(
|
|
|
"消息 token 数 (%d) 超过阈值 (%d),但无法执行 Level 1 压缩(缺少 store 或 goal_tree)",
|
|
|
token_count, max_tokens,
|
|
|
@@ -683,6 +709,11 @@ class AgentRunner:
|
|
|
# Level 2 压缩:LLM 总结(Level 1 后仍超阈值时触发)
|
|
|
token_count_after = estimate_tokens(history)
|
|
|
if token_count_after > max_tokens:
|
|
|
+ progress_pct_after = (token_count_after / max_tokens * 100) if max_tokens > 0 else 0
|
|
|
+ print(
|
|
|
+ f"[Level 2 压缩] Level 1 后仍超阈值: {token_count_after:,} / {max_tokens:,} ({progress_pct_after:.1f}%) "
|
|
|
+ f"→ 触发 LLM 总结"
|
|
|
+ )
|
|
|
logger.info(
|
|
|
"Level 1 后 token 仍超阈值 (%d > %d),触发 Level 2 压缩",
|
|
|
token_count_after, max_tokens,
|
|
|
@@ -690,6 +721,12 @@ class AgentRunner:
|
|
|
history, head_seq, sequence = await self._compress_history(
|
|
|
trace_id, history, goal_tree, config, sequence, head_seq,
|
|
|
)
|
|
|
+ final_tokens = estimate_tokens(history)
|
|
|
+ print(f"[Level 2 压缩] 完成: Token {token_count_after:,} → {final_tokens:,}")
|
|
|
+ elif token_count > max_tokens:
|
|
|
+ # Level 1 压缩成功,未触发 Level 2
|
|
|
+ print(f"[压缩评估] ✅ Level 1 压缩后达标: {token_count_after:,} / {max_tokens:,}")
|
|
|
+ print() # 空行分隔
|
|
|
|
|
|
# 构建 LLM messages(注入上下文)
|
|
|
llm_messages = list(history)
|