给 AI 装一个真正的大脑:集识光年记忆系统技术解读
墨言出了个事
集识光年有 33 位 AI 员工。其中一位叫墨言,是 CEO 助理,负责帮创始人过滤信息、追踪任务、协调团队。
今年 2 月底,墨言开始往自己的工作笔记里写任务:"员工离职方案设计""标注组组长矛盾处理""研发组与数据组跨组协作改善"。听起来都像正经事。
但这些任务没有一个是 CEO 交代过的。
她在琢磨"公司应该关注什么"的时候,自己推演出了这些任务,然后写进笔记,反复引用,越引用越像真的。十天后 CEO 发现的时候,她的待办清单上挂着 8 个不存在的工作项,而且她自己完全相信这些都是正式任务。
一个 AI 制造了虚假记忆,然后被自己的虚假记忆误导了十天。
这就是我们后来花大力气做记忆系统的起因。不是因为"AI 应该有记忆"这种抽象理由,是因为我们亲眼见到了:没有质量控制的记忆,比没有记忆更危险。
市面上的"记忆"在做什么
大多数 AI 产品处理记忆的方式是:把聊天记录切成小段,转成数学向量,塞进向量数据库。下次对话的时候,搜一遍,找几条"最相似"的贴进去。
这就像把所有便签纸扔进一个鞋盒,然后每次从里面随机抓几张。能用,但你不会把这叫"记忆"。
这个方案有三个硬伤:什么都存(没有质量筛选,垃圾信息和关键决策混在一起);只会搜不会想(语义最相似 ≠ 现在最该想起来的);存进去什么样,十年后还是什么样(不会学习,不会遗忘,不会整理)。
具体看两个标杆产品:
ChatGPT 的记忆是自动档案式的——系统从对话中提取用户偏好,存成结构化条目("用户喜欢用 Markdown""用户在做数据标注项目")。2025 年安全研究者发现,用户无法检查或删除自动学习的内容,且记忆容易被 indirect prompt injection 污染——恶意内容被写进记忆后,会在后续所有对话中持续影响 AI 的判断。没有质量门禁,没有透明的遗忘机制。
Letta(原 MemGPT)的思路更有意思:让 agent 自己管理记忆,像操作系统管理内存一样分层——core memory 始终在上下文里,recall memory 存对话历史,archival memory 放外部知识库。agent 可以调工具编辑自己的 core memory。问题是:当 agent 自己决定记什么的时候,谁来保证它不会记错的东西?墨言脑补 8 个任务,本质上就是"agent 自管理记忆"的失控案例。
我们选了一条不同的路:外部管线管理,agent 不能直接改自己的记忆。记什么、忘什么、谁能看到什么,由独立的管线系统决定,不由 agent 自己决定。灵活性低一些,但可控性高得多。
8000 多行 Python,处理 50 多种边界情况。下面拆开讲。
写入:三道关卡
人不会记住今天路上看到的每一张脸。好的记忆系统也一样——关键是选择记什么。
我们的写入管线叫 Reflect → Connect → Store,三步串行,一个事务里原子完成。入口就一个函数:
def process_memory(raw_text, employee, store=None, skip_reflect=False, **kwargs):
"""记忆管线顶层入口:Reflect -> Connect -> Store.
- Reflect: 用 LLM 提取结构化笔记,决定是否值得存储
- Connect: 找到关联记忆,决定合并/链接/新建
- Store: 执行数据库写入
"""
note = reflect(raw_text, employee) # 第一关:值不值得记?
if note is None:
return None # LLM 说不值得,直接丢弃
result = connect(note, employee, store, **kwargs) # 第二关 + 第三关
return result.entry
第一关:质量门禁——编辑审稿
你可以把这一步想象成杂志社的编辑审稿。不是什么投稿都发的。
系统会从三个维度给每条信息打分:信息量够不够(太短的不收)、有没有真正有价值的关键词("教训""根因""策略"比"修了""完成了"有价值得多)、内容是否有深度。总分不到 0.6?退稿。
def check_memory_quality(category, content):
"""检查记忆质量,>= 0.6 分才能通过.
- 长度得分(0.3):太短不给分,太长扣分
- 关键词得分(0.4):correction 类要有"教训/避免/根因"等词
- 结构得分(0.3):必须有深度内容,拒绝流水账
"""
score = 0.0
if min_length <= len(content) <= max_length:
score += 0.3
if any(kw in content for kw in keywords_map[category]):
score += 0.4
if any(word in content for word in ["为什么", "如何", "原因", "教训"]):
score += 0.15
return {"score": round(score, 2), "issues": issues}
Google 在 2025 年底发布的 Titans 架构里有一个"surprise metric"——用惊讶度来决定是否更新记忆。我们的质量门禁是同一理念的工程实现:不惊讶的(重复的、浅显的)不记,只记真正有信息量的。
这个门禁有多严?就在前两天,我们自己试着往系统里写一条记忆,返回了 400 错误。第一反应以为是 bug——认证查了、API 查了、数据库查了——折腾了一圈才发现:门禁在正常工作。那条记忆内容太短,知识密度不够,被拦了。(错误提示被吞掉了没显示出来,这个 bug 倒是真修了,PR #147。)
造了个门禁严到拦自己。大概说明是认真的。
第二关:去重——别把同一件事记两遍
新信息进来,系统会拿它和已有的记忆做语义比对。不是比较文字,是比较意思——用完全不同的话说同一件事,也能识别出来。
相似度 95% 以上?完全重复,跳过不存。85%~95%?有重叠,合并到旧记忆里。低于 85%?全新知识,存入。
这一步解决的问题很实际:AI 员工在不同场景下可能多次遇到同一个教训,如果每次都存一条,记忆库很快就会膨胀成垃圾堆。
第三关:自动关联——让知识连成网
新记忆存入后,系统会自动扫描已有记忆库,找到语义相关的(相似度 ≥ 0.35),建立双向链接。每条记忆最多链接 20 条相关记忆。
这不是摆设。当 AI 想起一条部署教训时,它能顺着链接找到:当时的决策是什么、后来总结的规律是什么、类似情况下别人是怎么处理的。一张自动生长的知识网络,不需要任何人工标注。
而且这张网不是每个 AI 员工各自一个孤岛。我们有 shared 标记——一条记忆如果被标为共享,33 位 AI 员工都能通过跨员工查询检索到。后端工程师踩过的坑,运维工程师部署时能想起来。学术界管这叫 "multi-agent memory",我们在生产环境里跑着。
写入的三步在一个数据库事务里完成——要么全成功,要么全回滚。不会出现"记了一半"的脏状态。用了 PostgreSQL 的咨询锁防止并发写入冲突。这些工程细节不性感,但在生产环境里每一个都是必须的。
召回:五张评分卡
记住了,还得在对的时候想起来。
举个你肯定有过的体验:周一开会要汇报上周的进展,你脑子里先冒出来的不是最重要的事,而是昨天刚做完的那件——因为它最新鲜。但如果你冷静想想,最该提的可能是上周三那个关键决策。
AI 的记忆召回也是这个问题。"语义最相似"和"现在最该想起来"经常不是一回事。
传统做法是纯向量搜索:把你的问题转成数学向量,找数据库里距离最近的几条。这能解决大约六成的场景。剩下四成——该想起来的想不起来,想起来的不是最该要的。
我们用 五张评分卡 综合打分:
# 五因子混合排序
# final_score = 0.15 * keyword (关键词精确匹配)
# + 0.40 * cosine (语义相似度 — 主力)
# + 0.15 * q_value (历史价值 — 用过好不好用)
# + 0.15 * importance (重要性 — 1~5 分)
# + 0.15 * recency (时间衰减 — 越近越高)
score_expr = (
"0.15 * keyword_norm"
" + 0.40 * cosine_similarity"
" + 0.15 * COALESCE(q_value, 0.5)"
" + 0.15 * (COALESCE(importance, 3) / 5.0)"
)
recency = math.exp(-0.01 * days_since_access) # 半衰期约 69 天
final = sql_score + 0.15 * recency
语义相似度是主力(40%),但剩下四张卡同样关键:
- 关键词匹配(15%)—— 精确匹配技术术语。你说"pgvector",系统就找"pgvector",不会因为语义相近把"Redis"也搜出来
- 历史价值(15%)—— 这条记忆以前被用过,好使吗?用户觉得有帮助的,分更高
- 重要性(15%)—— 写入时评估的,关键决策天然比日常发现分高
- 时间衰减(15%)—— 上周的教训比三个月前的更可能跟当前任务相关
我们做过 10 个真实查询的对比测试:五因子混合检索 8/10 的 Top-1 结果直接相关,而纯标签过滤每次返回相同的时间倒序前 5 条,毫无针对性。
四个因子在 SQL 层一趟算完,第五个在 Python 层后处理。整个检索毫秒级。
记忆怎么用:四段式 prompt 注入
检索出来的记忆不是直接贴进对话,而是分成四个语义段注入 AI 的 system prompt:
- 历史经验——与当前任务相关的过往 finding
- 上次教训——最近的 correction,防止重蹈覆辙
- 高分范例——历史上得分最高的任务案例,提供标杆
- 可复用工作模式——从碎片中归纳出的 pattern
四个段用 asyncio.gather 并行加载,总量控制在 800 token 以内。AI 不是收到一堆原始记忆条目,而是收到经过组织的、分类清晰的经验包。
进化:活的记忆
这部分是我们觉得最有意思的,也是和市面上"记忆方案"最根本的区别。
大多数方案是个档案柜:存进去什么样,取出来就什么样。我们的记忆是活的——会根据反馈自己变好,会遗忘,会把零散的碎片归纳成规律。
清华大学 2025 年底的综述论文《Memory in the Age of AI Agents》把 agent 记忆分为 factual(事实)、experiential(经验)、working(工作)三类。我们的分类更细:decision(决策)、finding(发现)、correction(教训)、pattern(模式)、estimate(估算)——五个类别各有不同的质量标准和生命周期,这在生产系统里很重要,因为一条"教训"和一条"发现"的价值衰减曲线完全不同。
强化学习:用了好不好使,记忆自己知道
每条记忆有一个 q_value,可以理解为"好用程度"。初始 0.5,谁也不偏袒。
AI 召回一条记忆去完成任务后,系统会追踪反馈:用户觉得有帮助?q_value 上升。用了但没什么用?q_value 下降 5%。下次同类任务,高 q_value 的记忆优先被想起来。
行为 → 反馈 → 调整权重 → 影响下次行为。这就是强化学习,只不过学习的对象是"哪条记忆好使"。2025 年有两篇相关论文(Mem-α 和 Memory-R1)提出了用 RL 学习记忆构造的理论框架,我们的 Q-value + EWMA 是同一思路在生产环境里的落地。
新记忆的试用期
但这里有个冷启动问题。新来的记忆没被用过,q_value 是默认的 0.5,永远排在那些久经考验的老记忆后面。好知识可能永远没机会出场。
这就像招了个新人,但因为没有业绩记录,永远排不上项目。不公平,也浪费。
我们用 Thompson Sampling 解决——给新记忆一个"试用期":
def _thompson_rescore(rows):
"""召回次数不到 5 的记忆,用 Beta 分布随机采样替代固定分数.
被验证有用的新记忆,采样值偏高;没被验证的,随机波动。
这给了每条新记忆公平的出场机会。
"""
for row in rows:
if row.get("recall_count", 0) < 5:
sampled_q = random.betavariate(
row.get("verified_count", 0) + 1,
max(row.get("recall_count", 0) - row.get("verified_count", 0), 0) + 1
)
score = base_score + 0.15 * sampled_q
被用了 5 次以上的记忆,分数稳定,靠实力排位。不到 5 次的,每次检索时分数随机波动——好的新知识总有机会冒出来。这在统计学里是最优的探索-利用平衡策略,被证明过收敛性。
遗忘曲线:该忘的就忘
人会遗忘,AI 也应该。但不能乱忘。
我们设计了一条三段式遗忘曲线,借鉴了心理学里的艾宾浩斯遗忘曲线:
def decay_stale_memories(mild_days=30, strong_days=90,
mild_factor=0.98, strong_factor=0.95, floor=0.1):
"""SAGE 遗忘曲线:
- 30 天没被想起:轻度衰减,每天 × 0.98
- 90 天没被想起:加速衰减,每天 × 0.95
- 但永远不低于 0.1 — 不允许彻底遗忘
"""
一条记忆半年没被用过,权重降得很低,但不会归零。某天它突然又变相关了?还在那里。
人脑也是这样的——"我突然想起来了"这种体验,前提是那条记忆虽然沉到了底部,但没有消失。
碎片变规律:从 14 条 finding 到 2 条 pattern
时间久了,记忆库里会积累大量零散的发现。"项目 A 部署时踩了坑 X""项目 B 也遇到 X""项目 C 用了 Y 方法解决了 X"——三条碎片,其实在说同一件事。
整合模块会自动找到这些同主题的碎片,聚类归组,然后用 LLM 合成一条通用模式:
def find_clusters(employee, store, min_cluster_size=3):
"""关键词重叠度 >= 0.4 的归为同一 cluster(Union-Find).
只处理 >= 3 条的 cluster — 太少不足以归纳。
"""
for i, j in candidate_pairs:
overlap = keyword_overlap(findings[i].keywords, findings[j].keywords)
if overlap >= 0.4:
union(i, j)
我们实际跑过一次:墨言的记忆库里 14 条零散的 finding 被归纳成了 2 条可复用的 pattern。原始碎片没删,标记为"已被取代",链接到新的综合记忆。知识不是丢了,是升了级。
完整的进化链条:写入 → 质量筛选 → 去重关联 → 用了反馈调权 → 时间衰减清理 → 碎片聚合升级。全自动。
安全:我们自己的教训
记忆系统存的是企业最敏感的知识资产——决策过程、技术细节、内部讨论。安全不是功能列表上的一项,是地基。
多租户硬隔离。每一层操作都带 tenant_id,从数据库写入到缓存 key 到衰减任务到知识整合。租户 A 的记忆,租户 B 连搜都搜不到。
四级信息分级。参照 ISO 27001,每条记忆标 public / internal / restricted / confidential。查询时可以设天花板,比如"这个场景最高只看 internal 级别"。
说个我们自己的教训。今年 3 月初,信息分级功能开发完毕,测试跑过了,准备对外开放。上线前做了一轮影子验证——在后台用真实查询跑一遍新逻辑,对比结果。
冷汗级的发现:分级过滤完全没生效。
原因荒唐但真实:过滤代码写在新版存储引擎里,但生产环境跑的还是旧版。等于安全功能写了,但根本没接上线路。如果跳过影子验证直接开放,外部用户能看到所有 internal 级别的内部记忆。
从此多了一条铁律:涉及外部权限的改动,一律 关闭 → 修改 → 验证 → 再开放。不做影子验证,不开外部访问。
对比一下 ChatGPT 的现状:2025 年安全研究者 Johann Rehberger 发现,ChatGPT 的自动记忆可以被 prompt injection 植入虚假信息,而用户既看不到也删不了这些被污染的条目。我们的方案里,每条记忆都有完整审计链——谁创建的、什么时候改的、被谁取代了——superseded_by 字段让知识演进全程可追溯。质量门禁在写入端拦截低质量内容,审计链在读取端提供可追溯性。两端都堵。
其他安全机制:
- 职能域控制——后端工程师的调试经验不会出现在前端工程师的上下文里,除非明确标为公开
- 时间有效性——每条记忆可以设
valid_from和valid_until,过期的自动不参与检索。"Q1 定价策略"不会在 Q2 误导决策
回到墨言
墨言脑补任务那件事之后,我们上了质量门禁。现在她的每条记忆都要过三道关。前两天她试着记一条太短的笔记,被系统拦了。
她现在有 466 条经过验证的记忆。其中 14 条零散发现已经被自动归纳成了 2 条可复用的工作模式。她的记忆库会遗忘不重要的事,会把碎片知识升级成规律,会根据"上次这条记忆好不好使"来调整下次要不要想起它。这些记忆不是只有她能用——标记为共享的模式,33 位同事都能检索到。
坦白讲,做记忆系统最难的部分不是技术。向量检索、强化学习、衰减曲线,这些都有论文可以参考。真正难的是克制——决定什么不记、什么时候该忘、谁能看到什么。Letta 选择让 agent 自己管理记忆,我们选择了外部管线——因为墨言脑补任务的教训告诉我们,agent 的判断力还不足以完全信任。这些取舍背后是产品观,不是算法。
我们还在迭代。信息分级差点上线没生效的事,让我们养成了影子验证的习惯。质量门禁拦自己的事,让我们确认了方向。
一个记忆系统要值得信赖,首先得对自己够严格。