<div align="center">

# Life Index | 人生索引    

*"Your life, indexed."*

</div>

<div align="center">

[English](./README.en.md) | **简体中文**

</div>

<!-- 品牌理念 Badges -->
<p align="center">
  <img src="https://img.shields.io/badge/初心-人生档案馆-ff6b6b" alt="初心">
  <img src="https://img.shields.io/badge/核心-Agent--native-78206E" alt="核心">
  <img src="https://img.shields.io/badge/存储-本地优先-4ecdc4" alt="本地优先">
  <img src="https://img.shields.io/badge/交互-自然语言-ffe66d" alt="自然语言">
</p>

<!-- 技术指标 Badges -->
<p align="center">
  <a href="https://github.com/DrDexter6000/life-index/actions/workflows/ci.yml"><img src="https://github.com/DrDexter6000/life-index/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
  <img src="https://img.shields.io/badge/python-≥3.11-3776AB?logo=python&logoColor=white" alt="Python ≥3.11">
  <a href="./LICENSE"><img src="https://img.shields.io/badge/license-Apache_2.0-blue" alt="License"></a>
</p>

<p align="center">
  <img src="./assets/life_index_readme.png" alt="Your Digital Legacy" width="600">
</p>

<!-- 快速导航 -->
<p align="center">
  <a href="#项目初心">💭 项目初心</a> &nbsp;•&nbsp;
  <a href="#快速开始">⚡ 快速开始</a> &nbsp;•&nbsp;
  <a href="#技术框架">🛠️ 技术框架</a>
</p>

---

<a id="项目初心"></a>

# 💭 项目初心

## 🎉 写在最前

这是我在 GitHub 创建的第一个仓库。

我只是一个零编程基础的平凡父亲，甚至连这篇README也是在AI的帮助下完成的——    
我创建它不是为了展示我的编程技术，而是因为我自己迫切需要一个**专门存放人生碎片的工具**——

> **不是知识库（PKM），不是 Agent 的记忆缓存，而是人生档案馆。**  
> **不为知识沉淀，不为 AI 性能优化，只为检索我自己的人生碎片。**

---

## 📌 关键区分：Life Index 不是什么

| 维度 | **Life Index** | **PKM**（Notion/Obsidian） | **Agent 记忆**（Mem0/Zep） |
|:---|:---|:---|:---|
| **核心追问** | "那时的我，什么心情？" | "我知道什么？" | "我刚才说了什么？" |
| **保存期限** | **永久，作为遗产** | 长期，随认知迭代重构 | 短暂，用完即弃 |
| **所有权** | **完全属于你**，本地文件永不过期 | 属于你，但格式可能随软件迭代 | 属于服务商，随时可能被清理 |
| **失败时的代价** | 没有代价，Markdown 文件永远可读 | 导出困难，格式锁定 | 瞬间归零，无感知丢失 |

> **Agent 记忆是消耗品**——它帮你订外卖、写代码，然后随风而逝。  
> **Life Index 是遗产**——它记录你为何而哭、为谁而笑，直到时间尽头。

---

## 💭 但以上只是技术说明

对我来说，Life Index 真正的用法发生在深夜：当我偶然翻到女儿两岁时的照片，那种**幸福中带怅然若失的复杂情绪**，可以被准确地固定下来——不仅是她的笑脸，更是我当时作为父亲的心跳、阳台上的光线、以及那个知道"这一刻正在消逝"的清醒。

这些记录最终会成为一本**数字化家书**。也许有一天我不在人世，她打开这些文件，就像翻开一本泛黄的老书，读到的不仅是爸爸的爱，还有爸爸这一生跌撞出来的经验、犯过的错误与得来的智慧。

**这不是 Agent 的"记忆"——它不会帮我订外卖或写代码。这是我留给女儿的"遗产"，是只有人类才需要的"过去"。**

<details>
<summary>📎 一篇真实的日志长什么样？（点击展开）</summary>

```yaml
---
title: "想念尿片侠"
date: 2026-03-04T19:43:02
location: "Chongqing, China"
weather: "晴天（浮云、阵雨）"
mood: ["思念", "温暖", "感伤"]
people: ["团团"]
tags: ["亲子", "回忆", "成长", "感伤"]
project: "LifeIndex"
topic: ["think", "create"]
abstract: "翻看女儿团团小时候的照片，怀念那个2岁上下的尿片侠，感叹时光流逝与父女情深。"
---

# 想念尿片侠

在翻过往资料的时候，看到了团团小时候的照片，那个只有2岁上下的尿片侠

突然有一种伤感 —— 我好想这个小娃娃，好想再见她一面，好想再能体验一次把小肉坨坨抱在怀里的感觉

错觉中，小时候的团团是我的宝贝儿，现在的团团也是我的心肝儿 —— 但她们不是同一个人？

三岁以前的娃娃好像小动物，全凭直觉驱动，想吃饭、想睡觉、想玩耍、想要爸爸要妈妈 —— 都不会经过大脑思考。

而且这个世界对于她来说好危险，什么都不懂、什么都不知道，最好奇、最感兴趣的就是爸爸妈妈的一举一动，天天围着爸爸妈妈转、模仿爸爸妈妈的一举一动。

我还记得，她屁颠屁颠儿跑到阳台上去，打开我的烟盒子、然后掏出一根烟递给我 —— 虽然她不知道这是在干嘛，但那是观察爸爸生活习惯的总结[笑哭]

三岁开始，团团上幼儿园了，开始接触老师和同学了 —— 她变成小孩儿了，开始有自己的思维/思考，有自己的个性甚至计划，爸爸妈妈也不是她世界中唯一的重心。

三岁之后的团团依然是全宇宙最重要最珍贵的存在 —— 但确实，她已经不是那个咿呀学语的小婴孩儿了，那个让我神魂颠倒的尿片侠、她长大了。

我既希望我们一家人永恒停留在团团2岁的时光 —— 也盼望她长大可以去感受更美好的世界。

总而言之，小疙瘩，爸爸想你了。

Tuantuan, this one is for you.

```

</details>

---

## 🎯 Life Index 相信

每个人都值得拥有这样一份人生档案馆。

—— **难道只有政客/有钱人才能聘请作家撰写回忆录？**    
—— **难道只有埃隆马斯克的生活点滴、观点看法才有资格被记录？**   
—— **你还记得十年前的那个决定，是基于什么做出的吗？**  
—— **你想不想留给下一代一本基于真实人生写就的经验宝典、错题集，甚至是数字化的记忆遗产？**

<u>这就是凡人也能拥有的数字平权</u> —— 不是优化 Agent，而是记录自己。

而当你积累了足够多的"自己"，也许有一天，这些记录会比你想象的走得更远。

---

## 🌱 适合谁？

- **新手父母**：记录作为父母的真实体验——那些疲惫、惊奇、心碎的时刻
- **数字游民**：在不同城市间穿梭，记录地理位置和当地心境
- **长期主义者**：想要一个能用 30 年的系统，而不是追逐最新的生产力工具
- **隐私偏执狂**：自己的生活细节不该成为云服务商的训练数据
- **未来主义者**：相信今天的记录，是明天尚不存在的技术的原材料
- **每个凡人**：相信自己的人生碎片值得被保存，即使它们并不"高效"

---

<a id="快速开始"></a>

# ⚡ 快速开始

## 普通用户

**适用人群** —— 只想"把项目交给自己的 Agent 安装并初始化"，不需要自己改代码。

**复制给你的 Agent** —— 把下面这段话直接发给你的 Agent（OpenClaw、Claude Desktop、Cursor 等均可）：

```text
请阅读并严格按照这个仓库里的 `AGENT_ONBOARDING.md` 完成 Life Index 的安装、初始化与验证：
https://github.com/DrDexter6000/life-index/blob/main/AGENT_ONBOARDING.md

要求：
1. 先完整阅读该文档，再开始执行
2. 严格按文档完成安装、初始化、验证与后续可选个性化步骤
3. 所有 Python/CLI 命令都必须使用虚拟环境路径
4. 如果某一步失败，立即停止并报告精确错误
5. 最终请使用中文按文档要求向我汇报结果

```

<details>
<summary>🔧 开发者安装（点击展开）</summary>

<br>

**适用人群** —— 需要本地调试、改代码、跑测试。

```bash
git clone https://github.com/DrDexter6000/life-index.git
cd life-index

# 创建虚拟环境 + 可编辑安装（已包含语义搜索）
python3 -m venv .venv
.venv/bin/pip install -e .    # Windows: .venv\Scripts\pip install -e .
```

### 开发者常用命令

| 操作 | 命令 |
|:---|:---|
| 激活虚拟环境 | `source .venv/bin/activate` (Windows: `.venv\Scripts\activate`) |
| 统一 CLI（推荐） | `life-index --help` |
| 健康检查 | `life-index health` |
| 记录日志 | `life-index write --data '{...}'` |
| 搜索日志（关键词+语义） | `life-index search --query "关键词"` |
| 仅关键词搜索 | `life-index search --query "关键词" --no-semantic` |
| 开发者调用 | `python -m tools.search_journals --query "关键词"` |
| 运行单元测试 | `python -m pytest tests/unit/ -v` |

> **提示**: 开发者可以先 `source .venv/bin/activate`，之后所有命令无需 `.venv/bin/` 前缀。

</details>

<details>
<summary>🔍 故障排除（点击展开）</summary>

<br>

**技能触发不稳定**  
→ 用 `"/life-index" + 意图词`（例如：`/life-index 记日志：...`）

**工具执行报错（ModuleNotFoundError）**  
→ 确认使用 `.venv/bin/python`（而非系统 python）执行命令，且在技能根目录下

**fresh install 时 health 显示 degraded**  
→ 如果还没执行 `life-index index`，这是正常现象；先初始化索引，再重新运行 health

**日志没有写入 ~/Documents/Life-Index/**  
→ 在技能根目录运行 `.venv/bin/python -m tools.query_weather --location "Beijing,China"` 确认工具可用

**Windows 下 `write --data '{...}'` 很难转义**  
→ 优先改用 `life-index write --data @first-entry.json`（该文件由 Agent 在安装流程中自动生成，非仓库自带；手动使用时需自行创建 JSON 文件）

**语义搜索不可用**  
→ 运行 `.venv/bin/life-index health` 检查 fastembed 是否已安装

**venv 损坏（Python 升级后、迁移系统后）**  
→ 删除 `.venv` 目录，重新执行 `python3 -m venv .venv && .venv/bin/pip install -e .`

**升级到新版本**  
→ 请参考 `docs/UPGRADE.md`（包含版本语义与兼容性承诺）

**安装健康检查**  
→ 运行 `.venv/bin/life-index health` 查看所有检查项的状态

**权限错误**  
→ Windows: 以管理员身份运行终端 | Linux/macOS: `chmod -R 755 ~/Documents/Life-Index`

</details>

---

<a id="技术框架"></a>

# 🛠️ 技术框架

## 📝 核心功能之一：人生记录

告诉 Agent 你想记什么，它就帮你归档：

> /life-index 记日志：今天看到团团以前的照片，突然很想念那个2岁的尿片侠，那种甜蜜又忧伤的感觉。

Agent 自动整理元数据（时间、地点、人物、情绪、标签），生成结构化 Markdown 文件，存在你自己的硬盘上。

> **💡 触发建议**：在当前 LLM/Agent 生态下，单靠自然语言触发技能有时不稳定。实测用 `/life-index` + 意图词（如"记日志""搜索记录"）写在同一条消息里，触发成功率更高。

## 📖 核心功能之二：人生检索

通过三层标签维度 + 全文搜索 + 语义搜索，在任意时刻找到过去的自己：

| 维度 | 示例 |
|:---:|:---|
| **主题** | `think`（思考）、`create`（创作）、`relation`（关系） |
| **项目** | `LifeIndex`（本项目）、`Parenting`（育儿） |
| **标签** | `亲子`、`回忆`、`感伤`、`尿片侠` |

想找"所有关于团团的感伤回忆"？搜索 `团团` + `感伤` 即可。甚至用英文 "missing my daughter" 也能找到中文日志——语义搜索支持 50+ 语言的跨语言理解。

### 为什么搜得到？

Agent 不需要读完你的 2000 篇日志——**双管道并行检索架构**让它只看 **真正需要的那几篇**：

> **关键词管道**（精确匹配）∥ **语义管道**（意思相近）→ RRF 融合排序

两条管道并行执行、结果智能融合。2000 篇日志暴力读取需 ~300 万 tokens，经检索后仅需 ~5000 tokens——**节省 99.8%**。

<details>
<summary>🔍 双管道检索架构详情（点击展开）</summary>

```
                    用户查询
                   ┌────┴────┐
            ┌──────▼──────┐  ┌──────▼──────┐
            │ 关键词管道 A │  │ 语义管道 B   │
            │             │  │             │
            │ L1 索引过滤  │  │ 向量相似度   │
            │ L2 元数据过滤│  │ (多语言嵌入) │
            │ L3 FTS5 匹配 │  │             │
            └──────┬──────┘  └──────┬──────┘
                   └────┬────┘
              RRF 融合排序 (k=60)
                      │
                  最终结果
```

**管道 A — 关键词匹配（找到"写了什么"）**

| 层级 | 数据来源 | 返回内容 | 设计意图 |
|:---:|:---:|:---:|:---|
| **L1 索引层** | `by-topic/` 索引文件 | 日期+标题+路径（~80字节/篇） | 按主题/项目/标签快速缩小候选集 |
| **L2 元数据层** | YAML Frontmatter（SQLite 缓存） | 全部元数据（~500字节/篇） | 按日期、心情、人物等多维度过滤 |
| **L3 内容层** | FTS5 全文索引 | 匹配片段+上下文（~300字节/条） | 关键词精确匹配，BM25 排序 |

**管道 B — 语义搜索（找到"想说什么"）**

| 数据来源 | 返回内容 | 设计意图 |
|:---:|:---:|:---|
| 多语言向量嵌入 | 路径+相似度（~100字节/条） | 找到"意思相近"但关键词不同的日志，支持跨语言检索 |

**两条管道并行执行**，最终通过 [Reciprocal Rank Fusion](https://plg.uwaterloo.ca/~gvcormac/cormacksigir09-rrf.pdf) (RRF, k=60) 融合排序——既不遗漏精确匹配，也不放过语义相关的结果。

</details>

---

## 🛡️ 你的数据，永远属于你

Life Index 采用「本地优先」和「数据与程序分离」策略：

- **技能代码**放在 Agent 的技能目录
- **你的日志、附件、索引**全部独立存储在系统用户目录下

```
~/Documents/Life-Index/
├── Journals/                    # 日志主目录（按年月组织）
│   └── 2026/03/
│       └── life-index_2026-03-04_002.md
├── attachments/                 # 附件（照片、视频、语音）
│   └── 2026/03/
└── by-topic/                    # 自动生成的索引
    ├── 主题_think.md
    ├── 项目_LifeIndex.md
    └── 标签_亲子.md
```

**这意味着**：20年后，即使 Life Index 这个软件已经消失，但你的数据依然在那里——纯 Markdown + YAML 格式，任何文本编辑器都能打开，字迹清晰，永不失效。

### ⚠️ 重要：数据备份建议

- 用户应要求 Agent **定期对日志数据目录进行加密备份**
- 用户可自行选择**本地设备**或**云端备份**方式

> **但 Life Index 强烈建议本地设备备份**，保护好自己的**数字遗产（Relic）**，不要把你的**灵魂印记（Engram）**主动送入公司的**神舆（Mikoshi）**

<details>
<summary>💀 强尼·银手有话说（点击展开）</summary>

> *"我看到公司……把夜之城变成了一台机器，用人们破碎的精神、破碎的梦想和空空的口袋作为燃料。公司长期以来控制着我们的生活，夺走了很多……现在他们又想要我们的灵魂！"*    
> *I saw corporations... turn Night City into a machine, fueled by broken spirits, broken dreams, and empty pockets. Corporations have been controlling our lives, taking... and now they want our souls!*

> *"有些命运比死亡更惨。"*    
> *There are fates worse than death.*

</details>

---

## 🎯 设计底线

```
宁可功能简单，不可系统复杂
宁可人工维护，不可自动化陷阱  
宁可牺牲性能，不可牺牲可靠性
```

我们不做：✕ 云端同步 · ✕ 富文本编辑 · ✕ 实时协作 · ✕ AI 替你思考

---

## 📚 文档导航

| 文档 | 适用场景 |
|:---|:---|
| **[SKILL.md](./SKILL.md)** | Agent 技能定义、工具接口、工作流 |
| **[AGENTS.md](./AGENTS.md)** | AI 编码代理上下文 |
| **[API.md](./docs/API.md)** | 工具参数和返回值 |
| **[ARCHITECTURE.md](./docs/ARCHITECTURE.md)** | 架构设计与关键决策 |
| **[CHANGELOG.md](./docs/CHANGELOG.md)** | 版本演进 |
| **[UPGRADE.md](./docs/UPGRADE.md)** | 版本升级与兼容性承诺 |
| **[PRODUCT_BOUNDARY.md](./docs/PRODUCT_BOUNDARY.md)** | 产品边界与执行优先级 |
| **[SCHEDULE.md](./references/schedule/SCHEDULE.md)** | 定时任务配置 |

---

## 🤝 参与贡献

目前 Life Index 处于个人自用阶段。如果你认同"人生档案馆"这个理念，欢迎：

1. **提 Issue**：分享你的使用场景，或报告 Bug
2. **完善文档**：帮助改进多语言版本
3. **分享故事**：如果你用 Life Index 记录下了重要的瞬间，欢迎分享

---

## 📜 许可证

[Apache License 2.0](./LICENSE) - 你的人生数据属于你，这段代码也是。

---

> *"我既希望我们一家人永恒停留在团团2岁的时光 —— 也盼望她长大可以去感受更美好的世界。总而言之，小疙瘩，爸爸想你了。Tuantuan, this one is for you."*
> 
> *—— 摘自 Life Index 第一篇日志，2026年3月4日，拉各斯。这不是关于她的成长记录，而是关于我爱她的记录。*
