Bundle
dsh-mylife
MyLife — a local-first personal state record and decision engine for DeepSeek Harness. Reconstructs the thread through your confusion, argues against its own conclusions, and retires premises you have outgrown.
- Source
- WsTe47
- License
- MIT
- Updated
- Updated 20 hours ago
Readme
# MyLife
> **从混乱中找出你的主线,并且记得它在时间里的变化。**
> **Your data stays home. Your thinking gets organized.**
[](https://github.com/WsTe47/mylife/actions/workflows/ci.yml)
[](LICENSE)
[](https://github.com/deepseek-ai/deepseek-harness)
中文 | [English](README.en.md)
MyLife 是 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(`dsh`)的一个插件:
一个**本地优先的个人状态档案与决策引擎**。
它不做旅游规划,不做记账,不推荐股票。它只做一件别人没做的事 ——
**持续维护"你是谁",并在你要做决定时,从混乱里帮你找出主线,同时主动质疑自己。**
---
## ⚠️ 免责声明
MyLife 是**决策支持与自我认知**工具。输出由大语言模型生成,**仅供参考**,
**不构成投资、法律、税务、医疗或心理健康建议**。
涉及投资、医疗、心理危机等专业领域,请咨询相应持证专业人士。
**MyLife 不是心理支持工具。** 若你正经历严重心理痛苦,请寻求专业帮助,
不要依赖本工具。
---
## 为什么会有这个东西
某个深夜睡不着,迷茫于自己未来的出路,我用语音输入写了一篇大约 14000 字的碎碎念,
花了一个小时。写完我自己都知道:**我说不清自己到底该怎么办。**
第二天我让 AI 总结那篇文档。它总结出来的点,**非常精准地命中了我心中所想**。
信息全是我自己提供的 —— AI 并没有告诉我任何我不知道的事。它做到的只有一件:
**把散落在 14000 字混乱里的那条线,抽了出来。**
我后来想明白,这件事人的大脑结构上就做不到:
| 人的大脑做不到 | 大模型做得到 |
|---|---|
| 同时持有 14000 字的上下文 | 全文同时在场 |
| 从情绪化碎片里抽出因果链 | 把"我烦这个"还原成"我在 X 和 Y 之间无法取舍" |
| 指出你话里的自相矛盾 | 你说了 A 也说 ¬A,它能同时贴出来 |
| 把模糊感受转成可执行动作 | 输出有主次、有验收条件的路径 |
| 记住你一年前的约束还在不在 | 时间戳 + 出处 + 时效判定 |
所以 MyLife 是一个**外置的思维组织器**。它帮你**想清楚**,而不是替你过日子。
---
## 核心功能
### 1. 从混乱里抽主线
你不需要先想清楚再输入。错别字、语病、说到一半改口 —— 全文原样保留,
因为它才是**唯一不可伪造的证据源**。
### 2. 四层信息模型(全部是你能 `cat` 的纯文本)
```
~/mylife/
├── raw/ L0 原始输入,只增不改不删
├── digest/ L1 按主题整理的摘要(同时保留 AI 原稿与你的修订版)
├── claims/ L2 证据图:一条证据一个文件
├── profile.yaml L3 当前状态 + 逐字段有效期
├── fields.yaml L3 字段词典(按需生长,非预制)
└── index.yaml L4 溯源链:结论 → 证据 → 原文
```
### 3. 信息会过期,而且它会提醒你
每个字段有**自己的有效期**:学历不过期,存款 90 天,房租 180 天。
在回答"我该不该裸辞"之前,它会说:
> 回答这个问题需要以下信息,但它们可能已经不准了:
> · 存款:120000(97 天前填写,有效期 90 天)
>
> 这些数字会直接影响结论 —— 存款变化会改变你承受空窗期的能力。
>
> [现在更新] 提供新数值,我会重算
> [沿用旧值] 我会照常回答,但结论会标注"基于可能过时的数据"并降权
**"沿用旧值"这个选项是刻意留的** —— 否则你只会被卡住然后烦。
### 4. 反证:它必须先反驳自己
给出任何正向结论之前,它必须去找反证。但输出形态不是"检测到你矛盾了"——
> ## 你在「职业去留」上的多段表述
>
> | 时间 | 表述 | 当时的语境 |
> |---|---|---|
> | 2025-11-03 | 我很喜欢这里,绝对不会考虑离开 | 刚完成一个项目 |
> | 2026-01-18 | 受不了这个管理方式,开始认真考虑跳槽 | 连续加班三周 |
>
> 这几段在「去留」上方向不同。**它们未必互相矛盾** ——
> 人在不同处境下对同一件事的感受本来就可以并存。
>
> 一个可能的解释是:你认可其中一部分(工作内容、同事),不认可另一部分(强度、管理方式)。
> 如果是这样,真正要解的问题就不是「走不走」,而是那个**具体的不认可项能否改变**。
>
> > 请你自己判断:哪一段更接近你现在的真实状态?
**这是本插件最核心的设计决定。** "我想跳槽"和"我热爱这里"往往不是矛盾,
而是同一个人的两面。如果 AI 跑去说"你上次说的和这次不一样!",
你的感受是**被抓住把柄**,而不是**被理解**。
### 5. 旧前提作废
人的旧约束会自动在心里失效,但记录不会。于是会出现"拿一年前的恐惧否决今天的决定"。
> ## 你可能还在沿用的旧约束
> - 财务压力大,不敢动(2025-06-01)—— 还成立吗?
当你确认它不再成立,记录会被**作废而不是删除**(历史留下来),并注明原因。
### 6. 每条判断都必须有出处
`mylife_trace` 能把一条证据还原到 `文件 + 行号 + 原文`:
```
证据 2026-09-17-003 溯源到 raw/2025-11-03-001-职业.md 第 14 行:
14 觉得自己短期内绝对不会考虑离开。
以上为 L0 原始文本,未经改写。
```
**这是"反谄媚"的技术实现**:不是靠提示词祈祷模型诚实,
而是让"引不出出处就说"这件事在结构上无法完成。
---
## 本仓库不含任何个人数据
MyLife 的设计是**代码与档案分离**:
| 位置 | 内容 | 是否公开 |
|---|---|---|
| `~/dsh-mylife/`(本仓库) | 插件源码、测试、设计文档 | ✅ 公开 |
| `~/mylife/`(工作区) | **你的原始自述、证据图、档案、报告** | ❌ 绝不入库 |
维护者一侧有三道机械防护(已挂进 CI):
1. **`.gitignore` 第二道防线** —— 覆盖工作区四层结构(`raw/`、`digest/`、`claims/`)、
`profile.yaml`、`report-*.md` 等,防止误提交
2. **`npm run check-secrets`** —— 扫描被跟踪文件里的密钥特征
(`sk-`、`gh[pousr]_`、`cli_`、Bearer、私钥块、赋值式密钥)与档案类路径
3. **CI 强制执行** —— 上面两项每次推送都跑,不过就红
```sh
npm run check-secrets # 提交前自检
npm run check-secrets:history # 额外扫完整 git 历史
```
> ⚠️ 如果你把工作区指向本仓库目录(**不推荐**),请先确认 `.gitignore` 生效。
> 更安全的做法是保持两者分开,就像本插件默认的那样。
## 设计原则
### 反过来做:能用结构解决的,不要用提示词解决
提示词会被更长的新指令挤掉,结构校验不会。
所以"必须给依据"是靠工具强制 + 溯源可检测,而不是靠一句"请不要编造"。
### 成功指标不是使用时长
**如果一个"思考组织器"的用户越用越离不开它,说明它失败了** ——
因为它的目标是让你获得**你自己的**清晰度。
所以:
| 健康 | 危险 |
|---|---|
| 你经常说"不对,我不是这个意思" | 你全盘接受它的每条结论 |
| 你自己给出了它没提到的判断 | 你只问"我该怎么办" |
**好的产品,是你用完它之后,即使没有它也能想得更清楚一点。**
它应该像一个好教练 —— 让运动员变强,而不是让运动员离不开教练。
### 权限透明
装插件等于把你的权限给它。所以这里逐条列出:
**MyLife 会做的:**
- 读写你指定的工作区目录(默认 `~/mylife`,纯文本 Markdown/YAML)
- 调用你配置的 LLM API 做推理 —— **对话与档案内容会发给你选择的模型提供方**
- 可选:读取 `~/dsh-mylife/examples/` 下的示例语料(仅当你要跑演示时)
**MyLife 不会做的:**
- 不读取凭据(`~/.dsh/.credentials.yaml`、`.env`、`*.key`)
- 不访问工作区以外的文件
- 不发起任何网络请求(除了你自己配置的 LLM API)
- 不上传、不遥测、不统计
**你的数据在哪里:**
- L0/L1/L2/L3/L4 → 工作区目录,纯文本,可直接 `cat` / `git` / 拷走
- 索引(若你用外部检索工具)→ 工作区内,可随时重建
> ⚠️ 如果你把档案 git 化,**务必使用私有仓库**。里面可能有你的收入、负债、
> 职业不满与心理状态。误推到公开仓库是不可逆的泄露。
---
## 安装
### 前置
- [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(`dsh`)**0.1.5-rc.1 或更新**
- Node.js **22.19+** 或 **24+**
### 安装
```sh
dsh plugin --profile web add dsh-mylife
```
或在 DSH 里打开 **Settings → Plugin Market** 搜索 `mylife`。
然后重启 `dsh web`,新开一个会话。
### 安装配套 Skill
DSH 只从固定根目录发现 Skill,**装 npm 包不会自动带上它**。请手动复制一份:
```sh
mkdir -p ~/.dsh/skills
cp -R ~/dsh-mylife/skills/mylife-decision ~/.dsh/skills/
```
(若你的 dsh-mylife 装在别处,把路径换成实际位置。)
Skill 目录**会实时刷新**,不需要重启;工具目录则在会话创建时确定。
验证:`dsh --profile headless "你的可用技能清单里有没有 mylife-decision?"` → 有。
> 这是当前的已知粗糙处:理想做法是插件通过 skill 注册表自带这个 Skill,
> 但那需要 import dsh 的内部包(本插件刻意不依赖它们,以便任何布局下都能加载)。
> 暂以手动复制为过渡方案。
### 配置工作区(可选)
默认工作区是 `~/mylife`。要改的话,在 profile 的 patch 里加 `workspaceRoot`:
```yaml
- insert:
- id: mylife
name: 'dsh-mylife'
config:
workspaceRoot: '~/my-own-path'
```
也可以用环境变量 `MYLIFE_ROOT`。
### ⚠️ 装完必须新开会话
工具目录在**会话创建时确定**。在已存在的会话里重装或启用插件,那个会话**看不到新工具**
(这是 dsh 的行为,不是插件的问题)。装完后请**新开一个会话**。
验证工具确实注册了:
```sh
dsh --profile headless "你可用工具里 mylife_ 开头的有几个?"
```
期望回答 `11`。
### 第一次用
直接开一个会话,说人话就行:
> 我最近对工作很迷茫,不知道该不该跳槽。
它会先问你情况,而不是先给你结论。
---
## 工具
| 工具 | 作用 |
|---|---|
| `mylife_status` | "我现在的状态"简报:字段时效、证据、无出处项 |
| `mylife_record` | 把原始输入存入 L0(一字不改) |
| `mylife_digest` | 写主题摘要,同时保留 AI 原稿与你的修订版 |
| `mylife_claim_add` | 新增证据(强制尽量给出处) |
| `mylife_claim_query` | 检索证据(字面匹配) |
| `mylife_trace` | **溯源到原文与真实行号** |
| `mylife_counter_evidence` | **强制反证**:跨时点的相反表述 + 已作废旧前提 |
| `mylife_supersede` | 作废旧前提(必须给原因,记录保留) |
| `mylife_profile_set` | 写档案字段(带来源与有效期;依赖关系由它声明) |
| `mylife_staleness_check` | 检查某决策依赖的字段是否过期 |
| `mylife_conclusion_add` | 登记结论并绑定依据(无依据会被标记) |
配套 Skill:`skills/mylife-decision/SKILL.md` —— 决策流程与语气约束。
---
## 验证安装
官方推荐的跨会话记忆验证法(本插件不依赖它,但可用来确认工具已注册):
1. 会话 A:让它记住一个唯一值
2. **新建**会话 B(不要复制 A 的对话),问那个值
3. 确认它调用了 `mylife_claim_query` 并能取回
也可以直接:
```sh
cd ~ && dsh --profile web --patch /path/to/dsh-mylife/cordis.patch.yml --dump-config | grep mylife
```
看到 `id: mylife` 就说明 patch 被正确解析。
---
## 开发
```sh
git clone https://github.com/WsTe47/mylife.git dsh-mylife
cd dsh-mylife
npm install
npm test # 63 个测试
```
测试覆盖三条不可退让的不变式:
- **L0 只增不改**:多次记录不互相污染,原文逐字保留
- **溯源必须真实**:行号与内容都要对得上;没有出处时必须如实报告,不许假装成功
- **反证语气**:输出必须含时间、语境,以提问收尾,且不得出现指控性措辞
> 如果你要改反证引擎:`test/core.test.js` 里有一条测试专门断言
> "还原文案不得使用指控性措辞"。**请不要为了让测试通过而删掉它** ——
> 那条测试守的是这个产品最核心的设计决定。
### 本地开发调试
```sh
dsh plugin --profile web add link:/绝对路径/到/dsh-mylife
```
改插件源码后需要重启 `dsh web`(配置层 live reload 不替换源码模块)。
### 目录
```
src/
├── index.js 插件入口:注册工具
├── lib/
│ ├── workspace.js 路径解析、原子写、ID 生成
│ ├── yaml.js 安全解析 / 可读序列化
│ ├── store.js 四层读写(核心)
│ ├── fields.js 时效引擎与 TTL 推断
│ └── evidence.js 反证引擎(最核心,也最容易做歪)
└── tools/
├── index.js 工具定义与渲染
└── execute.js 工具执行分发(可独立单测)
```
---
## 已知限制
- **`mylife_claim_query` 是字面匹配,不是语义检索。** 想跨表述找相关内容,
请在 `raw/` 上另配检索工具(例如 [zvec-grep](https://github.com/zvec-ai/zvec-grep),
它能把"我该不该离职"和"绝对不会考虑离开"匹配起来)。本插件不内置向量检索。
- **情绪极性词典是小而克制的**,只用于**发现值得追问的地方**,
不用于给你贴标签或做心理判断。它会漏,也会误报 —— 请把它当提示而非结论。
- **不做长周期自动提醒**(如"三个月后提醒我复盘")。`dsh-schedule` 的提醒需要
会话存活,跨月不可靠。计划用系统级定时(launchd/cron)+ `dsh --profile headless`。
- **不做 UI**,使用现有 Web 界面与文件本身。
- **Skill 需手动安装到 `~/.dsh/skills`**(见安装章节)—— npm 包不会自动带上它。
## 路线图
**第一阶段(已完成)**
- [x] 四层信息模型 + 溯源链
- [x] 时效引擎(逐字段 TTL + 依赖图;字段词典按需生长)
- [x] 反证引擎(多段表述还原 + 旧前提作废)
- [x] 11 个工具 + 决策流程 Skill
- [x] 65 个测试,含三条不变式的回归守卫
**第二阶段(计划中)**
- [ ] **话题漂移检测与子 Agent 分支** —— 设计已定(见设计文档第 5 章):
以"字段集是否重叠"为主信号识别话题切换,提议"拆出去聊"并带回结构化结论。
安排在二期,因为它依赖 `subagent_fork` 运行时行为,需与主动复盘一起做端到端验证。
- [ ] 主动复盘(系统级定时 + 消息推送;`dsh-schedule` 无法承担跨月提醒)
- [ ] 领域透镜 Skill 的社区化(职业 / 财务 / …)
- [ ] 可选语义检索接入(如 zvec-grep:实测能把"该不该离职"与"绝不考虑离开"匹配起来)
## 设计文档
这个项目的**思考过程**和代码一样重要 —— 因为它做的每个设计决定都在对抗大模型的
谄媚倾向,而那些决定需要解释才能被审查:
| 文档 | 内容 |
|---|---|
| [产品定义](docs/design/vision.md) | 核心洞察、三层架构、边界与风险、竞品对比 |
| [技术方案](docs/design/technical-design.md) | 四层信息模型、反证引擎、话题漂移设计、分发 |
| [路线图](docs/design/roadmap.md) | 四阶段规划、"越用越离不开即失败"的判据 |
| [发布与社区贡献](docs/design/release.md) | 两个分发渠道、收录要求、权限与伦理边界 |
| [Memorix 接入实测](docs/design/research-memorix.md) | 为什么不要让记忆层负责中文检索(含实测数据) |
| [存储层选型](docs/design/research-storage-options.md) | 三个候选项目的物种区分 |
| [界面挂掉勘察](docs/web-ui-hang-investigation.md) | 一次未确诊但排除项明确的排查记录 |
## 相关
- [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) —— 底座。`Everything is a Plugin.`
- [career-planning-skill](https://github.com/yutongcai0628/career-planning-skill) —— 职业透镜的方法论参考(ABZ + 90 天 + 复盘条件)
- [zvec-grep](https://github.com/zvec-ai/zvec-grep) —— 可选的语义检索层
- [awesome-dsh-plugin](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin) —— DSH 插件精选列表
## 许可
[MIT](LICENSE)
Install
dsh plugin --profile web add github:WsTe47/mylife
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-mylife from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.