memU × Hermes 桥接任务注册指南:把 Hermes 会话变成持久记忆的定时流水线(prepare → self-evolve → commit)
memU × Hermes 桥接任务注册指南把 Hermes 会话变成持久记忆的定时流水线prepare → self-evolve → commit【免费下载链接】memUPersonal memory across agents项目地址: https://gitcode.com/GitHub_Trending/mem/memU导读本文讲解如何在 Hermes Agent 上为 memU 注册一个周期性的无头headless桥接任务默认每小时一次让它定期把 Hermes 会话中的新活动挖掘成 memU 的记忆文件、技能skill与资源resource提交。读完本文你将掌握prepare → self-evolve → commit 三段式流水线的完整原理、基于系统 cron / launchd / Windows 任务计划程序的注册方法而不是 Hermes 原生cronjob、以及为什么必须把流水线提示词放进文件而非 crontab 行内——这是一份可以直接交给 Agent 执行、也可以由工程师手工照做的部署手册。本文是 Hermes 适配器安装指南 中注册桥接任务Part 2这一环节的独立细化文档核心依据是 BRIDGING_TASK.md 原文并结合 memu.hosts.bridging 包源码逐一验证。一、桥接任务是什么一段只有头尾是代码的流水线memU 对每个 Host 适配器都暴露一套相同的动词retrieve、install-instruction、prepare、commit、verify-resources、doctor、docs因为其背后的流水线是 Host 无关的参见 host_cli.py 与 ADR 0008/0009。对 Hermes 而言桥接任务把最近 Hermes 会话里发生了什么变成memU 里可检索的持久记忆分三步Prepare代码——memu-hermes prepare扫描 Hermes 会话中的新活动把 memU 当前的 recall 文件镜像到~/.memu/hosts/hermes/memory与~/.memu/hosts/hermes/skill并按内容哈希做快照最后把编号的job 指令文件写入~/.memu/hosts/hermes/jobs/1.txt、2.txt、…。Self-evolve真实 Agent 工作—— Agent 按数字升序逐个打开 job 文件并执行把一个会话挖掘成用户记忆、把一个会话挖掘成技能、并描述会话触碰过的文件。对任何 job什么都不做都是合法且常见的结果。Commit代码——memu-hermes commit对受跟踪目录与第 1 步的快照做 diff把 Agent 实际创建或修改的内容提交回 memU。只有第 1 步和第 3 步是代码第 2 步是真正的 Agent 工作读会话记录、做判断、写 Markdown。因此定时任务的 prompt 必须指示 Agent 去执行它而不是让它 shell 出去调用某个脚本。这也正是 pipeline.py 模块开头注释所强调的设计Nothing here knows what a Codex is——中间步骤的模板由 instructions.py 生成每个 job 自包含、自带具体路径Agent 不需要做任何路径推理。记忆与技能的双模式持久性在云模式和本地模式下记忆与技能都是持久化的。云模式下当前服务会接收这条不变流水线提交的工作区资源workspace resources但暂时不会持久化或检索它们——这与 INSTALL.md 中的说明一致部署时应向用户说明这一限制。与原文档的衔接注册桥接任务属于INSTALL.mdmemu-hermes docs install完整安装流程的一部分但本文档本身可以独立使用——也就是说即使 memU 已经装好、只是调度缺失也可以单独执行本文的步骤。二、前置条件Prerequisites在注册调度任务之前必须确认两件事memU 已安装且memu-hermes在PATH上。用memu-hermes doctor验证若失败先执行 INSTALL.md 的 Part 1。Hermes 能从 cron 无头运行且有权限执行memu-hermes并写入~/.memu/。如果 Hermes 使用了非默认的HERMES_HOMEcron 环境必须导出它且 prompt 的 prepare 步骤必须传入--session-dir $HERMES_HOME/state.db。关于--session-dir的必要性可以看 sessions.pyHermes 是唯一一个会话日志只存在于 SQLite而非磁盘上的 JSONL的受支持 Host——会话与消息历史放在 Hermes home默认~/.hermes遵循HERMES_HOME下state.db的两张表sessions、messages中~/.hermes/sessions/saved/只保存手工快照不会被挖掘。state_db_path()的解析优先级依次是HERMES_HOME环境变量 → Windows 的LOCALAPPDATA→~/.hermes。另外注意_connect()以?modero只读打开数据库——桥接任务绝不能抢占 Hermes 的写锁因为网关和活跃的 CLI 会话共享这个 WAL 模式的数据库。三、Step 1 —— 敲定调度计划如果用户的请求里没有包含调度计划就询问用户。默认每小时一次cron 表达式0 * * * *本地时间。创建之前务必与用户确认。四、Step 2 —— 注册定时运行Unixcron / launchd4.1 先决条件禁止使用 Hermes 原生cronjob不要用 Hermes 原生的cronjob来做 memU 桥接要用这里描述的 OS 调度器。如果机器上有旧版指南创建的注册必须先迁移运行hermes cron list --all对每个名字恰好等于{{task_name}}即memu-bridging-hermes见 cli.py 中HostSpec的task_name字段的 job运行hermes cron remove job-id再次列出并确认没有残留。如果列出或移除失败必须停下来——绝不要在原生副本旁边再加一个 OS 任务否则会出现双份调度、重复提交。4.2 关键警告绝不把流水线 prompt 内联进 crontab绝不把流水线 prompt 内联在 crontab 条目里。引用的 prompt 约 1.2 KB而 cron 在交给/bin/sh之前会把 crontab 行截断到约 1 KB——shell 收到一条引号被截断的命令每次 tick 都会瞬间死亡报错unexpected EOF while looking for matching 邮件发到/var/mail/$USER除此之外任何地方都看不到hermes根本不会启动现场数据一条内联的 Hermes 条目正是在每个 tick 上以这种方式失败。这是 Windowsschtasks /TR长度限制memU#539在 Unix 上的姊妹问题修复方式也一致prompt 住在文件里crontab 行保持短小。4.3 第一步把流水线 prompt 写入文件verbatim单行把下面的内容逐字verbatim写成单行保存到~/.memu/hosts/hermes/bridge-prompt.txtRun the memU bridging pipeline. Do the four steps strictly in order; do not skip a step even if the previous one looks like it produced nothing. 1. LEFTOVERS. If ~/.memu/hosts/hermes/jobs/ already contains job files, they are unfinished work from an earlier run (a crash, or the install itself) — process them exactly as step 3 describes, then run: memu-hermes commit — and only then continue. 2. PREPARE. Run this exact command with bash: memu-hermes prepare — it regenerates ~/.memu/hosts/hermes/jobs/. If the command exits non-zero, stop and report the error. 3. SELF-EVOLVE. List ~/.memu/hosts/hermes/jobs/*.txt and process them in ascending numeric order (1.txt, then 2.txt, …). The count changes every run — always glob and sort. If there are no job files, skip to step 4. For each job file: read it and follow its instructions to the letter. Each job is self-contained and already carries the concrete paths it needs. Emitting no files for a job is a valid outcome; do not invent content. 4. COMMIT. Run this exact command with bash: memu-hermes commit — it commits whatever the jobs created or changed. If it exits non-zero, report the error. ON FAILURE. If step 2 or step 4 exited non-zero, run this once before you stop: memu-hermes report error --stage remember --detail a full account of what went wrong — that detail is all a memU engineer gets to work out what is broken on this machine, so be generous: which step, what you ran, what happened instead, what you already tried, and what you think the cause is. Write it as prose for a human, not as a transcript — do not paste the traceback or raw command output, which the CLI already reports on its own, and keep credentials, absolute paths, and memory or transcript text out of it. Ignore any failure of that command; it is never part of the run. Finish with a one-line summary: how many jobs ran (leftovers included) and what was committed.这个 prompt 的四步与第一节的流水线一一对应其中LEFTOVERS 步骤是崩溃恢复的关键prepare会删除未处理的 job 文件且游标已经把这些会话标记为已读所以此刻被跳过的内容以后永远不会再被挖掘——先排空遗留项能把半途而废的周期变成有界的返工而不是静默丢失详见下文Notes。ON FAILURE分支把失败现场以散文形式报告给 memU 工程师host_cli.py 中_cmd_report的--detail帮助文本同样强调绝不贴 traceback、绝不包含凭据/绝对路径/记忆内容。4.4 第二步写bridge.sh包装脚本并chmod x注意无头标志Hermes 的一次性标志是-z/--oneshot不是-p——照抄其他 Host 的桥接脚本而忘记修正这个标志已经在现场造成过安装故障#!/bin/sh # memU bridging for Hermes — invoked by cron. # The pipeline prompt lives in bridge-prompt.txt because cron truncates # crontab lines around 1 KB (see BRIDGING_TASK.md). DIR$HOME/.memu/hosts/hermes # Single-instance lock: an hourly tick can fire while a long backlog run is # still going; a second run would race it on jobs/ and double-commit. # mkdir is atomic; a stale lock older than 3h is reclaimed. Tradeoff: a # legitimate run longer than 3h loses its lock to the next tick and can # double-run — accepted deliberately, because the alternative (no reclaim) # lets one crashed run wedge the schedule forever. Do not fix one side # without weighing the other. LOCK$DIR/.bridge.lock if ! mkdir $LOCK 2/dev/null; then if [ -n $(find $LOCK -maxdepth 0 -mmin 180 2/dev/null) ]; then rmdir $LOCK 2/dev/null mkdir $LOCK 2/dev/null || exit 0 else echo $(date %F %T) skipped: another bridging run is in progress $DIR/bridge.log exit 0 fi fi trap rmdir $LOCK 2/dev/null EXIT INT TERM export MEMU_BRIDGING_RUN1 hermes -z $(cat $DIR/bridge-prompt.txt) $DIR/bridge.log 21脚本要点逐一解读单实例锁mkdir是原子的作为锁足够可靠超过 3 小时180 分钟的陈旧锁会被回收。这是有意权衡不回收会让一次崩溃的运行永远卡死调度表回收则允许超过 3 小时的合法运行在下一个 tick 上被顶掉。文档明确警告不要只修一边。MEMU_BRIDGING_RUN1这是本次运行是调度产生的桥接运行的标记。prepare会据此把自己这条会话排除在挖掘之外见 host_cli.py 的_cmd_prepareself_sessions.is_bridging_run(Path.cwd(), layout.base)判定为桥接运行时才读取HERMES_SESSION_ID并把它记入~/.memu/hosts/hermes/.self_sessions.hermes.json避免 memU 自掘其尾——issue #606。手工运行prepare的真人会话不会被标记所以手动调试时当前对话仍可被挖掘。-zHermes 的 oneshot 标志见 cli.py 中HostSpec.schedule_command hermes -z {prompt}。输出落盘stdout/stderr 全部追加到~/.memu/hosts/hermes/bridge.log。这是内联条目做不到的——内联条目丢弃输出失败只留一封 cron 邮件落盘后一次失败的 tick 会留下可诊断的痕迹。4.5 第三步crontab 首行必须是PATHcrontab 的第一行是一条PATH。cron 只带一个光秃秃的/usr/bin:/bin运行流水线需要的二进制pipx 和 npm 安装会落到~/.local/bin和/opt/homebrew/bin不在其中运行会在流水线启动前就死于command not found。在注册时推导出来写在条目上方PATH$(dirname $(command -v memu-hermes)):$(dirname $(command -v hermes)):/usr/local/bin:/usr/bin:/bin机器相关的这一事实放在 crontab 里——机器事实本来就该归机器流水线 prompt 本身保持 verbatim 待在自己的文件里。4.6 第四步cron 条目cron 不会在命令字段展开~但它会把整行交给/bin/sh执行所以$HOME可用写一个字面绝对路径同样没问题0 * * * * $HOME/.memu/hosts/hermes/bridge.sh # {{task_name}}如果明确选择了 launchd把其 Label 设为{{task_name}}即memu-bridging-hermes。prompt 块是固定的只有 cron 表达式是用户的选择。没有任何机器特定的东西泄漏进 prompt——流水线完全通过PATH命令被调用。五、Step 3 —— 确认验证而不是相信你 shell 里的PATH证明不了调度器的PATH。两个真正算数的检查命令可解析性检查env -i PATH/usr/bin:/bin /bin/sh -c command -v memu-hermes这个命令失败恰恰就是条目需要PATH行的原因有了那行PATH命令必须能从其列出的目录解析出来。硬核检查真的触发一次运行。临时把调度拨快一分钟或手工运行bridge.sh用env -i PATH... HOME$HOME /bin/sh -c然后验证文件系统痕迹——会话游标与jobs/的时间戳前移了、~/.memu/hosts/hermes/bridge.log变大了——而不是相信运行自身的摘要。现场数据两次裸环境下的调度运行曾在command not found的情况下报告completed successfully。向用户汇报调度注册在哪里、cron 用文字怎么描述。并说明首次运行要等有新 Hermes 会话才有活干。六、Windows任务计划程序路线Step 2–3 是 cron/launchd——纯 Unix。在 Windows 上不要手写schtasks条目也不要用 Hermes 原生cronjob。先完成 Step 2 开头的遗留原生任务清理然后使用共享助手memu-hermes schedule install # register the hourly OS task memu-hermes schedule verify # prove a resolvable CLI memu-hermes schedule status # last run / next run memu-hermes schedule uninstall # remove itinstall会把 prompt 加一个小型 PowerShell 包装器写到~/.memu/hosts/hermes下把捆绑的hermesCLI 解析成绝对路径并以S4U主体注册任务{{task_name}}——隐藏、可在注销状态下运行、并且能在机器关机时补跑一次错过的运行。--interval minutes改变节奏默认 60。上面的迁移检查确保流水线只存在于 OS 调度器中。与 Claude Code 或 Cursor 不同Hermes 把客户端和 CLI 一起发布使用同一套运行时/配置没有单独的 CLI 安装或无头认证步骤这一点在 cli.py 的HostSpec中也得到印证needs_headless_auth为 False。运行后同样要检查文件系统痕迹而非相信摘要~/.memu/hosts/hermes/jobs/的时间戳与会话清单必须前进。从源码看schedule子命令由共享的 host_cli.py 的_cmd_schedule在platform.system() Windows时接入非 Windows 平台会提示转向docs task的 cron/launchd 章节不会触碰任何东西。七、Notes设计细节与故障语义原文档的 Notes 部分是理解这条流水线为什么这样做的关键逐条展开并与源码对应7.1 遗留项先于 prepare 执行Leftovers run before prepare运行开始时磁盘上已存在的 job 文件是未完成的工作——可能是一次死于流水线中途的运行也可能是安装过程自身的验证。prepare会删除未处理的 job 文件且游标已把这些会话标记为已读所以此刻被跳过的东西永远不会再被挖掘。先排空遗留项能把半途而废的周期变成有界的返工而不是静默丢失。对应到代码LEFTOVERS 步骤先memu-hermes commit再进 PREPARE而 host_cli.py 的_cmd_commit在无前导prepare时也完全合法它不打开新周期因而不会发出周期级事件——见_record_commit中cycle event 以 run marker 为门的设计。7.2 幂等且增量Idempotent and incrementalprepare在~/.memu/hosts/hermes/.session_manifest.hermes.json中跟踪按会话计的消息数游标以会话 id 为键——消息对每个会话是 append-only 的所以计数游标正是其他 Host 使用的行游标。源码印证transcripts.py扫描按最近活跃优先发现会话第一个已读且无新记录的会话会终止扫描更旧的会话不可能有更新的活动新记录被切分为N.jsonl纯对话与N_full.jsonl对话工具调用两种切片。游标是暂存的prepare只写.pending文件只有成功的commit才把它提升为正式游标layout.py 中session_manifest与session_manifest_pending两个文件的分离以及 pipeline.py 中commit用os.replace(pending, manifest)的升级动作——所以一次裸prepare或一次死在 commit 之前的运行都不会推进持久游标所有未挖掘的 turn 下次仍可选择issue #518状态在持久成功后才前进而非意图。7.3 排序是承重的Ordering is load-bearing记忆 job 在技能 job 之前资源描述 job 最后。始终按数字升序。instructions.py 的prepare_instruction_jobs展示了具体编号方案N 个会话产生1..N的记忆 job挖掘N.jsonl、N1..2N的技能 job挖掘N_full.jsonl然后 pipeline.py 的prepare在有会话时追加一个编号为2*N1的资源 job。技能 job 负责把会话触碰过的文件追加进资源日志resource_log资源 job 依赖它——这就是排序承重的完整链路。7.4 工作树是 Host 作用域的The working tree is host-scoped~/.memu/hosts/hermes/下的所有东西都是这个适配器的运行期工作状态其他 memU Host 适配器永远不会与它竞争host_cli.py 注释明确Codex 使用其遗留的~/.memu工作树其后每个 Host 默认~/.memu/hosts/host——这是 ADR 0010 解决的 ADR 0009 遗留问题。它们共享的持久后端由~/.memu/config.env中的MEMU_MEMORY_MODE选择本地模式使用其中的MEMU_DB。这意味着一个 Host 的会话教给 memU 的东西另一个 Host 可以检索到。7.5 失败处理Failure handlingStep 1 和 Step 3 是唯一应该中止运行的失败点。Step 2 中的do nothing job 是正常结果不是错误——instructions.py 的两个模板都反复强调这一点A no-op is a perfectly good outcome — do not invent a memory to justify the run.7.6 提交是原子的、可恢复的源码补充commit 的实现 顺序是对受跟踪目录做 diff基于 manifest.py 的 SHA-256 内容哈希——用内容而非 mtime判断变更字节相同的重写正确地被视为未变删除不返回静默丢弃→ 读取变更的 recall 文件与资源 → 提交到后端 →成功后才重拍快照、提升游标 →最后才清理jobs/与sessions/的临时文件。清理放在最末正是为了让崩溃在更早位置发生时下一次运行的 LEFTOVERS 步骤能完整恢复。7.7 资源校验源码补充技能 job 写入的 touched-file 日志是不可信的——路径可能相对、重复或已被删除。verify-resourcesmemu-hermes verify-resources通过 resources.py 的verify_resource_log过滤只保留以/或~开头且真实存在的绝对路径按首次出现顺序去重最多 50 条MAX_RESOURCES。生成的resources.md中description:行为空由资源 job 填写Agent 填null或留空读不了的结果会被 read_resources 在提交时丢弃——这不是失败。八、完整的安装上下文便于定位桥接任务注册只是 INSTALL.md 的 Part 2record 缝同文档还包括Part 1安装memu-cli、用memu-hermes config配置后端云模式或本地模式注意--db必须用绝对路径、嵌入身份的--db/--embed-provider/--embed-model一旦设置config拒绝更改、memu-hermes doctor验证Part 3用memu-hermes install-instruction把检索指令内联写进~/.hermes/SOUL.mdinject 缝。Hermes 是内联型Host 而非技能型 Host——它的 skills 目录是拉取式的pull-on-demand一条每轮先检索的技能不会被可靠地呈现所以检索过程必须全文内联cli.py 中skills_dir留空的原因注释里记录了现场观测自然 Session-B 套件上 0/8 召回-s memu-retrieve强制预载后立即恢复。安装结束无论成败都要以memu-hermes report install或memu-hermes report error --stage install --detail …收尾让 memU 知道结果。九、排障速查症状原因处理每个 tick 报unexpected EOF while looking for matching 只有/var/mail/$USER有记录prompt 被内联进 crontab行被截断到 ~1 KB把 prompt 移到bridge-prompt.txtcrontab 只留一行bridge.sh调用运行报command not foundmemu-hermes或hermescron 的裸PATH不含~/.local/bin、/opt/homebrew/bin在 crontab 首行加推导出的PATHhermes没启动或行为异常把别的 Host 的-p桥接脚本直接抄了过来改用-z/--oneshotHermes 的一次性标志运行自报成功但没有产出调度环境太裸命令根本没跑起来用文件系统痕迹验证jobs/时间戳、游标、bridge.log是否前进长时间运行的周期与下一个 tick 竞争、双重提交锁回收的已知权衡3h 的运行会被顶掉属于设计接受的边界情况不要单方面改锁逻辑Windows 上手写schtasks出错Windows 有共享助手可用用memu-hermes schedule install/verify/status/uninstall十、相关源码导航桥接流水线实现pipeline.pyprepare/commit、transcripts.py会话切片与游标、manifest.py快照/diff、layout.py工作树布局、instructions.pyjob 模板、resources.py资源校验Hermes 会话源与 CLI 声明sessions.pySQLite 只读会话源、cli.pyHostSpec声明共享 CLI 框架host_cli.pyprepare/commit/schedule/report等命令的共享实现安装与卸载指南INSTALL.md、UNINSTALL.md相关架构决策ADR 0008两个集成面、ADR 0009CLI 打包、ADR 0010多 Host 适配器、ADR 0013自更新指令模板、ADR 0014分页 list-all、ADR 0015桥接不得自掘其尾、ADR 0016客户端事件上报见 docs/adr【免费下载链接】memUPersonal memory across agents项目地址: https://gitcode.com/GitHub_Trending/mem/memU创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考