我最近搭了一套个人AI工作台。它的特别之处不在功能多,而在架构上做了一个很多人会忽略的选择:数据真源握在自己手里,AI 一切都必须经过权限、审批与审计。这一版重写严格以项目自己的「系统架构与技术选型」图和 README 为依据,把图上每一层都落到实打实的工程决策。

图片

先看项目自述的总体框架——它把系统切成客户端、本地回环服务和本地数据三层,每层之间的数据流都是单向的:

使用入口 ClientsPC 响应式工作台移动端 / PWA飞书连接器 · 后续Workbench · 本地回环服务 127.0.0.1今日 · 搜索 · 捕获 · AI 助手项目工作台(里程碑/任务/讨论/决策)专业视图与模板个人上下文知识库 · 授权范围融合权限 · 审批 · 审计 · 幂等Agent Runtime GatewayNative / Harness POC / Hermes 候选搜索 GateWay:FTS5 基线 · 向量 flag · 范围解释本地数据与派生索引SQLite业务对象 · 权限 · 审计受控文件原始资料 · 附件FTS5 派生索引可重建全文BGE-M3 sidecar隔离实验 · 默认关闭

↑ 依据项目 README「总体框架」mermaid(Clients → Workbench 本地回环服务 → 本地数据层)。三个使用入口共用同一个本地服务,所有读写都落在本机。

一、数据真源划分:文件是权、SQLite 是骨、索引是皮

项目最硬的一条架构原则,是每类数据只有一个权威位置(来自《系统架构与技术选型》§3.5“数据真源”):

原始资料(网页/论文/图片/附件/PDF)→ 受控文件目录(真相源)
项目·任务·讨论·决策·里程碑 → SQLite(真相源)
全文/图谱/向量 → 可重建派生存储(不是真源,丢了能重算)
密钥/访问令牌 → 环境或凭据存储(不进 Vault/DB/备份正文)

刻意不做“同一个项目对象同时写 JSON 和 SQLite”的实时双真源,因为双写必然在某个时刻丢一致。开放性靠完整 Schema、导出、备份和迁移工具保证,而不是靠复制数据。

选 SQLite 也不是随大流:它是 Node 24 内置的 node:sqlite,本地单用户无需独立数据库进程,支持事务、外键、prepared statement 和备份。不引入任何额外的原生 npm 二进制——这对一个要长期离线维护的个人工具很重要。

图片

二、五条稳定边界:UI 不该知道 SQLite

架构目标不是把所有能力堆进一个服务器文件,而是立起五条依赖边界(§1):UI 不知道 SQLite/Vault/Runtime;领域逻辑不依赖 HTTP/React/某个 Agent 框架;Repository 明确每类对象的唯一真源;检索/图谱/向量可从真源重建;所有 AI 工具和写操作都过权限、审批、审计与幂等。

依赖方向是严格单向的:

UI / Connectors
  ↓
HTTP / SSE Adapters
  ↓
Application Commands / Queries
  ↓
Domain + Policy
  ↓
Repository / Search / Runtime Ports
  ↓
SQLite / Files / Model / Harness / Hermes Adapters

关键约束是:下层适配器可以依赖上层定义的接口,领域层不得反向导入 Fastify、SQLite、React 或具体模型 SDK。这条我用一份 G2 架构决策单(A1–A15)落实,每个选择都有替代方案和影响——Node 24 LTS、React 19 + Vite 6、Fastify 5.12.1、node:sqlite、FTS5+trigram、REST+SSE、只监听 127.0.0.1。这不是“我喜欢的栈”,是逐一过评估后的收敛。

图片

三、单用户也要鉴权:本地不是免死金牌

项目在第 3.8 节把这条讲得很直白:首版虽然单用户,也不能把“只在本机”当成完整鉴权——恶意网页照样能探测本地接口。因此安全模型是:

· API 只监听 127.0.0.1,不提供 “改成 0.0.0.0 就能跨设备” 的偷懒开关;

· 启动时生成高熵会话令牌,用 HttpOnly + SameSite=Strict Cookie 绑定页面会话;

· 写请求校验 Origin、Content-Type、CSRF/nonce;文件工具做 realpath、白名单和符号链接逃逸检查;

· 权限过滤在搜索、对象读取、Tool Gateway 三层各强制执行一次——不是只挡一次。

图片

四、搜索:FTS5 是基线,向量是“待证明”的实验

首版只做可验证的全文基线:SQLite FTS5 用 trigram tokenizer 支持中文连续文本的子串检索,结构化过滤(space/project/type/time)先于正文返回,命中保存固定字符/块定位。

CREATE VIRTUAL TABLE context_search USING fts5(
  title, body, tokenize=‘trigram’
);
– ‘向量’ 能在 ‘向量数据库’ 里命中(子串)
SELECT object_id FROM context_search
WHERE context_search MATCH ‘“向量*”’;

向量检索(BGE-M3 sidecar)项目做了短样本修复与盲测,但边界 Top-1 质量门没过,所以结论非常克制:默认关闭、不进入生产依赖。只有当“固定评测集证明向量增益”后,才通过 SearchProvider 插口在 P1 接上。搜索的立场是——能用评测证明的才上线,其余一律关着。这是最容易让一个工程师点头的取舍。

五、AI 的一切都要“过审”:Tool Gateway 与候选审批

这是整套设计里我认为最有价值的部分。AI 产物的确可以有,但必须有证据、有范围、有审批,不直接污染长期知识:

· Native Runtime(native-v1)是进程内确定性执行器,不调模型、不联网,事件以持久化 run_id + seq 为真源;

· Tool 走候选机制:目前唯一可调 Tool 是 L1 “Task 候选” —— 它只把用户结构化输入存成待确认候选,不直接建任务;

· L2 审批:候选要经过本地拥有者 Approval + scope digest + 防替换 + 过期 + 版本校验,才在同一事务里落成真正 Task;

· 失败/越权 ToolCall 只持久化参数摘要和安全错误码,不保留可能敏感的全量参数。

一个 Agent Run 只有一个主 Runtime,Runtime 内部记忆只能产生待确认候选,任何外发/发布/删除/权限变更/长期知识写入都要求显式确认并审计。它刻意把“能做什么”和“自动做什么”划得很开——这正是当下很多 AI 工作台产品最缺的一层。

六、REST + SSE:每个改动都可重放、可溯源

· REST 管对象查询、命令、审批、取消、配置;SSE 管索引变化、Agent Run、后台导入和备份进度;

· 所有响应统一 request_id / status / data / errors / meta 信封;

· 创建/高影响命令要求 Idempotency-Key(重试不产生脏数据),修改要求对象 version(冲突 409 返回当前版本);

· SSE 事件含递增序号,客户端断线后可从最后序号恢复——这直接支撑了运行中心的中断续传和检查点恢复。

资料流转全景
多格式资料经捕获进入本地真源层,再被结构化沉淀——起点与控制权都在自己手里

七、多格式资料:文件为真源,登记文件指路

音频、视频、PDF 不是“传个附件就完事”的孤儿文件。按真源划分,二进制本体进受控文件目录,登记文件用 frontmatter 指过去,元数据进 SQLite 供检索和过滤:

—
type: material
format: audio    # text | audio | video | image | pdf
status: inbox    # inbox | processed | distilled
created: 2026-09-19
source: 技术播客
duration_seconds: 2400
asset: assets/audio/20260919-rag.mp3
captured_by: manual
tags: [RAG, 评估]
—
# 聊聊RAG评估
## 待办
- [ ] 提炼评估 checklist → wiki/concepts/rag-eval

受控导入只接受 API 正文里的原文,不接受客户端本地路径;原始字节按 SHA-256 内容寻址保存,结构化版本与审计在事务里提交——文件、索引、审计三者保持一致。

图片

八、这套架构教会我的三件事

1. **数据主权靠“单一真源”而非备份。**不双写、不复制,用清晰边界保住一致性,用导出/备份保证开放性。

2. **AI 能力的边界是工程能力,不只是模型能力。**没有审批、范围、审计的“AI 工作台”只是壳,决定性的是 Tool Gateway 这一层怎么设计。

3. **“默认关闭”是负责任的默认。**向量检索、外部 Runtime 都没有被吹成已投产,而是用评测和预检决定最低可接受标准,不过门就关着。

工具的价值不在功能多,而在数据可控、产出可验证。这套工作台对我就是:把知识学扎实,把机会抓得住,把内容写出来——而这一切,都建立在数据始终属于我自己之上。

感兴趣的话,我可以把 数据真源划分、Tool Gateway 候选审批 或 FTS5 vs 向量检索的取舍 单独拆成更细的文。评论区告诉我最想看哪块。

更多推荐