news 2026/9/23 7:19:41

Supermemory:为AI应用打造长期记忆层,从部署到实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Supermemory:为AI应用打造长期记忆层,从部署到实战

最近一直在折腾给AI应用加“长期记忆”这件事。早期聊天机器人那种“关掉窗口就失忆”的状态实在太难受了——每次重新开会话,都得把背景重新讲一遍,仿佛对面坐着一个非常热情但记性极差的新同事。我试着用向量数据库自己搭RAG,但折腾来折腾去,发现真正的瓶颈不在“存储”,而在“怎么无感地把散落各处的信息收进来,再在需要的时候准确捞出去”。后来在GitHub上翻到一个叫Supermemory的项目,实际部署体验了一轮,发现它把这条链路做得相当完整,值得拿出来分享。

Supermemory定位很直接:它是AI应用的一个“记忆层”。你喂它URL、文档、纯文本,甚至推文链接,它帮你做抓取、清洗、摘要、向量化,最后统一存进可检索的存储里;之后你的Agent或聊天机器人就可以通过一句自然语言查询,召回几个月前你随手保存过的东西。这篇文章我会从它的核心架构讲起,给出完整的部署流程、关键接口实战,以及我实际运行中踩过的坑和解决方案,适合那些正在构建AI原生产品、或者单纯想给自己的知识库加一层智能索引的开发者参考。

1. 为什么我需要一个“第三大脑”:AI记忆问题的本质

1.1 光靠对话上下文撑不住真实场景

先聊聊我这边的痛点。之前做过一个内部知识库问答机器人,把公司文档切片后扔进向量库,看起来一切正常。但实际用起来问题很明显:文档本身就是静态的,而每个人问问题的“上下文”是动态的。今天问“我们上次讨论的缓存方案”,这个“上次”到底指哪次?如果没有跨会话的记忆,系统只能瞎猜。更头疼的是,知识来源不只是文档——还有群聊里的链接、网页收藏、看完的行业报告,这些东西平时根本没有结构化的入口进入知识库。

市面上大部分“AI记忆”方案解决的是对话历史的存储,说白了就是把你和ChatGPT聊过什么存下来,下次接着聊。但真实世界的记忆远不止对话,还包括你消费过的信息、保存过的链接、浏览过的页面。这才是Supermemory这类“记忆层”项目要解决的问题:把一个人/一个Agent的数字足迹变成可以查询的结构化记忆。

1.2 Supermemory是什么,以及它做对了什么

Supermemory这个项目,直白点说,就是一套可以从零部署的AI记忆后端。它的核心工作是把“非结构化内容”转化为“可供语义检索的知识”,并在其上封装了简单的API。它的几个设计决策我很认可:

  • 输入方式多:你可以直接丢给它一段纯文本(content),也可以丢给它一个URL,它会自己抓取网页正文,甚至支持推文和PDF;
  • 自动做摘要和实体提取:不是简单切片存向量,而是先用LLM生成摘要,让存储的粒度更接近“知识”而不是“文本碎片”;
  • 存储层用的是Cloudflare生态:部署在Workers上,数据库用D1(基于SQLite),向量检索也直接在D1里完成,不需要额外维护一套重型向量数据库;
  • 对外暴露的是HTTP API:任何语言都可以对接,Python、Node、Go都行。

我接触过的很多开源项目,要么只做了抓取,要么只做了向量化,Supermemory比较难得的是把所有环节串成了一条完整的流水线,而且给出了可以直接用的云端托管版本和自托管方案。

1.3 和主流方案的区别:它处在RAG和你之间

很多做RAG的朋友会问:我已经有LangChain + Pinecone了,还需要Supermemory吗?我的理解是,RAG框架解决的是“如何检索增强生成”,但Supermemory解决的是更前一步——“记忆从哪来、以什么形式存”。它不是要替代你的向量数据库或编排框架,而是处于它们上游的一个记忆采集与处理层,而且它开放了底层存储访问,你可以很轻松地对接自己的下游应用。

对我来说,最有价值的一点是它解决了“源头供给”的问题——给你的RAG管道持续供应“新鲜且经过清洗”的知识内容,而不是每次都要手动准备文档再切片,这是一套基础设施,不只是Demo。

2. 把Supermemory拆开看:核心模块与数据流转

2.1 六大模块各司其职

Supermemory的代码库结构非常清晰,每个模块干一件事,部署时也可以灵活选择用哪些。我按观察到的职责划分如下:

模块职责关键点
Hono API应用处理HTTP请求、鉴权、路由跑在Cloudflare Workers上
supermemory-core记忆的写入、查询、管理核心逻辑封装了所有业务操作
Scraper抓取并清洗URL内容支持网页、PDF、推文
Flows从Twitter、书签、GitHub Stars等导入数据属于上层导入器
Models(LLM调用)摘要、实体提取、嵌入向量默认用Cohere和Moonshot
Storage(D1 + KV + Queues)持久化、缓存、异步任务全在Cloudflare家

这种模块化最大的好处是:你如果只需要“内容清洗+向量化”,可以把Scraper和Models单独拎出来用;如果你只想用API,完全不用关心底层实现。我第一次看到这种拆分时,第一反应是“这项目不只是个玩具”,结构设计显然考虑了真实部署的可维护性。

2.2 一次完整的数据流转,从URL到答案

我用“保存一个网页”的场景来说明数据是怎么走的:

  1. 客户端调用API,提交一个URL,比如POST /v1/writebody里带上urltype
  2. Hono应用收到请求后,先做基础校验,然后把任务发给Cloudflare Queues队列——这是异步设计的关键,抓取一个慢网页可能要几秒甚至几十秒,不能占用HTTP请求的同步时间;
  3. Worker(队列消费者)拿到URL后,调用Scraper模块,抓取网页正文,去除导航、广告、脚本等噪声,得到干净的正文内容;
  4. 正文随后被送到LLM摘要模块,生成一段简明的摘要,并可能提取出关键实体;
  5. 摘要和正文标题被送进Embedding模块,用Cohere的embed-v3模型转成1024维向量;
  6. 向量和原始内容一起写入D1数据库;期间KV缓存会被更新,用于快速命中反复查询的内容;
  7. 之后,当用户通过/v1/query提交一个问题(例如“我上个月收藏的关于矢量数据库优化的文章讲了什么”),系统把问题向量化后,在D1里做余弦相似度或点积检索,取Top-K相似记忆,再返回给客户端。

这套流程最打动我的一点是“异步处理”的决策。很多自建的RAG管道都是同步做“抓取→切片→embedding”,一次请求可能耗时几十秒,用户直接看到超时。Supermemory把最慢的抓取和向量化环节放到了队列里,HTTP接口立刻返回“已受理”,然后在后台慢慢干,体验就顺滑很多。

2.3 为什么这套架构适合个人开发者和中小团队

先摆一个反直觉的结论:做AI记忆层,SQLite(D1就是SQLite的分布式版本)够用了,不需要一开始就上pgvector或Pinecone。

很多人的惯性思维是“向量检索必须用专业向量数据库”,但实际在个人知识库的体量下——几万条向量、每天新增几百条——D1里存的向量+暴力扫描或简单索引的查询耗时就足够用了。Supermemory用D1做向量存储,配合Cloudflare的全球边缘网络,查询延迟能控制在几百毫秒以内。这让部署和维护成本无限趋近于零,不需要额外管理一个数据库实例,不用操心备份和扩容。

对于已经跑在Cloudflare生态里的项目来说,这套方案几乎是零摩擦集成。如果你本来就是个Node/Worker架构,那Supermemory的接入就像装一个中间件那么自然。即使你是从零开始,创建一个Workers项目、配置好wrangler,整个部署过程我实测下来也能在半小时左右跑通。

3. 手把手部署:从空项目到可调用API

3.1 初始化项目,把仓库拉下来

依赖要求不高,本机装好Node.js 18+、npm,然后全局安装Cloudflare的CLI工具wrangler。我自己用的Node版本是20,跑起来完全没问题。

# 安装 wrangler npm install -g wrangler # 克隆项目 git clone https://github.com/supermemoryai/supermemory.git cd supermemory

然后安装依赖。这个项目用的是npm workspace,所以一定要在根目录执行,不要在子包里单独装:

npm install

装完依赖后,建议先把根目录下的.dev.vars.example复制一份成.dev.vars——这是本地开发环境的变量配置文件,后端的密钥都放在这里:

cp .dev.vars.example .dev.vars

3.2 在Cloudflare控制台创建配套资源

Supermemory部署需要三样Cloudflare资源:D1数据库(存储记忆和向量)、KV命名空间(缓存)、Queues队列(异步任务处理)。我用wrangler命令逐一创建,然后记录返回的ID,后面写配置要用的。

# 创建D1数据库 wrangler d1 create supermemory-db # 创建KV命名空间 wrangler kv namespace create SUPERMEMORY_KV # 创建队列(这里需要登录Cloudflare账号) wrangler queues create supermemory-queue

创建D1和KV后,wrangler会输出对应的database_idid,把它们填到wrangler.tomlwrangler.jsonc的对应字段里。如果用的是新版wrangler,配置文件里D1的写法大致是这个样子:

{ "d1_databases": [ { "binding": "DB", "database_name": "supermemory-db", "database_id": "你的D1数据库ID" } ], "kv_namespaces": [ { "binding": "KV", "id": "你的KV命名空间ID" } ] }

3.3 配置模型密钥与关键环境变量

Supermemory的向量化默认走Cohere的embed-v3,摘要生成走Moonshot AI(EclipseMoonshot)或者OpenAI兼容接口。你需要去对应平台申请API Key,填进.dev.vars里。我整理了一份对照,方便知道每个变量是干什么的:

变量名用途获取地址
COHERE_API_KEY调用Cohere嵌入模型生成向量Cohere Dashboard
MOONSHOT_API_KEY调用Moonshot模型生成摘要/提取实体Moonshot平台
KVKV绑定(在wrangler里配置)Cloudflare控制台
DBD1数据库绑定(在wrangler里配置)Cloudflare控制台
TURNSTILE_SECRET_KEY人机验证密钥(不用的可忽略)Cloudflare Turnstile

配置完后,wrangler dev启动之前,可以先跑数据库迁移建表。Supermemory的迁移文件在packages/db或类似目录下,用wrangler的migration命令执行:

npx wrangler d1 execute supermemory-db --file=./packages/db/migrations/0001_init.sql

如果本地迁移执行成功,D1里就会生成memoriesdocuments这些核心表,后面写入和查询都靠它们。

3.4 本地跑通与线上发布

初始化完成后,本地启动:

npm run dev

wrangler会给你一个本地地址(一般是http://localhost:8787)。保险起见,先用健康检查接口试一下通不通:

curl http://localhost:8787/health

返回正常的话,就可以先写一条记忆试水。确认一切正常,然后发布到线上(需要已经登录Cloudflare账号):

npx wrangler deploy

部署成功后,Cloudflare会分配一个*.workers.dev域名,这个就是你的线上API地址。走到这里,你已经拥有一个可以随时写入和检索记忆的服务了。整个过程不算复杂,但对不熟悉Cloudflare生态的开发者,最耗时间的往往是“搞懂D1、KV、Queues之间的绑定关系”,所以我专门把这份配置关系放在上面,建议先对照着看清楚再动手。

4. 核心接口实战:写入知识、检索记忆

4.1 写入记忆:直接喂纯文本

Supermemory接口风格走REST,简洁直白。写入一条纯文本记忆,调用/v1/write即可:

curl -X POST https://你的域名/v1/write \ -H "Content-Type: application/json" \ -d '{ "type": "content", "content": "分布式系统设计中,最终一致性和强一致性的取舍需要结合业务场景,例如支付系统更关注强一致性,而社交媒体的点赞数可以接受最终一致性。", "title": "一致性权衡笔记", "source": "manual-note" }'

服务器处理后会返回一个UUID,比如"memoryId"字段,这就是这条记忆的标识。响应很快,因为实际写入和向量化在后台队列里异步跑,接口只负责受理任务。

4.2 写入记忆:抓取一个URL

抓取网页是Supermemory的拿手好戏。之前做知识管理的时候,最烦的就是“把网页正文提取干净”,各种广告、弹窗、导航栏混在里面。Supermemory的Scraper模块用@mozilla/readability一类的库做正文提取,实测下来对主流的博客站、文档站效果都挺干净。

curl -X POST https://你的域名/v1/write \ -H "Content-Type: application/json" \ -d '{ "type": "url", "url": "https://jvns.ca/blog/2024/01/01/some-notes-on-http/", "source": "pocket" }'

有两点要注意:一是type字段要填url,别填content,否则系统会认为请求体里的content字段才是正文;二是URL别带重定向链太长,否则抓取超时会自动失败。

4.3 检索记忆:用自然语言查“模糊的东西”

我觉得Supermemory检索接口做得最有价值的地方是:它允许你用语义查询,而不是非得记准关键词。比如你只记得看过一篇关于HTTP缓存的文章,但想不起标题,可以这样查:

curl -X GET "https://你的域名/v1/query?q=HTTP缓存的策略和注意事项" \ -H "Content-Type: application/json"

返回结果是一个数组,包含Top-K个最相关的记忆,每个记忆里带contenttitlesourcecreatedAt和相似度分数。你可以根据自己的应用场景,把返回结果直接拼进Prompt,让大模型基于这些记忆来回答。

4.4 权限与用户隔离:多用户记忆的分开存储

Supermemory的API默认是开放模式,只要知道API地址就能写入和读取。如果要做成产品,给不同用户分开记忆,需要自己在应用层加一层“用户标识”,或者在路由前面加一层鉴权逻辑。我的做法是封装一个中间层:每个请求带上自己的X-User-Id,由中间层校验身份并调用Supermemory的写入/查询接口。原因很简单——Supermemory本质上是“记忆引擎”,账号体系还是得自己做,它并不负责认证和用户管理。

5. 真实运行中的坑:我踩过的五个问题

5.1 嵌入模型维度不匹配导致静默失败

我第一次部署后调用写入接口,接口返回成功,但查询时老是什么都查不到。查了日志才发现,D1里存的向量维度是1536维(OpenAI的text-embedding-ada-002),而查询时用的模型或者代码里配置的维度是1024维(Cohere embed-v3)。Supermemory默认配置是用Cohere的,如果自己改过模型或者配置项没统一,就会出现这种“写是写进去了,但查不出来”的静默失败。

解决思路:要么把环境变量里的VECTOR_DIMENSION和模型对应好,要么直接调用wrangler d1 execute查一下表里的向量长度,确认和查询侧一致。这个坑特别隐蔽,因为它不报错,纯粹是数据层面维度对不上,相似度计算直接失效。

5.2 队列任务超时:大PDF直接卡死

抓取一个2MB的PDF时,任务在队列里跑了超过30秒还没结束,最终超时。原因是Scraper处理PDF时要做文本提取,大文件还要逐页处理,整个过程耗时很长,超过了我设置的队列超时上限。

调整方案有两个方向:一是把队列消费者的max_retries调大,超时后自动重试;二是把抓取超时时间从默认的15秒上调到60秒(在队列配置里设置)。我采用的是后者,实测处理5MB以内的PDF基本能稳定跑完。如果PDF超过10MB,建议自己先把文档拆分,再分别喂给Supermemory。

5.3 摘要模型返回空的边界情况

有一次抓取一个纯图片构成的网页,正文提取后几乎是空的,但Scraper没有报错,而是把一段空白内容送给了摘要模型,结果摘要模型返回了空字符串。这导致后续流程里虽然生成了向量,但向量本身是“空内容”的向量,检索时会造成大量噪声。

我在代码层加了一个保护:正文清洗后长度少于100个字符的内容,直接丢弃,不进入摘要和向量化环节。这个阈值可以根据自己的业务调整,但核心原则是“宁可不存,也不要存垃圾”。这个经验适用于所有知识库类的项目,不只是Supermemory。

5.4 速率限制与冷却策略

Cohere和Moonshot这类模型API都有速率限制(RPM/TPM)。默认配置下,如果一批导入任务同时进来(比如我一次性导入100个书签),队列会同时发多个请求去打模型API,很容易触发429限流。一开始我以为是自己配置问题,查了日志才发现是并发太高。

后来的处理是:在队列消费者的处理流程里加一层速率控制,比如每次最多并行3个抓取任务,多余的任务在队列里排队等着。Cloudflare Queues本身支持max_concurrency配置,我把它从默认的10调低到3后,429再也没出现过。如果你的模型API配额比较高,可以适当调高并发。

5.5 KV缓存的命中率优化

Supermemory里KV缓存主要用来存网页抓取的中间结果,避免同一个URL反复抓取。但默认的缓存策略对于“不同的URL但在相同域名下,页面结构变化不大”的场景命中率不高。我实际使用中把缓存的TTL(Time To Live)从默认的1小时调到了24小时,因为对于大多数博客文章来说,内容在一天内不会变。这样二次查询时会直接命中缓存,少一次抓取和embeddings调用,省时也省钱。

6. 把它接到自己的Agent/工作流里

6.1 给聊天机器人装一个“外挂记忆”

部署完Supermemory一周后,我开始把它接进自己的聊天机器人测试。实现的逻辑其实很简单:用户每次提问时,先用/v1/query把问题送进Supermemory检索,拿到Top-3相关的历史记忆,然后把记忆内容作为System Prompt的一部分拼进上下文,再让大模型生成回答。这样用户问“我之前有没有收藏过关于xx的帖子”,机器人就能基于记忆来回答,而不是一脸茫然。

下面这段伪代码展示了我接OpenAI时的做法,你可以直接用在自己项目里:

// 用一个中间函数把Supermemory接入你的Agent async function getRelevantMemories(question) { const resp = await fetch(`https://你的域名/v1/query?q=${encodeURIComponent(question)}`); const memories = await resp.json(); return memories.slice(0, 3).map(m => m.content).join("\n"); }

这个方案也有局限性:如果用户的记忆里根本没有相关信息,检索返回的结果可能并不相关,需要做一层相关性过滤。我使用的是分数阈值法——相似度低于0.5的结果直接丢弃。

6.2 做一个每日回顾:用Flows自动积累

Supermemory提供的“Flows”概念很实用——它可以把你的外部数据源(比如Twitter收藏、GitHub Stars、Pocket书签)自动同步过来。我搭了一个定时任务:每天早上从我的Pocket里拉取新增的书签,批量写入Supermemory,这样我的知识库每天都会自动更新,不需要人工干预。

真正让我觉得这个项目“值得一用”的瞬间,是我在两周后某天问它“我之前看到过一篇讲SQLite性能优化外文文章”,它准确地把那篇存过的文章标题和链接捞了出来。那一刻的感觉是:AI终于开始记得我“看过什么”了。

6.3 后续还能怎么玩

如果想更进一步,这几个方向值得尝试:

  • 把Supermemory和浏览器扩展结合,做“一键收藏当前页面”,任何网页都能1秒进入记忆库;
  • 对接微信/Telegram机器人,让它成为个人助理的“记忆后端”;
  • 在团队内部署一套,共享团队知识,但要注意在API前面加好鉴权和用户隔离。

写在最后

部署Supermemory之前,我一度觉得“AI记忆”是个大工程,要自己搭向量库、写抓取服务、设计embedding管道。实际把它跑起来之后,最大的感受是:这个领域已经有人在认真做“基础设施”了,不需要每个开发者都从轮子开始造。你可以把它当成一个“自托管的记忆API”来玩,也可以参考它的架构设计自己实现一套——不管哪种方式,我觉得这套“异步采集+LLM摘要+向量存储+语义检索”的模式,会是未来AI应用的基本底盘之一。项目本身还在快速迭代,社区也活跃,遇到问题去GitHub Issues里搜一搜,大概率能找到答案。如果你也在为AI的“七天记忆”发愁,花一个下午把它部署起来,应该不会让你失望。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/23 7:19:32

BLE主机与从机怎么选?从连接关系看主从一体模块的工程价值

在BLE终端开发中,主机(Central)和从机(Peripheral)的选择,实际上决定了设备如何发现对方、谁主动建立连接以及后续数据如何交互。常见的传感器、按键、外设等终端通常采用从机方式,通过广播等待…

作者头像 李华
网站建设 2026/9/23 7:18:45

基于 Java Spring Boot 的化妆品推荐系统设计与实现

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 1. 项目背景与意义 随着人们生活水平的不断提高,化妆品已成为日常消费的重要组成部分。面对市场上琳琅满目的化妆品品牌和种类,消费者往往难以快…

作者头像 李华
网站建设 2026/9/23 7:17:25

芝加哥时间与CST/CDT时区换算:消除歧义与代码实现

芝加哥现在几点?这问题听起来简单,真要对答案的时候很多人会懵一下。原因不是你不会查时间,而是查时间的时候会碰到两个缩写:CST 和 CDT。你要是直接搜索“CST”,结果往往五花八门,甚至可能搜出仿真软件 CS…

作者头像 李华
网站建设 2026/9/23 7:17:11

Java直接内存原理与JVM管理机制详解

1. 直接内存的本质与Java内存模型的关系直接内存(Direct Memory)是Java中一个容易被误解的概念。很多人以为它完全不受JVM管控,实际上情况要复杂得多。直接内存本质上是通过Java的NIO包中ByteBuffer.allocateDirect()方法分配的内存区域&…

作者头像 李华
网站建设 2026/9/23 7:16:39

打印机驱动安装全攻略:四种方法详解与避坑指南

打印机这东西,平时安安静静待在角落,一旦罢工,整个办公室都能听见有人喊“谁把驱动删了”。我见过太多人抱着打印机说明书翻半天,最后还是在网上随便下了一个来路不明的驱动包,结果装完系统蓝屏。也见过有人明明插着US…

作者头像 李华
网站建设 2026/9/23 7:16:26

短视频批量生成方案对比与选型指南

1. 短视频批量生成的核心需求解析在内容创作领域,批量生成短视频已经成为许多创作者和企业的刚需。这种需求主要来自三个方面:首先是内容电商领域需要大量商品展示视频,其次是自媒体运营需要保持高频更新,最后是教育培训行业需要快…

作者头像 李华