结合 Synapse 当前代码,复盘模型路由的真实实现:隐私分级、本地优先阈值、对话云端优先、失败降级、运行时配置、心跳探测和成本记录。
2026年5月12日 · 13 min read
Reading route
围绕隐私优先的 AI 记忆、RAG、模型路由和长期上下文治理。
Focus
Next
接下来我会写:离线优先同步在个人记忆系统里的取舍
做 Synapse 的过程中,有一个判断越来越明确:模型路由不是在代码里写几个 if else,然后把任务丢给本地模型或云模型。
如果只是 demo,这样当然能跑。但 Synapse 不是为了演示一次回答,而是要长期处理个人笔记、搜索、对话、摘要和实体抽取。这里面有隐私、质量、延迟、成本、可用性,还有一个很现实的问题:本地模型和云模型都不稳定地“完美”。
这篇文章只写当前代码里已经落地的部分。Synapse 的模型路由主要在 synapse-server/app/services/ai_service.py,周围还连着 PrivacyEngine、CircuitBreaker、CostTracker、云端配置热更新和 Web 控制台。
从代码看,模型相关的调用主要有四类:
这几类任务并不是同一种问题。摘要和实体抽取通常发生在笔记创建后的后台处理里;对话发生在用户显式提问时;embedding 更像检索系统的基础设施。把它们都交给同一个模型,表面简单,实际会把隐私、延迟和质量问题混在一起。
所以当前 Synapse 的后端先做一层路由:
输入内容
→ 隐私检测
→ 判断任务类型
→ 判断文本长度和本地优先策略
→ 本地 Ollama 或云端 OpenAI-Compatible API
→ 记录成本 / 处理熔断 / 必要时降级这条链路最重要的不是“用了哪个模型”,而是每一步都在降低系统不可控性。
Synapse 里的隐私判断在 app/core/privacy.py。当前实现不是单纯让模型猜,而是先用规则做确定性检测:
这一步输出的是 PUBLIC、SENSITIVE、HIGHLY_SENSITIVE 三档。到 AIService 里,HIGHLY_SENSITIVE 会强制走本地模型。
隐私路由规则
强制本地处理,不进入云端生成链路。
继续根据任务类型、文本长度和配置做路由。
语义层也是本地模型参与,避免“为了检测隐私而先把隐私发出去”。
这也是我对隐私优先的理解:不是在产品文案里说“重视隐私”,而是让敏感内容在架构上没有机会进入云端路径。
Synapse 的默认配置里有几个关键参数:
cloud_ai_enabledcloud_ai_model_chatcloud_ai_model_embedai_use_local_firstai_local_text_max_lengthai_cloud_timeout_seconds这里最关键的是 ai_use_local_first 和 ai_local_text_max_length。当前默认策略是:如果启用了本地优先,并且文本长度没有超过阈值,就走本地 Ollama;长文本或复杂任务再考虑云端。
这不是“本地模型一定更好”,而是先把低风险、低复杂度、低成本的任务留在本地。
云端未启用 → 本地
高敏感 → 本地
本地优先 + 短文本 → 本地
长文本 / 更复杂任务 → 云端这个设计来自一个很朴素的现实:本地模型适合处理明确、短小、隐私敏感的任务;云模型更适合长文本、复杂推理和高质量表达。二者不是信仰选择,而是资源调度。
在 AIService.chat 里,对话任务有一个特殊处理:它会用 force_cloud 倾向云端。
原因很简单:用户问问题时,对答案质量和稳定性的预期更高。摘要失败可以晚一点补,实体抽取失败可以重跑,但一次对话如果回答跑偏,体验会直接断掉。
不过代码里没有把云端当成唯一出口。云端调用失败时,会降级到本地 Ollama:
conversation
→ 优先云端
→ 云端不可用
→ 降级本地
→ 本地也不可用
→ 返回空结果,由对话服务给出可理解的错误提示这比“永远云端”更稳,也比“永远本地”更实际。
对话不直接把用户问题丢给模型。conversation_service.py 里先用 search_semantic 检索相关笔记,再把摘录拼进 prompt。
当前实现有几个真实细节:
这里要说一个真实边界:当前 Synapse 的向量检索粒度主要还是 note-level embedding。也就是说,Qdrant 里存的是笔记向量,不是成熟的 chunk 级索引。后续如果笔记越来越长,需要把 chunk 层补上,否则长笔记内部的精确召回会有上限。
Synapse 有一个我很喜欢的点:云端模型配置不只写在 .env 里。
cloud_ai_runtime.py 做了一个进程内覆盖层,管理端可以通过 /api/v1/admin/ai-cloud 修改这些配置:
Web 控制台里的 CloudModelsPage 对应了这套能力。它不是为了“看起来像后台”,而是为了让模型路由可以在运行中调整。
这对个人系统也很重要。比如本地模型升级了,可以把阈值调大;云端接口不稳定,可以临时关闭云端;某个模型质量下降,可以切换模型名,而不用重启整个服务。
模型调用最怕一种情况:外部服务已经不稳定了,系统还在持续打过去,把延迟、失败和成本一起放大。
Synapse 现在做了三件事:
这些看起来像运维功能,但实际上会反过来影响产品体验。一个 AI 记忆系统如果不能知道“模型现在是否健康”“这次调用花了多少钱”“失败后怎么降级”,就很难长期稳定运行。
也要诚实说当前边界:成本追踪已经落库和进 Redis,can_use_cloud 也已经有预算判断,但它还没有完整接入 AIService._should_use_cloud 的路由决策。也就是说,当前更像“记录与观察已经具备”,下一步才是“预算成为路由门闸”。
如果只看最终效果,用户只会看到一句回答、一段摘要、几个实体标签。但在系统里面,真正难的是这些问题:
Synapse 当前的答案还在演进,但方向已经确定:模型不是系统中心,路由才是系统中心。模型会变,供应商会变,本地硬件会变,真正要沉淀下来的是一套判断和调度机制。
当前代码里的路由坐标
PrivacyEngine 先做规则和可选语义检测,高敏感内容强制本地。
摘要、实体抽取、对话、embedding 分开处理,不假设一种模型适合所有任务。
对话更偏向云端,并保留本地降级路径。
熔断、心跳和健康检查让模型服务状态变得可观察。
云端调用已经有 token 和费用记录,预算门闸是下一步要接进路由的部分。
如果把 Synapse 看成一个长期记忆系统,模型路由其实是在回答一个更大的问题:哪些记忆应该留在本地,哪些问题值得借助云端,哪些失败必须被系统消化掉。
这比“接一个更强的模型”慢一点,但更像一个能长期运转的系统。
Keep reading
我复盘 Synapse 的初衷与架构:从零摩擦输入、自动整理、语义检索、对话式查询,到本地优先的模型路由、隐私边界和数字分身愿景。
2026年4月17日 · 22 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 主页继续交流。