diff --git a/memory/plan_sop.md b/memory/plan_sop.md new file mode 100644 index 0000000..bdfff2b --- /dev/null +++ b/memory/plan_sop.md @@ -0,0 +1,70 @@ +# Plan Mode SOP +**触发**:3步以上有依赖/多文件协同/条件分支/需并行 | **禁用**:1-2步简单任务直接做 +**工作目录**:`./plan_XXX/`(XXX=任务英文短名) +## 规划态(按序执行) +**步骤1:创建文件夹 + 存checkpoint** +``` +[任务] 产出 ./plan_XXX/plan.md | [需求] 一句话 | [约束] 关键限制 +[进度] 即将读领域SOP | ⚡写完plan后必须重读本SOP步骤3切换执行态 +``` +**步骤2:读领域SOP → 写plan骨架** +先读相关SOP,立即写骨架。允许"⚠待确认",禁止以"没调研清楚"推迟。 +**骨架格式**: +``` +# 任务标题 +需求:一句话 | 约束:关键限制 +1. [ ] 步骤1简述 +2. [P] 步骤2简述(并行,读subagent_sop.md执行Map模式) + 依赖:1 +3. [?] 步骤3(条件分支) + 条件:X成功→3.1,否则→3.2 +``` +**标记**:`[ ]`待做 | `[✓]`完成 | `[✗]`失败 | `[P]`并行 | `[?]`条件分支 +**[P]标记条件**(全YES才可标): +□ 2+步骤可同时? □ 无数据依赖? □ 产出不同文件? □ 节省>20%时间? +**子任务目录**:subagent产出放 `./plan_XXX/subtask_name/` +**探索规则**:有⚠项→逐项探索,每轮更新plan+checkpoint | 连续3轮无进展→用当前最佳方案 +**⛔ 写完骨架后禁止执行。必须先完成步骤3。** + +**步骤3:转入执行态** +``` +CALL update_working_checkpoint( + key_info='[执行] plan.md | 当前:1.1 | ⚡有[P]标记必须读subagent_sop.md执行Map模式' +) +``` +## 执行态循环 +1. 读plan.md → 定位当前`[ ]`项 +2. **检查并行**: + ``` + IF has_mark('[P]'): + CALL file_read('subagent_sop.md') + # 按SOP创建context.json(含绝对路径)+ input.txt + # ⚠ subagent必须从context.json读取绝对路径写入文件 + ELSE: + 执行当前步骤 + ``` +3. 执行该项 +4. **收尾(必须执行,不可跳过)**: + ``` + # ⚠ 进度标记更新是强制要求,每步完成后必须执行 + file_patch(plan, '[ ] 当前步骤' → '[✓] 当前步骤') + file_read(plan) # 验证标记已更新 + 找下一步 + update_working_checkpoint('[进度] 步骤N已完成 | 下一步:...') + ``` +5. **Checkpoint验证(每3步或关键节点)**: + ``` + file_read(plan) # 检查:所有已执行步骤是否标[✓] + IF 有遗漏标记: + 立即补标 file_patch(...) + ``` +6. 全部完成 → 汇总结果 → 清理checkpoint +## 失败处理 +1. **记录**:checkpoint中 `step_X: [FAILED] 原因 (retry: N/3)` +2. **重试**:网络超时→自动重试3次(2s/4s/8s) | 配置错误→询问用户 | 其他→标[✗]跳过 +3. **subagent失败**:查stderr.log→明确错误主agent修正重启 | 未知错误重试1次 | 最多重启2次 +4. **依赖传播**:步骤失败后,后续依赖项标[SKIP] +## 强制约束 +- 每项必须有独立完成判据 +- 禁止"处理所有文件",必须展开具体条目 +- 一次只做一项;计划有误回规划态修正 +- 不可逆操作前多验证一步 \ No newline at end of file diff --git a/memory/subagent_sop.md b/memory/subagent_sop.md index dcddb94..92b4da0 100644 --- a/memory/subagent_sop.md +++ b/memory/subagent_sop.md @@ -1,41 +1,76 @@ # Subagent 调用 SOP -## 何时调用(调用原则) +## Task Mode 文件IO协议 -唯一适用场景:**map模式**——将N个独立同构子任务分发给各自的subagent处理。 +- 目录:`temp/{task_name}/`(相对代码根GenericAgent/),主agent cwd在temp/时即 `./{task_name}/` +- 启动:`python agentmain.py --task {task_name} [--llm_no N]`(cwd=代码根),其中agentmain.py位于代码根目录 +- 流程:写 input.txt → 启动 → 轮询 output.txt → 读回复 → 写 reply.txt 继续 → 不写则5min自动退出 +- input.txt原则:写目标+约束,可指定SOP名。禁写具体实现步骤——除非主agent已读过该SOP确认正确。凭印象猜的步骤会误导subagent +- output.txt:首轮对话的流式输出(持续append),用mtime/size判断更新 +- output1.txt, output2.txt...:reply后各轮的流式输出(递增编号),同样持续append -- 核心优势:独立上下文。避免处理文档A的长上下文污染处理文档B的质量 -- 文件系统共享是优点:不同agent处理不同输入文件,产生不同输出文件 -- 共享资源冲突:键鼠/浏览器主体不可共享(浏览器可分tab但需谨慎),subagent任务应限于文件处理 -- 不满足map模式的任务 → 主agent顺序执行即可,别用subagent +## 后台调用要点 -**额外场景:SOP dry-run验证**——启动单个subagent执行目标SOP,通过output日志发现SOP缺陷(缺参数/选择器不准/步骤模糊),主agent据此patch优化SOP。单subagent不存在资源冲突。 +```python +task_dir = os.path.join(agent_root, 'temp', task_name) +creation_flags = 0x08000000 if platform.system() == 'Windows' else 0 +proc = subprocess.Popen( + [sys.executable, 'agentmain.py', '--task', task_name], + cwd=agent_root, creationflags=creation_flags, + stdout=open(os.path.join(task_dir, 'stdout.log'), 'w', encoding='utf-8'), + stderr=open(os.path.join(task_dir, 'stderr.log'), 'w', encoding='utf-8')) +``` + +- 必须 Popen,禁止 subprocess.run(会阻塞) +- stdout.log/stderr.log 用于调试subagent卡死、LLM调用失败等问题 +- 文件统一 UTF-8,subagent 无 reply 5min 自动退出无需清理 +- **禁止合并启动+轮询到同一个code_run**——会阻塞自己。启动Popen立即返回,下一轮再poll output.txt。这是并行的前提 +- 新建/复用任务目录时,先删除旧 output*.txt(否则会读到上次结果误判完成) + +## 场景1:测试模式 - 行为验证 +**用途**:观察agent真实行为,修正RULES/L2/L3/SOP +**流程**:创建test_path/写input.txt→启动subagent→轮询output.txt(2秒间隔)→验证→清理重复 +**测试原则**:只给目标,不提示位置/不诱导做法,观察自主选择 +**修正闭环**:发现问题→设计测试→定位根源(RULES/L2/L3/SOP)→patch修正→验证 +**技术要点**:Insight优先级>SOP;subagent的cwd=temp/ +**两种测试**: - 测SOP质量:input指定SOP名(如"用ezgmail_sop查看最近3封未读邮件"),排除导航干扰,失败即SOP问题 - 测导航能力:input只写目标,验证subagent能自主从insight找到正确SOP。禁止内联SOP内容 +## 场景2:Map模式 - 并行处理 +**用途**:将N个独立同构子任务分发给各自的subagent处理 +**核心优势**:独立上下文。避免处理文档A的长上下文污染处理文档B的质量 +**约束**: +- 文件系统共享是优点:不同agent处理不同输入文件,产生不同输出文件 +- 共享资源冲突:键鼠不可共享;浏览器暂时不可并行使用,避免同时操作同一标签页 +- 不满足map模式的任务 → 主agent顺序执行即可,别用subagent **标准流程(map-reduce)**: 1. 主agent准备阶段:爬取/dump数据,存为多个独立输入文件 2. 分发:对每个文件启动一个subagent处理(主agent自己也可以处理其中一个) 3. 收集:等所有subagent完成,主agent读取各输出文件,汇总结果 -## Task Mode 文件IO协议 -- 目录:`temp/{task_name}/`(相对代码根GenericAgent/),主agent cwd在temp/时即 `./{task_name}/` -- 启动:`python agentmain.py --task {task_name} [--llm_no N]`(cwd=代码根) -- 流程:写 input.txt → 启动 → 轮询 output.txt → 读回复 → 写 reply.txt 继续 → 不写则5min自动退出 -- input.txt原则:写目标+约束,可指定SOP名。禁写具体实现步骤——除非主agent已读过该SOP确认正确。凭印象猜的步骤会误导subagent -- reply后subagent的后续输出在 output1.txt, output2.txt ... 中(递增编号),主agent需轮询这些文件 -- output.txt 每轮覆盖写,用 mtime/size 判断新轮次 - -## 后台调用要点 -```python -task_dir = os.path.join(agent_root, 'temp', task_name) -proc = subprocess.Popen( - [sys.executable, 'agentmain.py', '--task', task_name], - cwd=agent_root, creationflags=0x08000000, - stdout=open(os.path.join(task_dir, 'stdout.log'), 'w', encoding='utf-8'), - stderr=open(os.path.join(task_dir, 'stderr.log'), 'w', encoding='utf-8')) -``` -- 必须 Popen,禁止 subprocess.run(会阻塞) -- stdout.log/stderr.log 用于调试subagent卡死、LLM调用失败等问题 -- `--llm_no` 默认=sonnet 4.5,`--llm_no 1`=opus 4.6 -- 文件统一 UTF-8,subagent 无 reply 5min 自动退出无需清理 \ No newline at end of file +## subagent内部plan_mode使用 +**原则**:subagent本身是完整agent,接收多步骤任务时应在内部创建plan管理执行 +**触发条件**:任务包含3个以上子步骤、子步骤之间有依赖关系、需要checkpoint来恢复执行 +**实现方式**: +1. **主agent创建subagent时**:在input.txt中说明任务包含多个步骤,建议使用plan_mode +2. **subagent内部执行**:检测到多步骤任务后,创建 `./subagent_plan.md` 并使用plan_mode执行 +3. **主agent监控**:只关注最终结果(output*.txt),不需要关心subagent内部如何执行 +4. **文件传递机制**:主agent创建subagent时在task_dir中生成 `context.json`,包含所有文件的**绝对路径** + **⚠ subagent启动后第一步必须读取context.json** + **⚠ 所有文件操作必须使用context.json中的绝对路径** +**格式示例**: +```json +{ + "task": "任务描述", + "work_dir": "/absolute/path/to/plan_dir/", + "input_files": { + "paper_info": "/absolute/path/to/paper_info.txt" + }, + "output_files": { + "pdf": "/absolute/path/to/paper.pdf", + "report": "/absolute/path/to/paper_report.md" + }, + "dependencies": ["paper_info.txt必须存在"] +} +``` \ No newline at end of file