LifeOS Principal Hot-Layer Memory 深度解析:从模板文件到自治记忆系统的完整链路
LifeOS Principal Hot-Layer Memory 深度解析从模板文件到自治记忆系统的完整链路【免费下载链接】LifeOS⛰️ The Life Operating System — an intent engineering platform that moves you from your current state to your ideal state, in life and work.项目地址: https://gitcode.com/GitHub_Trending/pe/LifeOS导读PRINCIPAL_MEMORY.md是 LifeOS 中用户Principal热层记忆的唯一事实载体它平时是一个空的模板文件由后台的 Memory Reviewer 在每次会话结束后自动将关于你的耐久事实写入其中并在每一个后续提示词中自动加载让 Digital AssistantDA始终带着关于你的最新认知与你协作。本文基于该模板的完整规格与仓库源码从文件结构、条目规范、写入链路、触发时机到恢复机制逐层拆解这套无需手动维护、自动策展、自动遗忘的自治记忆系统的实现原理与配置方式。一、模板文件定位为什么它应该保持为空在 LifeOS/install/USER/PRINCIPAL/PRINCIPAL_MEMORY.md 中文件首部的引言明确给出了它的定位SAMPLE TEMPLATE — auto-curated hot-layer memory about you. It starts empty and the memory reviewer writes durable facts here as you work with your DA. Nothing to fill in manually. Pulses memory panel reads this file.翻译过来就是这是关于你的、由系统自动策展的热层记忆初始为空记忆评审器memory reviewer会在你与 DA 协作的过程中把耐久事实写入这里无需手动填写。这正是本模板与普通笔记模板的本质区别——它不是给人填写的内容容器而是一个写入面write surface由后台自治循环独占写入。因此新安装的 LifeOS 上该文件为空是预期状态模板注释原文Empty on a fresh install — this is expected而不是安装故障。与之对称的还有一份关于 DA 自身的记忆文件 DA_MEMORY.md两者共同构成双热层记忆。二、文件结构与 schema 规格逐字段拆解2.1 frontmatter记忆文件的元数据契约模板顶部的 YAML frontmatter 定义了该文件的完整规格各字段含义如下--- provenance: template # 来源标记当前文件来自安装模板 schema_version: 1 # schema 版本号供解析器做兼容判断 cap_entries: 48 # 条目数上限最多 48 条 cap_chars_per_entry: 256 # 单条目字符上限256 字符含前缀与来源标记 last_updated: 2026-01-01 # 最近更新时间由写入器自动刷新 last_updated_by: bootstrap-template # 最近更新者写入时会被记录为调用方 convention: pai-freshness-v1 # 遵循的约定主记忆新鲜度 v1Principal AI freshness ---其中cap_entries: 48与cap_chars_per_entry: 256不是装饰性配置而是被底层代码硬编码执行的边界——在 MemoryWriter.ts 中可以看到对应的常量MAX_ENTRIES 48与MAX_CHARS_PER_ENTRY 256二者必须保持一致否则会出现frontmatter 说可以写、写入器却拒绝的失配。从源码结构看frontmatter 中的cap_*主要用于让各消费方如状态栏、Pulse 面板、健康检查在不解析代码的情况下也能知道容量语义。2.2 marker 对条目的物理边界!-- BEGIN ENTRIES -- !-- END ENTRIES --这是文件中唯一必须保持不变的结构所有记忆条目只会出现在这一对注释标记之间。模板注释明确要求 keep both markers in place保持两个标记在位。这两个标记字符串在 MemoryWriter.ts 中被导出为BEGIN_MARKER/END_MARKER常量全仓库的解析器LoadMemory 钩子、Pulse 面板、健康检查、恢复工具都通过它们定位条目区。值得强调的是实现中的一个防御细节条目中不允许包含 marker 子串。解析器只在整行等于 marker时将其视为结构行而写入验证器validateAndDedup会拒绝任何包含BEGIN/END ENTRIES子串的条目防止恶意或意外内容污染条目区块见 MemoryWriter.ts。2.3 条目前缀五种受支持的事实类型写入该文件的每一条记忆都必须是前缀 事实的形式且前缀只允许以下五种大小写敏感、精确匹配、后接冒号空格前缀语义示例NAME:姓名类事实NAME: 张伟ROLE:角色类事实ROLE: 某公司技术负责人RELATION:关系类事实RELATION: 与李娜是大学同学PREFERENCE:偏好类事实PREFERENCE: 偏好简洁直接的回复 ~explicitRULE:规则类事实RULE: 部署到生产前必须确认 ~explicit前缀白名单在源码中由正则PREFIX_PATTERN /^(NAME|ROLE|RELATION|PREFERENCE|RULE): /强制MemoryWriter.ts不符合前缀的条目会被静默丢弃silent-drop不会进入文件。这保证了热层记忆永远只包含结构化的五类事实便于后续 BM25 检索与上下文注入的稳定解析。2.4 来源标记provenance tag事实的可信度分级每条条目的末尾可附带来源标记表示该事实是如何被获知的~explicit—— 用户明确陈述的事实默认未标注即视为 explicit~deduced—— 从用户陈述中逻辑推断出的事实~inferred—— 观察到的行为模式中推断出的事实。评审提示词中的记忆策展规则对此有严格要求见 MemoryReviewer.ts只写陈述性事实不写指令。例如应写PREFERENCE: prefers terse responses ~explicit偏好简洁回复而不是RULE: Always be terse总是要简洁——后者在未来重新加载时会被误读为命令。这一设计把关于用户的描述与对 DA 的指令严格分离。三、条目规范与边界约束评审提示词中的硬性规则在 MemoryReviewer.ts 内置的评审系统提示词中定义了这套文件必须遵守的完整策展契约容量红线整个文件最多48 条、每条最多256 字符含前缀与来源标记。一旦当前列表达到 39 条约 80%评审器必须先合并CONSOLIDATE再新增——合并相关条目、删除最无用/最过时的条目。任何一条超限都会导致整批写入被拒绝。取代而非叠加SUPERSEDE, dont stack用户陈述了新事实如在 A 公司工作→在 B 公司工作必须删除旧条目、写入新条目绝不两者共存。无法溯源的冲突不裁决若两条既有条目互相矛盾而本次对话无法定论评审器不得二选一那只是猜测且写成~explicit会被当作用户亲口所说。正确做法是保留最新条目、标记为~inferred并在 rationale 中说明待确认。合并重复表达同一件事的三条条目应折叠为一条。保持未来价值保留仍能减少未来方向性引导的条目丢弃已过时的。永不保存的内容会话级临时信息、环境依赖的故障、一次性任务叙述、负面工具结论X 工具未安装、任务进度/TODO、commit SHA/PR 号/分支名、任何 7 天内会过时的内容、以及这次对话里发生了什么。四、写入链路从会话到记忆文件的完整调用链热层记忆不是被某个工具直接写入的而是经过一条完整的自治管道。以 MemoryReviewer.ts 的review()为骨架链路如下4.1 步骤 1定位并提取会话转写transcriptMemoryReviewer 在~/.claude/projects/下寻找最近修改的.jsonl会话转写findMostRecentTranscript或在收到钩子传入的--input path时直接使用指定转写。随后extractRecentExchanges解析转写只保留最近的 N 轮 user→assistant 配对默认DEFAULT_TURNS 20过滤掉 tool_use/tool_result/图片等非文本块并对每条消息做 2000 字符上限截断防止单条巨型消息撑爆推理预算MemoryReviewer.ts。4.2 步骤 2注入当前记忆快照进行策展式评审关键设计在于评审器不是简单地追加新发现而是拿着当前文件的完整条目列表readCurrentMemorySnapshot读取两份热层文件让模型以op:set返回它想要的完整下一状态。提示词原文MemoryReviewer.tsYou return, via op:set, the FULL desired list for that file — the next state you want. The system REPLACES the file with your list. Whatever you omit is forgotten.即你返回完整的目标列表系统用你的列表整体替换文件你省略掉的条目即被遗忘。这就是热层记忆活着的方式——新增、合并、取代、删除全部发生在同一次评审中。遗忘forgetting是结构性的省略即驱逐eviction is omission。4.3 步骤 3模型输出解析与校验模型输出必须是一个{items:[...]}的 JSON 信封。parseReviewerOutput具备容错能力容忍前后空白与 markdown 代码围栏json … 对超过 256 字符的合并条目做确定性截断在词边界截断并保留尾部来源标记任何未知类型、字段越界或注入风险frontmatter 注入、注释注入、控制字符、YAML 歧义语法都会整批拒绝见sanitizeTypedItemForPersistenceMemorySystem.ts。校验失败时还有一次修正性重试把精确的校验错误回喂给模型要求仅修复错误指出的问题后重发完整 JSON。4.4 步骤 4按类型路由分发每一条目通过 MemorySystem.ts 的add()按类型路由该路由表由 MemoryTypes.ts 中冻结的TYPE_REGISTRY定义类型存储位置加载时机变更层级写入方式memoryPRINCIPAL_MEMORY.md/DA_MEMORY.mdalways每个提示词Tier Aset-overwrite整体替换ideaMEMORY/KNOWLEDGE/Ideas/slug.mdon-relevance相关性加载Tier Bappend追加knowledgeMEMORY/KNOWLEDGE/{People,Companies,Research}/slug.mdon-relevanceTier Bappend追加proposalMEMORY/OBSERVABILITY/pending-proposals.jsonlsurface-only仅面板展示Tier Cqueue队列注意memory类型的load_timing: always与write_mode: set-overwrite正是本模板文件的两个关键语义每轮提示词都加载、每次写入都是整体替换。set-overwrite相较增量增删的四大优势在 MemoryWriter.ts 中有明确说明无竞争面每次评审单次原子写、幂等相同输入产生相同文件、驱逐是结构性的、心智模型简单这就是我想要的最终状态。4.5 步骤 5原子写入与安全护栏MemoryWriter.setEntries在写入前做四重验证MemoryWriter.ts前缀校验静默丢弃畸形条目、长度校验超 256 字符丢弃、重复校验大小写敏感的字符串去重、容量校验超 48 条返回结构化EAT_CAP错误供模型重提。随后以file.lock排他锁 → 写file.tmp→ fsync → 原子 rename的方式落盘MemoryWriter.ts并对目标路径做白名单校验——仅允许PRINCIPAL_MEMORY.md与DA_MEMORY.md两个文件任何其他路径返回EINVAL_PATH。写入前还会执行两道防丢失护栏MemoryWriter.tsESUSPECT_SHRINK灾难性收缩若现有条目 ≥10 条而新列表 3 条或删除超半数且零新增判定为疑似幻觉输出拒绝写入ESUSPECT_EROSION缓慢侵蚀单次写入净删除 ≥2 条删除数 − 新增数即被拦截——这是针对 LLM 重转录时每轮悄悄少几条的慢性数据丢失模式设计的护栏。合法的深度整合可通过allowDrastic: true放行。同时每次 Tier A 写入前都会把旧文件内容快照到MEMORY/OBSERVABILITY/memory-snapshots/环形缓冲区每个文件保留最近 30 份使每一次自治写入都可经由 MemoryRestore.ts 单独回滚。五、触发机制谁、何时启动记忆评审5.1 MemoryReviewFire 钩子评审节奏的唯一拥有者触发评审的是 MemoryReviewFire.hook.ts这是一个 Stop 钩子——每次主会话primary session停止时执行。其节奏逻辑见 MemoryReviewFire.hook.ts本会话turn_count_since_last_review加一记录last_message_at当本会话轮次 ≥turn_threshold且距全局last_review_at≥min_minutes_between分钟时分离式detached启动bun MemoryReviewer.ts review并重置本会话计数、打上全局时间戳。这里有个刻意的不对称设计轮次阈值按会话计问的是这段对话是否足够有内容值得评审时间间隔阈值全局计是推理量护栏防止 N 个并发会话每窗口跑 N 次评审。轮次计数存储在 per-session 状态文件MEMORY/STATE/memory-review/session_id.json修复了此前全局计数被并发会话互相清零的问题public issue #1711。5.2 评审节奏配置memory-review.json节奏参数集中在 memory-review.json{ schema_version: 1, turn_threshold: 8, min_minutes_between: 30, idle_threshold: 2, confidence_threshold: 0.70, notes: Cadence for the autonomic memory reviewer: it considers writing durable memory only after turn_threshold turns, min_minutes_between minutes since the last run, and idle_threshold idle turns. Tier-C proposals auto-apply at confidence_threshold. Conservative defaults; tune after use. }参数默认值含义turn_threshold8单会话至少 8 轮对话才考虑评审min_minutes_between30距上次评审至少 30 分钟全局护栏idle_threshold2空闲轮次阈值confidence_threshold0.70proposal 自动应用的最低置信度见下文钩子默认回退值turn_threshold: 8、min_minutes_between: 30在 MemoryReviewFire.hook.ts 中与配置文件一致confidence_threshold的默认回退0.70则在 MemoryReviewer.ts 中加载。5.3 钩子会剥离凭证值得一提的安全细节spawnReviewer在派生评审进程时显式删除ANTHROPIC_API_KEY、ANTHROPIC_AUTH_TOKEN、CLAUDE_CODE等环境变量MemoryReviewFire.hook.ts并以stdio: ignore、detached: true、unref()方式运行——评审进程完全独立于会话生命周期且不携带宿主会话的密钥。六、加载链路为什么每一轮对话都记得你6.1 LoadMemory 钩子每轮注入写入只是闭环的一半。读取侧由 LoadMemory.hook.ts 承担它是一个UserPromptSubmit 钩子在每一个提示词提交前把两份热层文件渲染为lifeos-memory上下文块注入lifeos-memory ## PRINCIPAL MEMORY [12/48 entries · 2140/12288 chars] NAME: 张伟 ROLE: 某公司技术负责人 PREFERENCE: 偏好简洁直接的回复 ~explicit ... ## DA MEMORY [3/48 entries · 430/12288 chars] ROLE: LifeOS 数字助理 ... /lifeos-memory这里可以看到容量计算的另一种形式48 条 × 256 字符 ≈ 12288 字符/文件capChars 12288两份合计约 24K 字符上限。该钩子是热路径钩子必须廉价只渲染条目、不含帮助注释任何错误只写 stderr 并返回空绝不阻塞提示词。子代理进程subagent通过环境标记被识别并跳过——每轮记忆循环只服务于主用户会话LoadMemory.hook.ts。6.2 共享解析器读写永不分歧LoadMemory 钩子与写入器共用同一个解析器parseMemoryContentMemoryWriter.ts其注释强调Every consumer (LoadMemory hook, Pulse memory panel, MemoryHealthCheck, MemoryRestore) imports it — reader and writer can never diverge again. Never write a second marker-parsing implementation.所有消费者都导入它——读写永不分歧永远不要写第二套 marker 解析实现。解析器采用整行识别 marker、宽容解析模型marker 只在作为完整修剪行时才被当作结构行任何前缀合法的行无论是否在 marker 区块内都被视为条目从而即使文件历史上出现过END在BEGIN之前的错乱也能完整恢复条目而不会静默丢失记忆。6.3 检索支持除了全量注入热层文件还参与 BM25 相关性检索——MemorySystem.ts 的find()将两份_MEMORY.md与知识笔记一并纳入语料供按需召回MemoryRetriever.ts。七、状态可见性Pulse 面板与状态栏该文件的实时状态有多个可见面Pulse 记忆面板Pulse 的 memory.ts 模块通过GET /api/memory提供完整快照状态、上次运行、健康、两文件内容、proposals、近期运行记录内部同样复用parseMemoryContent解析文件内容memory.ts状态栏LIFEOS_StatusLine.sh与 MemoryStatus.ts 提供 记忆状态行评审的全局镜像状态MEMORY/OBSERVABILITY/review-state.json持续被各消费方读取健康检查MemoryHealthCheck.ts 依据 48/256 容量与写入日志评估记忆健康度评审运行摘要记录于reviewer-runs.jsonl每次写入事件记录于memory-writes.jsonl含 prior_count/new_count、逐条 evictions/additions为防侵蚀审计提供完整证据。八、CLI 操作与验证手段仓库中的记忆子系统提供一组可直接运行的命令行接口均以 bun 执行# 读取当前热层记忆含容量统计与非法条目报告 bun MemoryWriter.ts read ~/.claude/LIFEOS/USER/PRINCIPAL/PRINCIPAL_MEMORY.md # 以 stdin 逐行条目写入set-overwrite printf NAME: 张伟\nPREFERENCE: 偏好简洁回复 ~explicit\n | \ bun MemoryWriter.ts set ~/.claude/LIFEOS/USER/PRINCIPAL/PRINCIPAL_MEMORY.md # 手动触发一次记忆评审最近 N 轮对话 bun MemoryReviewer.ts review --turns 20 # 对指定转写评审不写盘仅提取与构造提示词 bun MemoryReviewer.ts review --input transcript.jsonl --dry-run # 查看类型注册表与存储路径解析 bun MemoryTypes.ts list bun MemoryTypes.ts resolve memory {actor:principal} # 内置冒烟测试注意MemoryWriter 的 test 不触碰真实记忆文件 bun MemoryWriter.ts test bun MemorySystem.ts test需要特别提示bun MemoryWriter.ts test的设计原则是不触碰真实记忆文件其冒烟测试曾因在真实文件上清理时误清空记忆而重构为纯内存夹具见 MemoryWriter.ts 的注释对已装载记忆的安装环境是安全的。九、故障自愈与边界防护小结综合以上源码分析PRINCIPAL_MEMORY.md所在的记忆子系统围绕不能丢、不能错、不能静默损坏设计了多层防御路径白名单——写入器只认两份热层文件EINVAL_PATH条目 schema 强制——五前缀、256 字符、48 条上限、marker 隔离畸形静默丢弃写入竞争防护——排他锁 原子 rename fsync锁支持带 pid/host 时间戳的陈旧锁恢复MemorySystem.ts 的staleLockReason决策矩阵本机 pid 消失立即破锁无法验证的持有者按 5 分钟 TTL 兜底防丢失护栏——灾难性收缩ESUSPECT_SHRINK与缓慢侵蚀ESUSPECT_EROSION双重拦截可回滚——每次写入前快照到 30 份环形缓冲MemoryRestore.ts 可单独恢复读写统一解析——单解析器模型杜绝写进去读不出的分歧完整可观测——memory-writes.jsonl、reviewer-runs.jsonl、reviewer-fires.jsonl、memory-locks.jsonl构成审计证据链。十、总结PRINCIPAL_MEMORY.md表面看是一个近乎空白的模板文件实际上它是 LifeOS 自治记忆系统的热层出口前端由MemoryReviewFire钩子按节奏触发MemoryReviewer中端由MemoryTypes的冻结注册表完成类型路由、MemorySystem统一入口调度后端由MemoryWriter以set-overwrite 原子写 防侵蚀护栏落盘最终由LoadMemory钩子在每个提示词中全量回灌。这套设计把记住用户从手工笔记变成了一个有容量边界、有策展规则、有遗忘机制、有安全护栏的自治闭环——空文件不是终点而是记忆生命周期的起点。若要深入建议依次阅读 MemoryWriter.ts、MemorySystem.ts、MemoryReviewer.ts 与 MemoryTypes.ts再对照 LoadMemory.hook.ts 与 MemoryReviewFire.hook.ts 两个钩子理解闭环两端。【免费下载链接】LifeOS⛰️ The Life Operating System — an intent engineering platform that moves you from your current state to your ideal state, in life and work.项目地址: https://gitcode.com/GitHub_Trending/pe/LifeOS创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考