LifeOS 用户定制层完全指南:CUSTOMIZATIONS 目录的契约、结构与覆盖机制
2026/9/14 5:32:46 网站建设 项目流程

LifeOS 用户定制层完全指南:CUSTOMIZATIONS 目录的契约、结构与覆盖机制

【免费下载链接】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

导读

LifeOS 是一个「意图工程平台」(intent engineering platform),它的框架层内置了大量通用的 Skills、Agents、动作执行器与流水线执行器,但每一个真实用户的生命系统应当是独一无二的。CUSTOMIZATIONS/目录就是 LifeOS 为此设计的用户专属扩展层:所有需要“针对当前使用者而非所有 LifeOS 用户”生效的个性化内容都存放在这里,由系统组件在运行时动态叠加。读完本文,你将掌握 CUSTOMIZATIONS 目录的契约规则、SKILLS 与 ARBOL 两棵子树的组织方式、个人覆盖优先于系统默认的解析顺序,以及“何时该放、何时绝不该放”的边界判断标准。

CUSTOMIZATIONS 是什么:从「通用框架」到「你的 LifeOS」

打开仓库中的 CUSTOMIZATIONS/README.md,开篇即给出定义:LifeOS 框架自带通用的 skills、agents、action runners 和 pipeline executors,而CUSTOMIZATIONS/目录存放的是这些通用组件在运行时叠加(layer over)的用户内容——正是这些东西,让你的 LifeOS 与每一台其他安装的 LifeOS 都不同。

关键句值得反复咀嚼:

This directory holds the per-user content that those generic components layer over at runtime — the things that makeyourLifeOS different from every other LifeOS install.

也就是说,框架负责「公共的、可发布的、面向所有人的」行为,定制层负责「私人的、只属于这一个 principal 的」行为。二者不是两套系统,而是同一套系统在运行时的两层叠加:skill body 保持通用,用户文件在运行时覆盖其上

这一点与仓库中的系统级文档完全一致。SystemUserBoundary.md 用四个 Zone(SYSTEM / USER / INTERFACE / RUNTIME-STATE)描述了整棵树的边界结构,其中USER区域明确包含 identity、TELOS、projects、integrations、contacts、finances、health、business 以及customizations;而 LifeosSystemArchitecture.md 则从架构层面说明为什么必须存在这一层用户内容挂载点。

契约(Contract):系统组件必须在这里找用户内容

原文档将最重要的规则定义为一条契约

Anything running a system component MUST look here for user content that applies tothis principal but not every LifeOS user.

即:任何运行系统组件的代码,必须到 CUSTOMIZATIONS 查找“只适用于当前 principal、而不适用于所有 LifeOS 用户”的内容。该契约具体展开为两条:

  • Skills读取CUSTOMIZATIONS/SKILLS/<SkillName>/,用于存放用户偏好、来源清单(source lists)、声音档案(voice profiles)、项目名称以及其他公共 skill 主体无法包含的上下文。skill body 始终保持通用,用户文件在运行时叠加。
  • Arbol读取CUSTOMIZATIONS/ARBOL/,用于存放用户的 actions、pipelines、flows 与 worker 代码。解析顺序永远是个人优先(personal-first)CUSTOMIZATIONS/ARBOL/ACTIONS/<name>覆盖LIFEOS/ARBOL/Actions/<name>PIPELINES/FLOWS/同理。用户副本胜出(The user copy wins)

这条“个人优先覆盖”的解析顺序是整个定制层最核心的机制:你不需要 fork 任何系统组件,只需要在正确的位置放下同名的覆盖文件,运行时就会自动采用你的版本。

目录结构:SKILLS 与 ARBOL 两棵子树

原文档给出了完整的目录骨架:

CUSTOMIZATIONS/ ├── SKILLS/ ← per-skill override files (one subdir per customized skill) └── ARBOL/ ← user actions, pipelines, flows, and Arbol worker code ├── ACTIONS/ ├── PIPELINES/ ├── FLOWS/ └── (worker code: Workers/, cli/, scripts/, etc.)

在仓库的 CUSTOMIZATIONS 目录下,可以看到这一模板的实物形态:

  • SKILLS/README.md— 技能定制说明;
  • ARBOL/ACTIONS/README.md— 动作模块说明;
  • ARBOL/PIPELINES/README.md— 流水线注册说明;
  • ARBOL/FLOWS/README.md— 流程编排说明。

新装状态下,这些子目录“Empty / Just this README”——即只有说明文档,真正的用户内容会在你实际使用 LifeOS 的过程中逐渐生长出来。这是一种刻意设计:定制内容由用户主动显式写入,而不是由框架预置

SKILLS/:不改 skill,只覆盖行为

SKILLS/README.md 将 SKILLS 目录的目的概括为:

Per-skill overrides — the place to change a default skill behavior without forking the skill itself.

要点如下:

  • 每个被定制的 skill 一个子目录,目录名与 skill 名一致,例如CUSTOMIZATIONS/SKILLS/<SkillName>/
  • 每个支持定制的 skill 会自行文档化它从覆盖目录读取哪些文件——通常是配置、模板或 prompt 片段,skill 在运行时将其与默认值合并(merges over its defaults);
  • 填充方式是由用户显式进行的:只有当你确实想覆盖某个 skill 的默认行为时才创建子目录,否则保持为空,skill 以出厂默认行为运行。

仓库中大量 skill 文档都在实践这一约定。例如 LocalIntelligence/SKILL.md 及其 UserSources.ts 工具、Fabric/SKILL.md、SuggestSkills/SKILL.md 等文档中均提及在CUSTOMIZATIONS/SKILLS/下存放用户专属来源或偏好。这套约定的核心收益是:skill 是公共资产,可以在发布、升级、共享时保持纯净;你的品味、你的来源、你的项目、你的声音,全部安全地留在私有定制层

ARBOL/:Actions、Pipelines、Flows 三原语

ACTIONS/README.md 说明 Actions 是可复用的动作模块——LifeOS 流水线与流程组合成更大工作流的原子工作单元。每个 action 是一个自包含子目录(典型命名A_<NAME>/,或按extract/format/transform/等类别目录分组),内含:

  • action.json— 清单:名称、描述、输入/输出 schema、requires(能力声明);
  • action.ts— 实现:execute(input, ctx) → output

Actions 的关键约束是:输入 → 单一操作 → 输出,无旁路通道、无共享状态。保持小而可组合是全部要点。你之所以要构建 action,是因为某段逻辑将被两个以上的 flows 或 pipelines 复用,或者你希望用经过良好测试的独立单元代替散落在多个 skill 中的内联代码。

PIPELINES/README.md 说明 Pipelines 是顺序处理链——把 actions 组合成线性工作流,前一个 action 的输出直接作为下一个 action 的输入。目录中存放一个pipeline-index.json注册表,外加每个 pipeline 一个 yaml 文件。Pipeline 刻意比 Flow 更简单:无分支、无条件、无并行扇出。如果工作就是“先 A,后 B,再 C”,pipeline 就是正确形态。新增方式:把 yaml 文件丢进目录,并在pipeline-index.json中登记。

FLOWS/README.md 说明 Flows 是分支式工作流定义——把 actions 组合成带条件路由、并行执行与错误处理的处理图(processing graph)。目录中存放一个flow-index.json注册表,外加每个 flow 一个 yaml 文件。Flow 描述的是 action 之间的有向图、路由条件、并行分支的扇出与汇合、以及失败如何传播。当工作流需要决策、重试或并发步骤时用 Flow;纯线性工作用 Pipeline

三种原语的层级关系与命名规范

更完整的机制定义可以参考仓库中的 ArbolSystem.md(注意:该文档同时明确声明 Arbol 云端实现是维护者的私有基础设施,不随 OSS 发布随附,本文档作为架构蓝图与参考规范存在;LIFEOS/ARBOL/本地执行树在公共发布中被 rsync 排除)。其核心层级为:

Action ---> Pipeline ---> Flow (unit) (chain) (scheduled system)
原语前缀做什么组合方式
ActionA_单一工作单元(LLM 调用、API 调用、shell 命令)不组合
PipelineP_以管道模型按顺序链接 actions组合 Actions
FlowF_按计划把 source → pipeline → destination 连起来组合 Pipelines

命名约定上:action 采用UPPER_SNAKE_CASE、动词开头(WRITEEXTRACTLABELSEND)、2–4 个词,例如A_LABEL_AND_RATEA_EXTRACT_TRANSCRIPT;pipeline 采用P_前缀,如P_MY_PIPELINE;flow 采用F_前缀与F_SOURCE_PIPELINE模式。

一个可参考的 action 清单示例(来自 ArbolSystem.md 的 Action 表):

Action输入输出
A_LABEL_AND_RATE{ content, title }(须为文章正文,不接受裸 URL,最少 200 字符,拒绝 LLM 拒绝模式){ labels, rating, quality_score }
A_EXTRACT_TRANSCRIPT{ url }{ content, video_id, title }
A_TRANSCRIBE_AUDIO{ url }{ content, source: "whisper", audio_bytes, truncated }
A_SEND_EMAIL{ to, subject, body }{ success, message_id }
管道模型(Pipe Model)与 passthrough 模式

Pipeline 采用 Unix 风格的管道模型:第 N 个 action 的输出成为第 N+1 个 action 的输入。为了不让上下文在每一跳被丢弃,actions 使用passthrough 模式...upstream)保留前序 actions 的元数据,同时附加自己的输出:

// Action receives upstream data, adds its own, passes everything forward const { content, ...upstream } = input; return { ...upstream, // preserve all prior action output myField: result, // add this action's contribution };

这意味着 pipeline 中最后一个 action 可以访问前面每一个action 产出的字段,而不仅仅是紧邻上一个。这也是CUSTOMIZATIONS/ARBOL/下自定义 actions 的最佳实践之一。

一个新 action 的落地流程

结合 ArbolSystem.md 中“Creating a New Action”一节与定制层契约,在CUSTOMIZATIONS/ARBOL/ACTIONS/下新建一个动作的完整路径为:

  1. 创建目录:CUSTOMIZATIONS/ARBOL/ACTIONS/A_YOUR_ACTION/
  2. 编写清单action.json:声明 name、description、input/output schema、requires(例如["llm", "readFile"]);
  3. 实现逻辑action.ts:使用execute(input, ctx)模式,并遵循 passthrough 模式;
  4. 本地测试:bun lib/runner.v2.ts run A_YOUR_ACTION --input '{"content": "test"}'
  5. 若需部署到云端(可选):在CUSTOMIZATIONS/ARBOL/Workers/a-your-action/下添加 Worker,再执行部署脚本。

一个完整的action.json示例:

{ "name": "A_LABEL_AND_RATE", "description": "Label and rate content using Fabric's label_and_rate pattern.", "input": { "content": { "type": "string", "required": true }, "title": { "type": "string" } }, "output": { "one_sentence_summary": { "type": "string" }, "labels": { "type": "array" }, "rating": { "type": "string" }, "quality_score": { "type": "integer" } }, "requires": ["llm", "readFile"] }

Action 最佳实践清单:单一职责(一件事,做两件事就拆开)、始终 passthrough、显式声明requires、快速失败(立即校验输入并抛出清晰错误)、尽量幂等(LLM action 用 temperature 0)。

为什么定制层要放在 USER 之下

原文档用一个段落回答了“Why This Lives Under USER”:

LIFEOS/USER/holds everything specific to one principal.CUSTOMIZATIONS/is the part of USER that other system components read on every invocation — not standalone reference data (CONTACTS.md,OPINIONS.md) but live overlays that change how LifeOS behaves for this user.

翻译过来有两层含义:

  1. LIFEOS/USER/存放一切属于单一 principal 的内容;
  2. CUSTOMIZATIONS/是 USER 中被其他系统组件在每次调用时读取的那一部分——它不是CONTACTS.mdOPINIONS.md那样的独立参考数据,而是改变 LifeOS 对该用户行为的实时覆盖层(live overlays)

这一定位与 SystemUserBoundary.md 的边界设计互为表里:USER 区域的字节永远不进入公共发布管线,因此可以在其中放心存放任何个性化内容;而 SYSTEM 代码访问 USER 数据必须通过四个被允许的访问模式之一(LifeosConfig.load()类型化加载器、由 LifeosConfig 计算出的路径、启动时的 @-import、Pulse 的 HTTP/IPC),直接硬编码LIFEOS/USER/...字符串读取则构成边界违规。从源码结构看,SystemFileGuard.hook.ts 与 DeployRegistrationGate.hook.ts 等钩子正是这一边界在运行时的执行者。

何时应该把内容放进 CUSTOMIZATIONS

原文档给出了三条明确的准入标准:

  1. skill 需要你的偏好:一个 skill 需要你的品味、你的来源清单、你的项目或你的声音 → 写入SKILLS/<SkillName>/PREFERENCES.md(或该 skill 文档声明的任何读取文件)。
  2. 你要覆盖系统组件:想用你自己的版本覆盖某个系统 action 或 pipeline → 把覆盖文件放到ARBOL/ACTIONS/<name>ARBOL/PIPELINES/<name>.yamlrunner 会优先采用你的版本
  3. 你要新建私有组件:想创建一个只对你有意义的新 action 或 pipeline → 同样放进ARBOL/。不存在 “personal vs. user” 的区分:只要是你的,就放这里

判断的底层逻辑一句话概括:定制是关于“行为”(behavior)的,而不是关于“事实”(facts)的。

何时绝不该把内容放进 CUSTOMIZATIONS

同样地,原文档给出了两条排除标准:

  1. 纯参考数据:用户只是“读取”的参考数据(identity、projects、contacts、opinions、TELOS)——这些是CUSTOMIZATIONS/同级目录,而不是它的子级。定制层管行为,不管事实。仓库中可以看到这些参考数据确实以同级身份存在于 USER 目录 下:PRINCIPAL/CONTACTS.mdOPINIONS.mdTELOS/WORK/等。
  2. 一次性实验:临时尝试应使用MEMORY/WORK/{slug}/,只有当它“证明了自己的价值(earns its keep)”时才提升(promote)到CUSTOMIZATIONS/

这防止了两类常见的腐化:把事实数据混进行为层导致系统每次调用都加载无关内容;以及用一次性实验污染需要长期维护的覆盖空间。

一个端到端的最小心智模型

把上面所有规则压缩成一个可操作的工作流:

  1. 改 skill 行为但不 fork skillCUSTOMIZATIONS/SKILLS/<SkillName>/PREFERENCES.md(或该 skill 文档化的文件);
  2. 复用一段逻辑到多处→ 在CUSTOMIZATIONS/ARBOL/ACTIONS/A_<NAME>/下写action.json+action.ts
  3. 把多个 action 串成线性处理→ 在CUSTOMIZATIONS/ARBOL/PIPELINES/下写 yaml 并登记到pipeline-index.json
  4. 需要分支、重试、并发→ 在CUSTOMIZATIONS/ARBOL/FLOWS/下写 yaml 并登记到flow-index.json
  5. 凡是别人不该看到或不该共享的→ 一律留在 USER 区域,由边界机制保证不进入公共发布。

这套机制的最终效果,正如 SystemUserBoundary.md 所概括的:“LifeOS 这个操作系统是普适且公开的,而它所运行的人生是单一且私密的”——同一个仓库可以是所有人的 Life OS,却永远不会包含任何一个人的生活CUSTOMIZATIONS/正是这条哲学在用户侧落地的执行枢纽。

【免费下载链接】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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询