Skip to content
dsh.fish
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.**

[![CI](https://github.com/WsTe47/mylife/actions/workflows/ci.yml/badge.svg)](https://github.com/WsTe47/mylife/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![DSH](https://img.shields.io/badge/DSH-bundle-purple)](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

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source