Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

潮痕图标:三道潮线与一枚金点

潮痕 Tideline

在记忆消失以前。

一个由照片、语音、文字等个人材料驱动的记忆理解与重建工具。
AI 通过复述、分析、关联和适度追问,帮你找回正在消退的事实、感受与意义,
最终整理成由你自己长期掌控的个人档案。

状态:MVP 开发中 Python 3.11+ FastAPI React + TypeScript SQLite 自托管于 NAS License: AGPL-3.0

潮痕的入口:宣纸底色上的宋体标题与一道潮线

它的任务不是让过去变得更精彩,而是让过去尽可能少地消失

Note

早期开发中(MVP 阶段),个人自用项目,暂无账号体系与多用户计划。

为什么做这个

照片看起来把某个瞬间永远保存了下来,但它留下的只是一个薄薄的表面。它没有留下你为什么站在那里、事情如何偏离了计划、风的温度、耳机里的音乐,以及当时一闪而过的念头。

我曾在岚山一个下雨的车站等了一个小时——买错了方向的票,站在屋檐下看雨打湿的绿色。两个月后,我已经记不清当时的狼狈,只剩下绿色、雨声和一种短暂停留在世界某处的感觉。再过几年,也许连这些也会消退,只剩一张潮湿站台的照片。

而另一次经历让我发现:记忆并不总是靠提问被提取出来的。当 AI 认真分析我已经说出的内容、把其中的结构和矛盾返还给我时,记忆会自己继续生长——"对,就是这里""不,当时还有一个前提""你这么说,我又想起了一件事"。

Tideline 想把这种过程带到照片里。它更像一艘很小的打捞船,沿着照片、声音和文字留下的微弱坐标,把仍然能够找到的东西一件件捞起来。

它是怎么工作的

  1. 建立项目 —— 为一段不想失去的经历建一个项目(一次旅行、一段日子)。
  2. 导入材料 —— 批量上传照片,按 EXIF 拍摄时间摊开成时间线;语音、文字随时补充。
  3. 对着照片讲述 —— 想到什么说什么,不需要完整,不需要按顺序。
  4. AI 回应 —— 基于项目纪要、当前照片、邻近材料与最近对话作出回应:复述、分析、关联、适度追问。
  5. 档案沉淀 —— 讲述与确认都作为原始事件保存,最终生成带照片的 Markdown 档案,随时导出。

照片在这里不是最终产物,而是记忆的触发器。

一轮真实的讲述

就是上面岚山的那个故事。左边是那张照片(拍摄时间来自 EXIF),右边是对着它随口说的几句话,和 AI 的回应——它认真看了照片:第 5 节车厢的候车牌、收拢的伞、看不到雨棚的站台,把讲述与画面之间的出入摆出来,但不替你下结论。

回忆工作台:岚山站台的照片与一轮讲述、AI 回应

产品原则

摘自 PRD 中最重要的几条:

  • 真实优先于流畅 —— AI 不为了文章完整而补写不存在的事实、情绪或因果。
  • 原始材料不可覆盖 —— 生成的文章、摘要都不能取代原始输入。
  • 回应优先于提问 —— AI 的价值不在提问数量,而在回应是否唤起继续回忆、补充或修正。
  • 推测必须与事实区分 —— AI 的分析是等待确认的暂时性理解,用户可以纠正、否定、撤回。
  • 用户拥有最终控制权 —— 随时导出、删除、迁移,决定哪些公开、哪些永远私密。

架构与技术栈

选型
后端 Python 3.11+ / FastAPI / SQLAlchemy,uv 管理依赖
前端 React / Vite / TypeScript
数据库 SQLite
AI Claude(provider 抽象:API / 本机 CLI / 远端桥接可切换,见下)
部署 威联通 NAS(Docker Compose),Web 仅局域网;推理经桥接链路出网
备份 restic 加密增量备份至 Cloudflare R2(3-2-1 策略,见 deploy/nas/)

关键设计(详见决策记录):

  • 事件溯源 —— 讲述、确认、纠正都是 append-only 事件;项目纪要是可从事件流重放重建的派生缓存,每条条目带来源事件 ID。
  • 双调用分离 —— 主模型流式生成回应(纪要 + 当前照片 + 邻近材料 + 最近对话);小模型在后台队列提取纪要增量。
  • 时间线 —— 按 EXIF 拍摄地本地时间排序,不强转 UTC;无 EXIF 材料打不可靠标记,允许手动定位。
  • 媒体安全 —— 图片一律经鉴权接口或短时效签名 URL 输出,不走静态目录。
目录结构
Tideline/
├── backend/                # FastAPI 后端
│   └── app/
│       ├── main.py         # 应用入口(生产环境同时托管前端静态文件)
│       ├── config.py       # 配置(TIDELINE_ 前缀环境变量)
│       ├── auth.py         # 单用户会话鉴权
│       ├── db.py / models.py / schemas.py
│       ├── routers/        # projects, materials, memory, export
│       └── services/       # AI 调用、上下文组装、纪要、EXIF、图片、提示词
├── frontend/               # React + Vite + TS 前端
│   └── src/pages/          # 登录、项目列表、项目时间轴、回忆工作台
├── doc/                    # 随笔、理念文档、PRD、决策记录
├── deploy/                 # 部署物料:NAS 运维/备份脚本、桥接主机安装脚本
├── Dockerfile              # 单镜像多阶段构建(前端产物打进后端镜像)
└── docker-compose.yml      # NAS 部署入口

快速开始

本机开发 —— 后端:

cd backend
uv sync
uv run uvicorn app.main:app --reload

前端(开发服务器代理 /api 到 8000 端口):

cd frontend
npm install
npm run dev

配置:复制 .env.examplebackend/.env。不填 TIDELINE_PASSWORD 时跳过鉴权(仅限本机开发)。

NAS 部署(详见 deploy/):

cp .env.example .env   # 填好密码、密钥,选定 AI 后端
docker compose up -d --build

AI 后端(TIDELINE_AI_PROVIDER

模式 说明
api 直连 Anthropic API(TIDELINE_ANTHROPIC_API_KEY
claude_cli 本机/容器内 Claude Code CLI,走订阅额度
bridge 部署机无法直连模型厂商时,经 HTTPS 隧道把推理转发给远端桥接主机(同仓库的 app/bridge_server.py 入口点;协议定义在 app/services/bridge.py,部署见 deploy/bridge-host/,决策依据见决策记录第 14/15 条)。桥接主机支持双引擎——claude(Claude 订阅,主通道)与 codex(ChatGPT 订阅,备用/对照),应用内「服务状态」页可查看各链路状态并热切换
echo 无任何凭证时的本地开发占位回应
auto(默认) 有 API key 走 api;本机有 CLI 走 claude_cli;否则 echo

文档

文档 内容
在记忆消失以前 随笔,项目的情感起点
照片驱动的个人记忆理解与重建工具 理念文档
产品需求文档(PRD) 完整需求与 MVP 范围(10.1)
决策记录 已确定的 15 条技术与产品决策(含理由与修订)

状态与许可

MVP 开发中,范围以 PRD 10.1 为准:创建项目、批量上传照片、按时间浏览、对照片讲述、AI 基于上下文回应、保存完整原始输入、生成带照片的 Markdown 档案并导出。

单用户自用工具。以 AGPL-3.0 发布——自部署、修改、分发都自由,但基于它提供网络服务时须同样开源;记忆应当由它的主人掌控,衍生品也一样。


让过去尽可能少地消失。

About

潮痕 Tideline — 照片驱动的个人记忆理解与重建工具 / A photo-driven personal memory understanding & reconstruction tool

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages