From 2eb69983ddbb00602750cb657eeb9fb856444ab9 Mon Sep 17 00:00:00 2001 From: Liang Jiaqing Date: Sat, 2 May 2026 20:30:23 +0800 Subject: [PATCH] feat: peer_hint mechanism & history folding compression --- agentmain.py | 9 ++++++--- ga.py | 29 +++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/agentmain.py b/agentmain.py index 1a7eb25f..5bafc21c 100644 --- a/agentmain.py +++ b/agentmain.py @@ -44,11 +44,11 @@ class GeneraticAgent: os.makedirs(os.path.join(script_dir, 'temp'), exist_ok=True) self.lock = threading.Lock() self.task_dir = None - self.history = [] + self.history = []; self.handler = None; self.task_queue = queue.Queue() self.is_running = False; self.stop_sig = False - self.llm_no = 0; self.inc_out = False - self.handler = None; self.verbose = True + self.llm_no = 0; self.inc_out = False; self.verbose = True + self.peer_hint = True self.load_llm_sessions() def load_llm_sessions(self): @@ -136,6 +136,7 @@ class GeneraticAgent: self.history.append(f"[USER]: {rquery}") sys_prompt = get_system_prompt() + getattr(self.llmclient.backend, 'extra_sys_prompt', '') + if self.peer_hint: sys_prompt += f"\n[Peer] 用户提及其他会话/后台任务状态时: temp/model_responses/ (只找近期修改的文件尾部)\n" handler = GenericAgentHandler(self, self.history, os.path.join(script_dir, 'temp')) if self.handler and 'key_info' in self.handler.working: ki = re.sub(r'\n\[SYSTEM\] 此为.*?工作记忆[。\n]*', '', self.handler.working['key_info']) # 去旧 @@ -200,6 +201,7 @@ if __name__ == '__main__': threading.Thread(target=agent.run, daemon=True).start() if args.task: + agent.peer_hint = False agent.task_dir = d = os.path.join(script_dir, f'temp/{args.task}'); nround = '' infile = os.path.join(d, 'input.txt') if args.input: @@ -220,6 +222,7 @@ if __name__ == '__main__': else: break nround = nround + 1 if isinstance(nround, int) else 1 elif args.reflect: + agent.peer_hint = False import importlib.util spec = importlib.util.spec_from_file_location('reflect_script', args.reflect) mod = importlib.util.module_from_spec(spec); spec.loader.exec_module(mod) diff --git a/ga.py b/ga.py index 1f6567a2..715c6fa7 100644 --- a/ga.py +++ b/ga.py @@ -508,10 +508,26 @@ class GenericAgentHandler(BaseHandler): else: result = "Memory Management SOP not found. Do not update memory." return StepOutcome(result, next_prompt=prompt) + def _fold_earlier(self, lines): + FALLBACK = '直接回答了用户问题' + parts, cnt, last = [], 0, '' + def flush(): + if cnt: + if FALLBACK in last: parts.append(f'[Agent]({cnt} turns)') + else: parts.append(f'{last}({cnt} turns)') + for line in lines: + if line.startswith('[USER]'): + flush(); parts.append(line); cnt = 0; last = '' + else: cnt += 1; last = line + flush() + return "\n".join(parts[-150:]) + def _get_anchor_prompt(self, skip=False): if skip: return "\n" - h_str = "\n".join(self.history_info[-40:]) - prompt = f"\n### [WORKING MEMORY]\n\n{h_str}\n" + h = self.history_info; W = 30 + earlier = f'\n{self._fold_earlier(h[:-W])}\n\n' if len(h) > W else "" + h_str = "\n".join(h[-W:]) + prompt = f"\n### [WORKING MEMORY]\n{earlier}\n{h_str}\n" prompt += f"\nCurrent turn: {self.current_turn}\n" if self.working.get('key_info'): prompt += f"\n{self.working.get('key_info')}" if self.working.get('related_sop'): prompt += f"\n有不清晰的地方请再次读取{self.working.get('related_sop')}" @@ -529,16 +545,17 @@ class GenericAgentHandler(BaseHandler): clean_args = {k: v for k, v in args.items() if not k.startswith('_')} summary = f"调用工具{tool_name}, args: {clean_args}" if tool_name == 'no_tool': summary = "直接回答了用户问题" - next_prompt += "\n[DANGER] 你遗漏了,必须按协议一直在每次回复中用中输出极简单行摘要!" - summary = smart_format(summary, max_str_len=100) + next_prompt += "\n[DANGER] 你遗漏了,必须按协议在每次回复中用中输出极简单行摘要" + summary = smart_format(summary.replace('\n', ''), max_str_len=100) self.history_info.append(f'[Agent] {summary}') - if turn % 65 == 0 and 'plan' not in str(self.working.get('related_sop')): + _plan = self._in_plan_mode() + if turn % 65 == 0 and (not _plan): next_prompt += f"\n\n[DANGER] 已连续执行第 {turn} 轮。你必须总结情况进行ask_user,不允许继续重试。" elif turn % 7 == 0: next_prompt += f"\n\n[DANGER] 已连续执行第 {turn} 轮。禁止无效重试。若无有效进展,必须切换策略:1. 探测物理边界 2. 请求用户协助。如有需要,可调用 update_working_checkpoint 保存关键上下文。" elif turn % 10 == 0: next_prompt += get_global_memory() - if (_plan := self._in_plan_mode()) and turn >= 10 and turn % 5 == 0: + if _plan and turn >= 10 and turn % 5 == 0: next_prompt = f"[Plan Hint] 你正在计划模式。必须 file_read({_plan}) 确认当前步骤,回复开头引用:📌 当前步骤:...\n\n" + next_prompt if _plan and turn >= 90: next_prompt += f"\n\n[DANGER] Plan模式已运行 {turn} 轮,已达上限。必须 ask_user 汇报进度并确认是否继续。"