你的Agent 为什么会失忆?不是上下文窗口给得不够大

做Agent 工作流这段时间,我一直有个挥不去的感觉——我们好像一直在解决一个错误的问题。

每次 Agent 开新会话就失忆,大多数人的第一反应是往prompt 里塞更多东西:把上次的决策记录塞进去,把项目背景塞进去,把之前 踩过的坑也塞进去。上下文窗口越来越大,大家也就越塞越多,好像只要窗口足够大,问题就能解决。

但这个逻辑本身就是错的。

窗口大小解决的是"单次会话能处理多少信息",而不是"信息能不能跨会话保留"。这是两个性质不同的问题。把历史记录手动塞进 pro mpt,本质上是用人力去弥补系统缺失的持久化能力——会话一关,那些"记忆"照样清零。下次打开,重新塞。这不是记忆,这是搬运。

我自己做嵌入式出身,后来做储能系统,现在碰 AI 工程化。这几个方向有一点是共通的:如果你一直在用应急手段解决一个结构性问题,迟早要还债。

意识到这一点之后,我开始认真找专门解决 Agent 持久记忆的工具,最后选了 EverOS。


一、为什么不自己搭一个

最直觉的方案是自己搭:选个向量数据库,写一套存取逻辑,把 Agent 需要记住的东西序列化进去。我之前也考虑过这个方向,但做过几个 RAG 项目之后,对"自建向量库"这件事有了一些不太美好的经验。

核心问题不是搭不起来,而是出问题之后你搞不清楚发生了什么。

向量数据库是典型的黑箱:你喂进去一段文本,它在里面做嵌入、建索引,检索时给你返回一批相似度分数。理想情况下这个流程很流畅,但一旦出了问题——检索结果不对、记忆里存了脏数据、Agent 的行为开始漂移——你几乎没有直接的手段去看清楚里面到底存了什么。调试靠猜,修复靠蒙。

这对我来说是不可接受的。工程系统的一个基本要求是可观测性:你能知道里面在发生什么,能介入,能修。一个你看不进去的记忆系统,出了问题等于在排查一个黑盒——这种感觉,做过硬件调试的人大概都懂。

EverOS 吸引我的原因,正是它在这个问题上的设计取向:记忆的最终载体是 Markdown 文件,你能cat,能 grep,能用 Git做版本管理,能用编辑器直接改。


二、它怎么工作的

EverOS 的存储是三层:Markdown 作为唯一可信来源,SQLite 管理状态和处理队列,LanceDB 负责向量检索、BM25全文索引和标量过滤。

三层里最重要的是第一层。所有记忆最终都会落成 .md 文件,结构化、可读、可编辑。SQLite 和 LanceDB
是查询加速层,让检索速度不至于太慢,但"记忆里有什么"这个问题,直接去看 Markdown 就能回答。

检索策略是混合的:BM25 处理关键词,向量 ANN 处理语义相似度,LanceDB 统一承载并支持按 user_id
等维度做精确过滤。这意味着同一条记忆,就算你换了问法,也能被召回。官方在LoCoMo 上跑出了93.05%,LongMemEval-S 是83.00%,HaluMem大概 90% 出头,数据说得过去,但我真正在意的不是这几个数字,而是"记忆我能直接打开看"这件事。

记忆的组织方式上,EverOS 做了一个我觉得比较合理的分离:users/ 目录存用户相关的情景记录和画像,agents/ 目录存 Agent 自身积累的案例和技能。两条线分开抽取,相互不污染。用户的偏好变了,改用户画像;Agent 学到了新的处理模式,更新Agent 的案例库。这个结构比把所有东西混在一起要清晰得多。


三、实际怎么装

环境要求不高:Python 3.10以上(推荐 3.12+),uv 包管理器,两个 API key——OpenRouter 管LLM 和多模态,DeepInfra管向量化和重排。

手头有 OpenAI key或者本地跑着 Ollama 的,不用换账号,EverOS 兼容所有 OpenAI 协议端点,改一下配置里的 base URL 就行。

uv 没装过的话:

curl -LsSf https://astral.sh/uv/install.sh | sh

装EverOS 有两种方式,按需选一个。想读代码或者做改造:

git clone https://github.com/EverMind-AI/EverOS.git cd EverOS uv sync source .venv/bin/activate

只是接进项目用:

uv pip install everos

然后初始化:

everos init

会生成一个 .env 文件,填进两个 key。顺手把 .env 加进 .gitignore,这是基本操作,但忘掉的概率很高,提前说一次。

验证环境:

everos --help

能看到命令列表就装好了。


四、跑通核心流程

启动服务:

everos server start

这个终端保持运行,新开一个做健康检查:

curl http://127.0.0.1:8000/health

返回 {“status”:“ok”} 说明服务起来了。

接下来写入一条记忆。注意带上 user_id,这个参数决定这条记忆归属于谁,也是多用户场景下记忆不串台的关键:

# 确切命令以仓库根目录 QUICKSTART.md 为准 everos memory add --user-id alice "Alice 写代码偏好 TypeScript,不用 any 类型"

这条命令触发后,EverOS 在后台做了三件事:对内容做结构化抽取,落盘成 Markdown,同步进SQLite 和 LanceDB的索引。

现在关掉这个会话,模拟第二天打开,用自然语言搜:

everos memory search --user-id alice "Alice 有什么编程偏好?"

如果能搜回刚才那条记录,跨会话记忆就跑通了。


五、记忆文件实际长什么样

完成上面的步骤之后,去看一下 ~/.everos:

~/.everos/ └── default_app/ └── default_project/├── users/alice/ │ ├── user.md # Alice 的用户画像 │ ├── episodes/ # 按天记录的情景日志 │ ├── .atomic_facts/ # 原子事实(隐藏目录) │ └── .foresights/ # 预测性记忆(隐藏目录) └── agents/<agent_id>/ ├── agent.md └── .cases/ # Agent 的案例库

打开 users/alice/user.md,刚才写入的偏好已经被结构化整理进去了,格式清晰,完全可读。你想修改一条记错的内容,用编辑器打开直接改就行,不需要任何 API 调用。整个 ~/.everos 目录可以用 git init 纳入版本管理,记忆的变更历史就有了。

如果你用Obsidian,把 ~/.everos 直接作为 vault 打开,Agent 的记忆就变成了一座可以浏览的知识库,这个体验比较直观。


六、几个容易翻车的地方

网上能搜到很多 EverOS 的教程,大部分讲的是它早期的重型版本,需要 docker-compose 拉起 MongoDB、Elasticsearch、Redis 一整套服务。这个版本已经不是现在的 EverOS 了,照着操作,第一步就会出问题。

现在的 1.0.0 轻量版整个设计方向就是去掉这些外部依赖,everos init 和 everos server start 这套CLI 就是全部入口。

另一个坑:Office 文档(.docx/.pptx/.xlsx)的解析依赖系统安装 LibreOffice,没装的话这类文件会失败,但PDF、图片、音频不受影响。多模态摄取是一个可以继续探索的方向,支持把 PDF、图片、网页 URL 直接吃进记忆,一次API调用,不需要自己写解析层。

路线图上还有两个方向:Knowledge Wiki(把碎片记忆整理成可版本化的 wiki页)和 Reflection(系统空闲时连接弱信号、压缩历史记录、主动改进画像)。目前这两块还在开发中,方向是有价值的,但不要指望现在就用。


七、说几句实在话

我现在把它用在 Claude Code 和 Codex 相关工作流的记忆层上,跑了一段时间没遇到大问题。

回头看,它解决的是一个工程上挺基础的问题:让一个原本无状态的系统有了可持久化、可检索、可审查的状态存储。说出来简单,但在Agent 这个领域,真正把它做成透明的、开发者能直接介入的形态,目前见到的方案里EverOS 算是做得比较彻底的一个。

对于在搭Agent 工作流、LLM应用、或者编程助手的人来说,记忆层是个绕不开的问题。与其等到上下文塞满了再临时补救,不如从一开始就把这层设计进去。

仓库地址:https://github.com/EverMind-AI/EverOS

本文基于EverOS 1.0.0轻量版,跑分数据为官方口径。仓库迭代较快,操作前建议以仓库根目录 QUICKSTART.md 中的最新写入/检索命令为准。