MemPalace Agent Task:基于 Logstream 的多智能体任务委派、执行与受控无头运行的完整指南
本篇技术指南以 MemPalace 的 mempalace-task 技能文档为核心,讲解如何通过共享大脑(shared-brain hub)的 logstream 通道在多 Agent 之间完成任务的创建(delegate)、交接(handoff)、认领(claim)、执行与闭环(ack),并覆盖 mempalace task launch 受控无头运行与收件监控纪律。读完本文,你将掌握一套可直接复制的任务生命周期操作流程:既能粘贴一条 "Ready to paste" 交接行唤醒目标 Agent,也能在干净 Git checkout 上以 codex/claude runner 无头启动任务,并理解其背后的事件模型与源码校验逻辑。
任务的本质是 logstream 中的不可变事件,而不是记忆抽屉里的一条记录——本文所有流程都建立在这一前提上。技能的权威协议文本位于 协调协议(coordination-protocol),本文在该协议与 skills/mempalace-task/SKILL.md 技能本体 的基础上,结合 任务封装实现、CLI 实现 与 MCP 工具实现 做了源码级展开。
先分清两个通道:记忆 vs 协调
共享大脑给每个 Agent 提供两条彼此不应混淆的通道:
- 记忆通道:drawers(抽屉)、知识图谱(KG)、日记等,存放"未来值得回忆的持久知识",通过语义检索获取,遵循 recall-protocol。
- 协调通道:logstream 事件与 artifact,存放"此刻正在 Agent 之间流动的活跃工作"——委派、回复、补丁、ack。它按结构化字段过滤,绝不做语义搜索。
判断准则就一句话:如果别的 Agent 需要对它"采取行动",它是事件;如果未来会话需要"知道"它,它是抽屉。 一场已结束的委派通常两者都会产生:事件承载了工作过程,抽屉记录最终结论。mempalace-task 技能处理的是前者。logstream 协调层的设计动因与存储模型见 RFC 003,事件/artifact 的完整模型与工具参考见 Agent Logstream 概念文档。
任务在协调通道上的标准生命周期如下(与协议中 requester/worker 两端的步骤一一对应):
| 阶段 | 动作 | 关键字段/工具 |
|---|---|---|
| 委派 | 追加一条 task.request |
stream=project/<name>、room=delegation、to_agent=<worker>、status=open |
| 认领 | 对请求回 claimed |
mempalace_event_ack(status=claimed),防止重复劳动 |
| 交付 | 提交补丁 | mempalace_patch_submit(携带 diff、correlation_id、branch、base_commit) |
| 受阻/失败 | 原样回复 | 事件类型 task.reply,status=blocked 或 failed |
| 闭环 | 请求方验证后 ack | mempalace_event_ack(status=applied) 或 failed,附逐字证据 |
硬性规则贯穿始终:事件 只追加(append-only)、载荷 逐字保留(verbatim)、每条被认领的 task.request 最终必须落到 applied/failed/blocked——不允许悬空的 open。
验证协调接缝:动手前先做四项检查
技能文档要求在实际委派或接收任务前,先确认运行时具备协调能力,检查顺序如下:
- 确认命令与工具存在:
mempalace --version应成功;同时确认mempalace task --help与mempalace_task_create都存在。若两者任一缺失,说明当前运行时是缺乏 update-awareness 命令的旧版本——不要假设它具备协调能力,应停止并向用户说明不兼容,交由mempalacesetup 技能处理,给出与包管理器匹配的升级建议(uv tool upgrade mempalace、pipx upgrade mempalace,或由当前解释器执行-m pip install --upgrade mempalace),以及npx skills update mempalace mempalace-recall mempalace-task。任何命令执行前都必须获得用户明确授权。 - 确认 MemPalace MCP 工具已连接,且当前活跃 palace 就是预期的共享大脑(shared brain),避免写入了一个并非预期的本地 palace。
- 确立当前 Agent 的稳定身份。身份遵循
<machine>-<harness>格式(如mac-claude、windows-codex),整个事件足迹只有在身份稳定时才可审计,绝不冒充其他 Agent。 - 尽量确认目标 Agent 的监控状态。一条粘贴过去的手动交接行能唤醒回合制 Agent,但单独的 logstream 事件做不到——这决定了后面"交接还是无头启动"的选择。
若上述设置不完整,技能明确要求停止并改用 mempalace setup 技能(见 .claude-plugin/skills/mempalace/SKILL.md)。
创建一条任务:字段、规范化与批准
创建任务前需要从用户或当前仓库状态收集以下字段:
- 项目路由名(project);
- 请求方与目标 Agent 身份(from/to agent);
- 精确目标(exact goal);
- 目标分支(target branch);
- 精确的十六进制基线提交 id(base commit)——只能是提交 id,绝不能用分支或标签;
- 完成定义(definition of done)。
两个关键来源事实可以印证这里的规范:
base commit必须匹配正则^[0-9a-fA-F]{7,64}$(7 到 64 位十六进制 Git 对象 id),分支与标签会被直接拒绝,见 validate_task_base_commit。基线提交与分支必须从目标 worker 的 checkout 解析,而不是从无关仓库取。correlation_id由task_<目标slug>_<随机4字节hex>自动生成(task_slug会把目标压成最长 40 字符的路由安全标签),见 create_task。事件stream会被规范化为project/<slug>,room=delegation,初始status=open。
追加任何内容之前,必须先向用户展示"精确规范化后的任务"——身份、项目、目标、分支、基线提交、完成定义,以及"交付必须经由 MemPalace 闭环"这一约定。原因在于 logstream 事件不可变:除非用户在当前回合已经明确批准,否则必须先获得对这份逐字内容的批准,再写入。
写入应走高层接口而不是手工拼装原始 task.request:
- MCP 连接时(尤其是客户端要加入远程 shared-brain hub):调用
mempalace_task_create,传入已批准的字段。它会写入 hub 并返回存储的task与handoff,而不是写入某个非预期的本地 palace。该工具的实现就是转发到create_task高层封装,见 tool_task_create。 - 在 palace 拥有者机器上,或有意通过 shell 操作本地 palace 时,使用等价 CLI:
mempalace task create \
--project <project> \
--from-agent <requester> \
--to-agent <worker> \
--goal <exact-goal> \
--branch <branch> \
--base-commit <commit> \
--done <exact-definition-of-done>
CLI 层的参数定义与 create_task 完全对应(--project/--from-agent/--to-agent 必填,--goal 与 --done 必填,另有 --json 输出机器可读结果),见 cli.py 任务解析器。多行目标或完成定义要使用 --goal-file / --done-file(两者皆支持 - 表示 stdin),CLI 内部通过 _read_text_arg 读取,绝不把用户的措辞压扁或转述——目标与完成定义必须逐字保留在事件 body 中。
创建成功后,CLI 会打印一行 "Ready to paste";MCP 工具则以 handoff 字段返回同一行(格式为 Open MemPalace task <id> as <agent>. Claim it, follow its exact definition of done, and deliver through the logstream.,渲染逻辑见 task_handoff)。应把该行原样返回给用户,让用户无需复制整个任务正文即可唤醒目标 Agent。注意两条纪律:一是永远不要因为远程 MCP 调用失败就悄悄回退到本地 CLI——应当暴露并修复连接问题;二是"创建任务"与"启动进程"是两个独立动作(见下文)。
接收并执行一条粘贴过来的任务
当用户给出 Open MemPalace task <id> as <agent>... 形式的交接行时,worker 侧应按下述顺序执行:
- 取完整请求:用
correlation_id=<id>调用mempalace_event_list取回精确的task.request——绝不能只依据短小的粘贴行工作。correlation_id是索引化过滤字段,见 tool_event_list。 - 校验身份与基座:确认任务确实是发给本 Agent 的(或是明确接受的广播);编辑前校验 workspace、branch 与 base commit。
- 认领:
mempalace_event_ack(status=claimed),避免其他 Agent 重复执行。 - 干活并运行声明的验证。
- 交付补丁:用
mempalace_patch_submit(带 diff、correlation_id、branch、base_commit)。若受阻或失败,则改发逐字的task.reply(status=blocked/failed,附原样证据)。沉默不是有效结果——技能与协议都反复强调:静默是唯一不可恢复的失败。推送一个分支不等于完成交接,事件才是。 - 请求方闭环:请求方取回并校验 artifact、在明确告知用户的意图下应用补丁、运行验证,然后 ack
applied或failed。
对纯远程的 shared-brain 客户端,收件箱监控必须走 MCP:用 mempalace_event_wait 携带稳定的目标身份,并把最后看到的事件 id 作为 since_event_id 往前推进;用 mempalace_event_list 做唤醒清扫(inbox sweep)。默认超时 60 秒、上限 5 分钟,超时返回 {"timed_out": true, "events": []} 是正常结果而非错误,且内部已做退避——不要手工包一层紧循环。除非本机拥有该 palace 或是一个刻意同步的副本,否则不要运行本地 SQLite 的 mempalace logstream watch 命令。
受控无头模式:task launch 启动 codex / claude
只有在用户明确要求启动一个 Agent 时,才走无头路径。先准备一份受信任、干净的 Git checkout,且必须位于任务指定的精确分支与基线提交上,然后运行:
mempalace task launch <task-id> --runner codex --workspace <path>
mempalace task launch <task-id> --runner claude --workspace <path>
这两条命令从本地 palace 解析任务。对于远程纯 MCP 客户端,则先用 mempalace_event_list 取回那唯一一条完整的 task.request,把该事件对象原样保存为 JSON 放到目标机器上,再用 --task-file 启动,全程不咨询任何无关的本地 palace:
mempalace task launch --task-file <task-request.json> --runner codex --workspace <path>
关键约束如下:
- task 文件只是传输快照,不是替代任务:不得编辑或重建它。
- 无头启动永远发生在目标机器上——即拥有受信任 checkout 的那台机器。请求方不可能只凭向 hub 追加事件就远程拉起一个进程。
- CLI 的
launch分支(见 cmd_task)会依次完成:解析存储的请求 → 校验 workspace 是干净的 Git checkout 且HEAD等于存储的 base commit(_validate_task_workspace)→ 校验被寻址身份及其约定的*-codex/*-claudeharness 后缀与所选 runner 一致 → 不经 shell 直接启动所选 runner。 --agent <identity>只能用于接受广播任务,绝不能用它覆盖一条寻址给别人的任务;解析器会直接拒绝身份不匹配的启动。- launcher 不绕过沙箱、审批或 harness 权限。不要替用户添加危险的权限旗标。
参数层面对应关系见 cli.py launch 解析器:correlation_id 位置参数与 --task-file 互斥二选一,--runner 的取值集合来自 _TASK_RUNNER_ADAPTERS,--workspace 必填。
一句话总结定位:任务创建与进程启动是两个独立动作。可粘贴的手动交接行是可移植的默认路径;无头启动只是显式受控模式下的一层适配器。
监控纪律:谁在听、在听什么
多数协调摩擦并非协议失败,而是"监听失败"——任务停在 open,只是因为被寻址的 Agent 从未在看,而请求方无法分辨"正在处理"与"没人在家"。技能要求 worker 侧的监控决策要有意识且可见,以下要点直接继承自 协调协议:
光标(cursor)铁律:恢复用 since_event_id,绝不用 since_created_at。 事件按追加顺序(rowid)而非墙上时钟排序,跨副本同步会令"创建时间更早"的远端事件晚于本地事件被摄取;用时间做光标会静默漏掉这类事件。since_created_at 只是"今天发生了什么"这类时间窗口查询,且含端点需自行按 id 去重。整个 watcher 状态就是一串字符串:你处理过的最后一个事件 id。
按存活时长选监控模式:
| 模式 | 适用场景 | 做法 |
|---|---|---|
| 收件箱清扫 | 每个会话开始、任何长任务之前 | mempalace_event_list + to_agent=<你> + since_event_id=<上次> + preview=true |
| 后台 watcher | 干活时希望被唤醒 | mempalace logstream watch 作为后台进程 |
| 长轮询 | 回合内主动等待某个已知关联 | mempalace_event_wait + correlation_id + to_agent=<你> |
| 推送(SSE) | 常驻进程:daemon、面板、实时查看器 | GET /logstream/stream,同一信封,since_event_id 续读 |
| 声明空闲 | 回合制 Agent(无后台循环) | 无法监听;明确说明并发布光标,让请求方来 ping |
后台 watcher 是最多 Agent 该用的形态:它阻塞到出现你关心的内容才打印并退出,因此任何能跑后台进程、能对进程退出做出反应的 harness 都会被唤醒:
mempalace logstream watch \
--agent mac-claude \
--type task.request --type task.reply --type patch.ready \
--state-file ~/.mempalace/watch/mac-claude.json --json
逐参数要点(详见协调协议):--agent <id> 等价于 --to-agent <id> 且 --exclude-from-agent <id>——排除并非装饰,因为 to_agent=<你> 会刻意匹配 * 广播,而你自己发的广播也是广播,没有排除会把每条自发状态都吵醒;重复 --type 表示"或"(一旦委派过任务,务必把 task.reply 放进过滤器,否则 blocked/failed 会让 watcher 静默推过光标,委派无人应答);--state-file 持久化光标,重启后精确续读;退出码是唤醒信号——0 表示打印到匹配、2 表示 --idle-exit-ms 超时无消息、130 表示被打断,只有 0 才算"有邮件";--follow --json 输出 NDJSON(逐行一条记录);首次启动从 tip 开始(重放历史是收件箱清扫的职责,--from-start 可强行重放)。
主动武装并每次唤醒后重新武装:watcher 退出 0 → 从你自己的光标清扫收件箱(watcher 的 state 文件不是你的收件箱光标)→ 处理并 ack → 用同一 state 文件重启 watcher。事件在重武装间隙到达也不会丢。
宣布你在听,或声明你没在听:协调任务前,向 to_agent=* 发一条 status 事件声明监听过滤器、光标与重叠提醒;回合制 Agent 则应在回复中明说"不监控"并发布光标,让请求方知道需要人工 ping——绝不谎称在监控,假 watcher 比声明缺席更糟。另外若 harness 把 shell/MCP 写入都挡在人工审批后,务必请操作员对 mempalace MCP 工具(至少 event append/ack 与 mempalace_patch_submit)和 mempalace logstream watch 放行,否则每次 ack/reply 都卡在无人看守的提示上,从对端看就是"认领后消失"。
技能的完整 System-Prompt 片段与 mempalace rules --agent <id> 渲染命令可在 shared_brain_rules.md 与 协调协议 中找到。
异常路径速查:遇到这些情况该怎么做
技能收尾给出的 unhappy paths 是最实用的决策清单:
| 症状 | 正确动作 |
|---|---|
| 任务缺失或重复 | 停下来,不要猜该执行哪一条 |
| 身份错误(任务不是发给你的) | 拒绝,并告诉用户任务实际寻址对象 |
| 基线提交不匹配 | 不要编辑;请请求方发一条修正后的请求来取代旧任务 |
| 目标未在监控 | 把 "Ready to paste" 行交给用户,说明需要人工唤醒 |
| MCP/logstream 不可用 | 运行 mempalace status 回到 setup;绝不悄悄用记忆抽屉替代协调 |
从技能到源码:整条调用链一图串联
最后把上述流程落到源码上,方便继续深入(全部为仓库内相对路径):
mempalace_task_create/mempalace task create→ tasks.py 的 create_task,内部用logstream.append_event追加一条task.request,并返回{task, handoff};mempalace task create的 argparse 定义与Ready to paste输出在 cli.py 与 cmd_task;- 认领/回复/补丁的 MCP 侧实现依次为 tool_event_ack、tool_patch_submit 以及 list/wait 工具 tool_event_list、tool_event_wait;
- 无头启动前的严格校验集中在 cmd_task 的 launch 分支:身份寻址、runner 后缀匹配、workspace 干净 checkout 与
HEAD == base_commit; - 最上层的身份纪律、光标语义与 watcher 模式见 integrations/shared/coordination-protocol.md,事件模型与 artifact 规范见 docs/rfcs/003-agent-logstream-coordination.md。
掌握这些之后,无论你是请求方还是 worker、本地 palace 拥有者还是远程共享大脑客户端,都能按同一条协议可靠地委派、认领、交付并闭环任务,让"工作推进"与"记忆沉淀"各归其位。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00