Talegorithm 8 часов назад
Родитель
Сommit
a65fb3b18e
2 измененных файлов с 33 добавлено и 14 удалено
  1. 31 12
      agent/core/runner.py
  2. 2 2
      agent/trace/run_api.py

+ 31 - 12
agent/core/runner.py

@@ -106,8 +106,9 @@ class RunConfig:
     tools: Optional[List[str]] = None          # None = 全部已注册工具
     side_branch_max_turns: int = 5             # 侧分支最大轮次(压缩/反思)
 
-    # --- 强制侧分支(用于 API 手动触发)---
-    force_side_branch: Optional[Literal["compression", "reflection"]] = None
+    # --- 强制侧分支(用于 API 手动触发或自动压缩流程)---
+    # 使用列表作为侧分支队列,每次完成一个侧分支后 pop(0) 取下一个
+    force_side_branch: Optional[List[Literal["compression", "reflection"]]] = None
 
     # --- 框架层参数 ---
     agent_type: str = "default"
@@ -781,8 +782,9 @@ class AgentRunner:
             return history, head_seq, sequence, False
 
         # 知识提取:在任何压缩发生前,用完整 history 做反思(进入反思侧分支)
-        if config.knowledge.enable_extraction:
-            # 返回标志,让主循环进入反思侧分支
+        if config.knowledge.enable_extraction and not config.force_side_branch:
+            # 设置侧分支队列:先反思,再压缩
+            config.force_side_branch = ["reflection", "compression"]
             return history, head_seq, sequence, True
 
         # Level 1 压缩:GoalTree 过滤
@@ -824,7 +826,10 @@ class AgentRunner:
                 "Level 1 后仍超阈值 (消息数=%d/%d, token=%d/%d),需要进入压缩侧分支",
                 msg_count_after, compression_config.max_messages, token_count_after, max_tokens,
             )
-            # 返回标志,让主循环进入压缩侧分支
+            # 如果还没有设置侧分支(说明没有启用知识提取),直接进入压缩
+            if not config.force_side_branch:
+                config.force_side_branch = ["compression"]
+            # 返回标志,让主循环进入侧分支
             return history, head_seq, sequence, True
 
         # 压缩完成后,输出最终发给模型的消息列表
@@ -1011,12 +1016,12 @@ class AgentRunner:
 
             # 进入侧分支
             if needs_enter_side_branch and not side_branch_ctx:
-                # 判断侧分支类型
-                if config.force_side_branch:
-                    # API 强制触发
-                    branch_type = config.force_side_branch
+                # 从队列中取出第一个侧分支类型
+                if config.force_side_branch and isinstance(config.force_side_branch, list) and len(config.force_side_branch) > 0:
+                    branch_type = config.force_side_branch.pop(0)
+                    logger.info(f"从队列取出侧分支: {branch_type}, 剩余队列: {config.force_side_branch}")
                 elif config.knowledge.enable_extraction:
-                    # 自动触发:反思
+                    # 兼容旧的单值模式(如果 force_side_branch 是字符串)
                     branch_type = "reflection"
                 else:
                     # 自动触发:压缩
@@ -1240,6 +1245,12 @@ class AgentRunner:
 
                         # 清除侧分支状态
                         trace.context.pop("active_side_branch", None)
+
+                        # 队列中如果还有侧分支,保持 force_side_branch;否则清空
+                        if not config.force_side_branch or len(config.force_side_branch) == 0:
+                            config.force_side_branch = None
+                            logger.info("反思超时,队列为空")
+
                         if self.trace_store:
                             await self.trace_store.update_trace(
                                 trace_id, context=trace.context
@@ -1321,6 +1332,9 @@ class AgentRunner:
 
                         logger.info(f"压缩侧分支完成,history 长度: {len(history)}")
 
+                        # 清除侧分支队列
+                        config.force_side_branch = None
+
                     elif side_branch_ctx.type == "reflection":
                         # 反思侧分支:直接恢复主路径
                         logger.info("反思侧分支完成")
@@ -1332,6 +1346,11 @@ class AgentRunner:
                             history = [m.to_llm_dict() for m in main_path_messages]
                             head_seq = side_branch_ctx.start_head_seq
 
+                        # 队列中如果还有侧分支,保持 force_side_branch;否则清空
+                        if not config.force_side_branch or len(config.force_side_branch) == 0:
+                            config.force_side_branch = None
+                            logger.info("反思完成,队列为空")
+
                     # 清除侧分支状态
                     trace.context.pop("active_side_branch", None)
                     if self.trace_store:
@@ -1341,8 +1360,8 @@ class AgentRunner:
                             head_sequence=head_seq,
                         )
 
-                    # 清除强制侧分支配置(避免影响后续续跑)
-                    config.force_side_branch = None
+                    # 注意:不在这里清除 force_side_branch,因为反思侧分支可能已经设置了下一个侧分支
+                    # force_side_branch 的清除由各个分支类型自己处理
 
                     side_branch_ctx = None
                     continue

+ 2 - 2
agent/trace/run_api.py

@@ -487,7 +487,7 @@ async def reflect_trace(trace_id: str, req: ReflectRequest):
     config = RunConfig(
         trace_id=trace_id,
         model=trace.model or "gpt-4o",
-        force_side_branch="reflection",
+        force_side_branch=["reflection"],  # 使用列表格式
         max_iterations=20,  # 给侧分支足够的轮次
         enable_prompt_caching=True,
     )
@@ -535,7 +535,7 @@ async def compact_trace(trace_id: str):
     config = RunConfig(
         trace_id=trace_id,
         model=trace.model or "gpt-4o",
-        force_side_branch="compression",
+        force_side_branch=["compression"],  # 使用列表格式
         max_iterations=20,  # 给侧分支足够的轮次
         enable_prompt_caching=True,
     )