我复盘 Synapse 的初衷与架构:从零摩擦输入、自动整理、语义检索、对话式查询,到本地优先的模型路由、隐私边界和数字分身愿景。
2026年4月17日 · 22 min read
Reading route
围绕隐私优先的 AI 记忆、RAG、模型路由和长期上下文治理。
Focus
Next
接下来我会写:离线优先同步在个人记忆系统里的取舍
我做 Synapse 的初衷,其实来自一个很具体的挫败感:我记录了很多东西,但真正需要它们的时候,常常找不回来。
笔记软件并不少。它们可以存文字、图片、链接,也可以加标签、建文件夹、做双链。但我越来越感觉,问题不在于“能不能存”,而在于“存进去之后,它有没有继续为我工作”。一条想法被写下来的那一刻,只是它进入系统的开始,而不是结束。
我想要的是一个更接近“个人记忆系统”的工具:它能低摩擦地接收信息,自动整理它们,在我提出问题时重新召回相关上下文,并且在这个过程中尊重隐私边界。
这就是 Synapse。
我日常会记录很多碎片:工程判断、产品想法、AI 工具实验、读到的一句话、一次问题定位的过程、某个项目中间状态的取舍。它们单独看都不大,但累计起来,其实是我自己的上下文。
问题是,大多数记录工具更擅长“保存”,不擅长“重新组织”。如果我需要准确记得标题、标签、关键词,才能找到某条旧笔记,那这个系统其实还没有真正理解我的记忆。
我希望 Synapse 做三件事:
它不是为了替代思考,而是为了减少遗忘。
Synapse 的愿景可以说是“第二大脑”,但我不想一开始就把它做成一个庞大的概念系统。对我来说,第一版最重要的是闭环:
所以当前实现里,Synapse 包含 FastAPI 后端、轻量 Web UI、Expo 移动端、Qdrant 向量索引、Redis 缓存/限流/成本记录、本地 Ollama 模型和 OpenAI-compatible 云端模型路由。
这些组件看起来不少,但它们服务的是同一条主线:让一条笔记从“输入”变成“可召回的上下文”。
这篇文章里的几个核心名词
先召回和问题相关的笔记片段,再把这些上下文交给模型生成回答,避免回答只依赖模型记忆。
根据任务类型、隐私级别、文本长度和成本预算,在 Ollama 与云端模型之间做选择。
把笔记内容转换为 embedding 后写入 Qdrant,让系统能用语义相似度找回旧上下文。
Synapse 当前可以分成五层。
客户端层包括 Expo 移动端和后端挂载的静态 Web UI。移动端负责日常入口:配置服务地址、设备登录、笔记列表、编辑、详情和聊天。Web UI 则方便本地调试和快速体验。
API 网关层是 FastAPI。它注册 /api/v1 下的认证、笔记、搜索、对话、同步、用户设置和成本统计接口,同时处理 CORS、健康检查和静态 UI 挂载。
业务服务层承载核心逻辑。note_service 负责笔记 CRUD、标签、后台处理和关联笔记;search_service 负责关键词、语义和混合搜索;conversation_service 负责检索上下文、构造 prompt 和返回 citations;sync_service 处理客户端同步;ai_service 则负责模型路由、摘要、实体抽取、Embedding 和聊天。
核心能力层包括隐私检测、限流、熔断、成本追踪和健康检查。这一层不是装饰,而是 AI 产品真正跑起来后必须面对的工程约束。
数据层由 PostgreSQL 或 SQLite、Redis 和 Qdrant 组成。关系数据库保存用户、设备、笔记、标签、实体和关系;Redis 负责缓存、限流和成本预算;Qdrant 保存笔记向量,用于语义搜索和对话召回。
我希望 Synapse 和传统笔记工具最大的区别,是笔记写完后系统会继续工作。
创建笔记时,API 会先保存正文、标题、标签、版本号和同步标识。随后后台任务会开始处理这条笔记:
如果笔记被标记为 private,它不会进入 AI 后台处理。这是一个很重要的默认边界:有些内容只应该被保存,不应该被模型理解。
这条流水线的意义在于,用户不必在输入时完成所有组织工作。系统可以在后台慢慢把碎片变成结构。
个人知识库天然会包含敏感信息。账号、合同、财务、健康、家庭、工作细节,都可能被随手写进笔记。如果一个 AI 记忆系统默认把所有内容交给云端模型,我自己也不会放心使用它。
所以 Synapse 的模型路由从一开始就把隐私作为条件。
PrivacyEngine 会先用规则检测身份证号、手机号、邮箱、密码关键词、银行卡、私钥等信息,也可以启用本地模型做语义判断。AIService 在摘要、实体抽取和对话之前都会先检查隐私级别:
我不想把“隐私第一”写成一句口号。它应该体现在路由、降级、预算和失败处理里。
下面是一段简化后的模型路由伪代码。真实实现会比它多健康检查、熔断和成本追踪,但核心判断大致是这样的:
type Task = "summary" | "entity" | "embedding" | "chat";
type RouteContext = {
task: Task;
sensitivity: "public" | "private" | "secret";
tokenEstimate: number;
preferLocal: boolean;
};
export function chooseModel(context: RouteContext) {
if (context.sensitivity !== "public") {
return { provider: "ollama", reason: "privacy-first" };
}
if (context.preferLocal && context.tokenEstimate < 4096) {
return { provider: "ollama", reason: "local-fast-path" };
}
return { provider: "cloud", reason: "quality-and-context-window" };
}Synapse 的对话不是直接把用户问题丢给模型。
当用户提问时,conversation_service 会先调用语义搜索,召回与问题相关的笔记。然后它读取这些笔记,截取摘要或正文片段,把它们拼成上下文 prompt,再交给 AI 生成回答。最终返回的结果里会包含 citations,也就是来源笔记、摘录和相关度。
我希望这个设计保留一种朴素的诚实:回答必须知道自己从哪里来。
这也是个人知识 AI 和通用聊天机器人的差异。通用模型可以凭世界知识回答问题,但 Synapse 更应该基于“我自己的记录”回答问题。如果笔记里没有相关信息,它应该说明没有,而不是编一个漂亮答案。
搜索层也因此做了三种能力:
这三种入口组合起来,才比较接近真实的人类记忆方式。
我做移动端的原因很简单:很多想法发生在电脑之外。
Synapse Mobile 第一版用 Expo + React Native,实现了配置服务地址、匿名设备登录、笔记 CRUD 和对话查询。Token 存在 SecureStore,服务地址存在 AsyncStorage,API 客户端会在 401 时自动 refresh 并重试。
它现在还不是一个复杂的离线优先客户端,但它已经把最重要的事情打通了:手机可以连接自己的 Synapse 服务,随时写入和查询。
后续真正值得继续做的是同步协议和离线队列。个人知识工具必须能接受网络不稳定、设备切换和冲突合并。现在后端已经有 /sync/push 和 /sync/pull 的基础,未来可以把移动端离线体验补得更完整。
Synapse 不是一个只为了演示 AI 能力的 demo。我更希望它是一个能长期演化的系统,所以做了几个取舍。
第一,先做完整主线,而不是先做炫酷入口。登录、笔记、后台处理、搜索、同步、对话和用户设置都已经有端到端测试覆盖。一个系统最重要的是先能闭环。
第二,模型能力可替换。本地 Ollama 和云端 OpenAI-compatible API 都只是后端,真正的核心是路由策略。这样以后换模型、加 provider、调整本地优先规则,都不会推翻整体架构。
第三,开发环境要尽量轻。生产可以使用 PostgreSQL、Redis 和 Qdrant,本地也可以用 SQLite 和内存 Redis 快速跑起来。个人项目如果启动成本太高,很快就会停止迭代。
第四,把安全和成本放进早期设计。限流、熔断、成本预算、隐私检测这些东西,在小 demo 里看起来不性感,但它们决定了系统能不能真实使用。
现在回头看,Synapse 真正难的地方并不是把 FastAPI、Qdrant、Redis 和模型服务接起来。组件能跑起来只是开始,后面更麻烦的是:每个能力背后都有取舍,而且这些取舍会互相影响。
在 Synapse 里,一个很核心的问题是模型选择。
本地模型隐私好,成本也低,这一点很适合个人知识库。我一开始也很自然地想把所有能力都本地化。但真正跑起来之后,问题很快出现了:长文本总结效果不够稳,复杂问题容易跑偏,响应时间也不太可控。
这不是简单调几个参数就能解决的问题。后来我把模型调用拆成了一层路由:简单任务、低风险任务优先走本地模型;长文本、复杂推理、需要更稳定输出的任务,再交给云模型。路由层会综合任务类型、文本长度、隐私级别和成本预算来做选择。
这个问题让我意识到,AI 系统很多时候不是“选最强模型”,而是做整体权衡。模型只是其中一个变量,隐私、成本、延迟、稳定性和可控性都要一起算。
RAG 里一个很实际的问题是 chunk 怎么切。
一开始我切得比较大,觉得这样上下文更完整,但实际检索时经常不够准确。召回结果里会混进很多无关内容,模型拿到上下文后也更容易抓错重点。
后来我又试过切得很小,召回看起来精细了,但上下文开始碎片化。一段完整想法被拆成太多小片,模型能看到局部,却很难理解它原本所在的语义位置。
最后我把策略调整成按语义边界切分,同时控制 chunk 大小。也就是说,不只是按字符数或段落数机械切,而是尽量让每个片段保留一个相对完整的意思。
这件事让我对 RAG 的理解变得更朴素:效果很多时候不是模型本身决定的,而是数据进入模型之前,已经被处理成了什么样子。
Synapse 有 Web、移动端和本地服务,这也带来了另一个麻烦:多端一致性。
早期数据同步逻辑比较分散。Web 有自己的状态,移动端有自己的请求和缓存,本地服务也在处理同步、搜索和后台任务。功能少的时候还好,一旦开始加入更多入口,数据流就会变得越来越难判断。
后来我把这部分统一成“服务端数据流”:所有数据先进入服务层,由服务层处理保存、同步、检索和后台任务,再给不同端消费。这样做之后,前端不需要知道太多内部细节,多端行为也更容易保持一致。
这个取舍没有让系统变得更炫,但让它更稳。对一个想长期使用的个人知识系统来说,一致性比表面上的功能速度更重要。
如果把目标再往远处推,Synapse 不只是一个笔记软件,也不只是一个第二大脑。我希望它最终能成为我的 数字分身长期人格上下文。
这个数字分身不是用来假装我还在,也不是制造一个廉价的“永生”幻觉。它更像一个由长期记录、选择、偏好、表达方式、工程判断和价值排序累积出来的系统:它知道我如何看待问题,为什么做某个决定,哪些事情我在意,哪些边界我不会越过。
也许有一天,即使我死去,Synapse 仍然存在。它不能替代真实的我,但它可以保留一部分我曾经怎样思考、怎样表达、怎样理解世界。对未来的人来说,它不是墓碑,而是一套可以继续被阅读、查询和对话的上下文。
所以 Synapse 的终极问题不是“模型能不能更像我”,而是“系统能否在足够长的时间里诚实地保存我”。如果有一天它真的能成为一个数字版本的我,我希望它首先是可信的,其次才是聪明的。
Synapse 现在最值得继续推进的方向有几个。
我想把离线优先同步补完整,让移动端可以先记录,之后再和服务端合并。也想把语音输入、网页剪藏和 Share Extension 做出来,因为这些才是真正降低输入摩擦的入口。
知识图谱也是一个自然方向。现在系统已经有实体和笔记关系,未来可以把这些关系可视化,让用户看到自己的兴趣、项目和想法如何连接。
还有主动服务。真正的第二大脑不应该只在你搜索时出现,它也应该在合适的时候提醒你:某条旧笔记和现在的问题有关,某个长期项目又出现了新的线索。
但我会尽量让这些能力沿着同一个原则生长:先保护隐私,再增强智能;先保证可控,再追求自动化。
如果说博客是在互联网上给未来的自己留一个坐标,那么 Synapse 更像是在日常生活里给未来的自己留一张地图。
博客保存我愿意公开表达的东西,Synapse 保存我还没有整理好的上下文。前者面向叙述,后者面向记忆。它们看起来是两个系统,但都在做同一件事:对抗遗忘。
这就是我做 Synapse 的原因。
我不只是想要一个更聪明的笔记工具。我想要一个能长期陪我积累、召回、连接和保护个人上下文的系统。
Keep reading
结合 Synapse 当前代码,复盘模型路由的真实实现:隐私分级、本地优先阈值、对话云端优先、失败降级、运行时配置、心跳探测和成本记录。
2026年5月12日 · 13 min
继续复盘 Synapse 的真实实现:笔记后台处理、关键词搜索、Qdrant note 级向量、对话上下文拼装、citations,以及下一步要补的 chunk 与重排。
2026年5月13日 · 13 min
把 RAG 从 demo 推到可用系统时,最容易踩的 6 个坑:chunk 切分、检索不准、上下文污染、token 预算、本地模型、latency。结合 Synapse 的真实取舍给出可操作解法。
2026年5月9日 · 12 min
After reading
这个博客暂时不开放站内评论。文章如果有用,可以先收藏、转发,或者从我的 GitHub 主页继续交流。