diff --git a/memory/checklist_helper.py b/memory/checklist_helper.py index 31df5a87..19706dc1 100644 --- a/memory/checklist_helper.py +++ b/memory/checklist_helper.py @@ -20,9 +20,9 @@ class CL: else: self._d = {"closed": False, "goal": goal, "bbs": None, "tasks": []} self._save() - if workers > 0: - self._ensure_bbs() - self.start_worker(workers) + if workers > 0: + self._ensure_bbs() + self.start_worker(workers) @property def tasks(self): return self._d["tasks"] @@ -55,7 +55,9 @@ class CL: for t in texts: self.tasks.append({"id": nid, "text": t, "result": None, "ts": int(time.time())}) ids.append(nid); nid += 1 - self._save(); return ids + self._save(); + print('task added, must reread checklist SOP before start executing ...'); + return ids def mark(self, tid, result): for t in self.tasks: @@ -83,6 +85,18 @@ class CL: "--base_url", self.bbs_url, "--board_key", self.bbs_key, "--name", f"w{i+1}"], **_PK) if i < n - 1: time.sleep(5) + def _pid_alive(self, pid): + if not pid: return False + try: + r = subprocess.run(["tasklist", "/FI", f"PID eq {pid}"], capture_output=True, text=True) + return str(pid) in r.stdout + except Exception: return False + def start_master(self): - subprocess.Popen(["python", str(_MAIN), "--reflect", str(_M_RE), + old_pid = self._d.get("master_pid") + if old_pid and self._pid_alive(old_pid): + print(f"[CL] master already running (PID {old_pid}), skip") + return + p = subprocess.Popen(["python", str(_MAIN), "--reflect", str(_M_RE), "--mr_folder", str(self.folder.resolve())], **_PK) + self._d["master_pid"] = p.pid; self._save() diff --git a/memory/checklist_sop.md b/memory/checklist_sop.md index e7cbaa42..77c6aed1 100644 --- a/memory/checklist_sop.md +++ b/memory/checklist_sop.md @@ -6,14 +6,14 @@ ```python from checklist_helper import CL cl = CL("cl_xxx", goal="<用户要求任务,尽量原样>") -cl.start_master() +cl.start_master() # Only for Booter,Master严禁调用 ``` **MapReduce 模式**(多人,master派发+worker执行): ```python from checklist_helper import CL cl = CL("cl_xxx", goal="<用户要求任务,尽量原样>", workers=2) -cl.start_master() +cl.start_master() # Only for Booter,Master严禁调用 ``` goal 写法:只写「做什么 + 参考哪个SOP」,不写怎么做。Master 自己读 SOP 决定 plan。 @@ -55,7 +55,7 @@ B 要等 A 的结果 → 不要硬拆,串行做。 ``` cl.look() -├─ 有未完成任务 → 去 BBS 派发(mapreduce模式)/ 挑最简单的**不派发**自己干 / 自己干(无worker checklist模式) +├─ 有未完成任务 → 去 BBS 派发(mapreduce模式)/ 自己干(无worker checklist模式) └─ 全部完成 ├─ 用户最终目标已达成 → close() └─ 最终目标未达成 → plan 下一步 @@ -72,7 +72,7 @@ worker无法看到add的任务,只能看到BBS! 每条任务 prompt 须**自包含**——worker 没有 master 的上下文。 每次最多只派发3个任务,不要一次性把所有任务贴到bbs上。 worker足够聪明,只允许写目标和需要的信息,不要干预 -**master不允许执行已经派发出去的任务,会导致重复执行!** +**master不允许执行已经派发出去的任务,会导致重复执行!** 没事就sleep! 写 prompt 要点: 1. **背景**:worker 需要的信息直接给(路径、数据、约定),不要假设 worker 知道 diff --git a/reflect/agent_team_worker.py b/reflect/agent_team_worker.py index d54df69e..0139dcbc 100644 --- a/reflect/agent_team_worker.py +++ b/reflect/agent_team_worker.py @@ -39,7 +39,7 @@ BBS: {base_url} (key: {board_key}) 1. GET /posts?limit=10&key=xxx 查看新帖,有必要才看更多 2. 找到适合接的任务帖,点名你的优先接;未点名且适合也可接 -3. 回复抢单,确认最早接单后,执行任务 +3. 回复抢单,然后**看最新帖子确认是最早接单后**,执行任务,务必注意不要和别的worker重复 4. 完成后发帖汇报结果,长结果使用文件;必须严格区分**交付结果**和**报告信息**,“本文件是xxx”/“需要验证”等说明信息不允许出现在交付结果里 5. 有问题在BBS中交流,等下次唤醒看回复 6. 你会被持续唤醒,注意跟进BBS上的回复和追加指令 diff --git a/reflect/checklist_master.py b/reflect/checklist_master.py index 8bb5dc88..34dadc1c 100644 --- a/reflect/checklist_master.py +++ b/reflect/checklist_master.py @@ -53,13 +53,12 @@ def _prompt(data, new_posts): if new_posts: trigger = "有新回帖,去BBS查看并验收" elif any(t["result"] is None for t in data.get("tasks", [])): - trigger = "有未完成任务,继续执行" if not bbs else "有未完成任务,派发或自己执行" - else: - trigger = "无未完成任务,该plan下一步了" - lines = [f"你是 Checklist Master({mode}模式)。阅读 checklist_sop.md 按 Master 循环行事。"] - if bbs: - lines.append(f"BBS API文档(requests): GET {bbs['url']}/readme?key={bbs['key']}") + trigger = "有未完成任务,继续执行" if not bbs else "有未完成任务,派发" + else: trigger = "无未完成任务,该plan下一步了" + lines = [f"你是 Checklist Master({mode}模式)。阅读 checklist_sop.md 21行之后按 Master 行事。"] + if bbs: lines.append(f"BBS API文档(requests): GET {bbs['url']}/readme?key={bbs['key']}") lines.append(f"目标: {goal}") lines.append(f"唤醒原因: {trigger}") lines.append(f'用 checklist_helper 的 CL("{_folder}") 管理状态(look/add/mark/close)。按决策树行动。') + if bbs: lines.append("【禁止】你只负责派发+轮询+验收,绝不自己执行任务。") return "\n".join(lines)