行业痛点
用户不会说「你的召回率低」,
他们只说「你忘了我说过的话」。
「我上次说的那件事呢?」
记忆被清理时不记原因。不是没记 —— 是记了,又在某一次压缩里悄悄没了。你查不出它去哪了,用户也不接受「我忘了」这个回答。
「它对我的印象莫名其妙变了」
画像是覆盖写的:今天抽出的结论盖掉昨天的。三月你说预算二十万,六月改口五十万 —— 覆盖之后,「你当初是怎么想的」这个问题永远答不出来了。
「你为什么会想起这个?」
检索是黑箱。它端上来一条毫不相干的记忆,你既问不出为什么被选中,也没法告诉它这条不对。下一轮它还会端上来。
「我早就不在那家公司了」
只有一个时间戳,分不清「事情何时发生」与「我们何时知道」。于是 2023 年的旧雇主和今年的新雇主,一起被塞进同一段上下文。
模型会换,供应商会换,监管不会松。
「能被审计的记忆,才敢放进生产。」
同一个问题,接与不接,答出来不是一件事
「下周我要和老周谈合作,这个项目风险不小,我该怎么谈?」
给出网上通用的谈判技巧:BATNA、先报价还是后报价……它不知道老周是谁,不知道你在这件事上踩过什么坑,也不知道你做事的原则。
老周性子急、喜欢口头敲定,你们上次就吃过口头约定的亏。按你一贯「先划风险边界、不做口头承诺」的原则,建议先肯定合作方向,再把风险与权责落到书面。语气缓和,给自己留缓冲。
- 「上次吃过口头约定的亏」→ 回到 2025-11-02 的那段原始对话
- 「先划风险边界」→ 画像槽位 决策偏好/谨慎 · 可下钻到支撑它的每条事实
差别不在模型,在于它手上有没有你的账本——而且每一条都查得到出处。
机制
三条机制,一个底座
账本怎么记、召回怎么解释、记忆归谁 —— 这三条决定了你能不能审计它。底座决定的是另一件事:出故障的时候,你手上还剩下什么。
backend/src/memcore/models.py:307-311(valid_from / valid_to / ingested_at / expired_at + invalidated_by_message_id)
红字冲销:三时间轴让「改」变成「增」
一条事实同时挂在两条轴上 —— 现实轴说「这件事什么时候是真的」,系统轴说「我们何时知道、何时作废」。两轴分离,才谈得上不静默丢失、不静默篡改。
| 记录 | 事实 | valid_from | valid_to | ingested_at | expired_at |
|---|---|---|---|---|---|
| #1041 | 在 A 公司任职 | 2023-03-06 | — | 2023-06-12 | — |
| #1041 | 在 A 公司任职 | 2023-03-06 | 2024-01-20 | 2023-06-12 | 2024-02-03 |
| #2288 | 在 B 公司任职 | 2024-01-21 | — | 2024-02-03 | — |
#1041 没有被删除,也没有被改写 —— 它被写上 expired_at 与 invalidated_by=#2288,原行留在账上。
这两个问题在覆盖写的系统里只有一个答案。
每条记忆都能说明「我为什么想起你」
检索走六路并行(向量 / 关键词 / 图 / 时间 / 空间 / 新近),RRF 融合。融合过程对调用方是透明的 —— 不是给一个分数,是给出每条路的名次与各自的贡献。
{
"statement": "Melanie plays clarinet.",
"why": {
"matched_paths": { "vector": {"rank": 2}, "keyword": {"rank": 2}, "graph": {"rank": 2} },
"rrf_contribution": { "vector": 0.016129, "keyword": 0.016129, "graph": 0.012903 },
"validity": { "state": "current", "valid_from": "2023-08-28", "valid_to": null }
},
"confidence": 1.0,
"confirmed_times": 1
}三条内容路都命中、名次一致 → 高置信;若只有新近路命中,这条记忆根本不会被返回 —— 先验路不得独立引入证据。
你的记忆是你的
每条淡出都带原因
被清理的记忆都写下 forget_reason 并可一键恢复,清理动作进审计账本。默认只提候选、不自动执行。
删除闭合到派生物
删一个会话,连带其派生事实与向量索引一并闭合。没有溯源链,删除只能删表面,派生记忆会变成幽灵。
一键导出
画像(Markdown)与事实账本(开放格式)完整导出,含溯源字段。不做数据绑架。
唯一真相源,加一层可以随时丢掉的索引
Postgres 是唯一真相源,向量库是影子索引 —— 索引丢了能重建,账本丢了就没了。这个边界决定了故障时你还剩下什么。
| 组件 | 职责 | 可重建 |
|---|---|---|
| PostgreSQL | 事实账本 · 三时间轴 · 审计日志 | 否 · 唯一真相源 |
| 向量索引 | 语义检索 | 是 · 可重建 |
| Redis | 快层 / 队列 / 分布式锁 | 是 · 可重建 |
| 对象存储 | 画像与日记 / 导出包 | 否 · DB 有索引副本 |
接入
两条路:一行不改,或者五个动词
现有应用走 OpenAI 兼容代理,业务代码一行不动就有了长期记忆。要用到溯源、遗忘与审计,就走 SDK——四条能力各自对应一个方法,不是埋在文档角落里的可选参数。
from openai import OpenAI
client = OpenAI(
base_url="https://api.reglos.ai/v1", # ← 只改这一行
api_key="mk_live_…",
)
resp = client.chat.completions.create(
model="gpt-4o-mini",
user="alice", # ← 记忆归属到谁
messages=[{"role": "user", "content": "我最喜欢什么乐器?"}],
)from memcore import Memcore
user = Memcore(api_key="mk_live_…").subject("alice")
user.remember("我住在上海,周末喜欢爬山。") # 写入
hits = user.recall("他住在哪里", explain=True) # 检索 + 为什么是它
user.explain(hits.facts[0].id) # 溯源到原始对话
user.forget(hits.facts[0].id, reason="抽错了") # 作废但留痕
user.audit(limit=5) # 审计账本归属不明确时返回 400 并说明该设什么——不会默默塞进一个共用的匿名桶。那样的记忆对谁都没用,而且是隐私事故的温床。
产品形态
三种用法,一个内核,两种部署
上面换的是形态,下面换的是部署位置。中间那一层——账本、召回、溯源、审计——三种用法共用同一套,不存在「App 版记忆」和「API 版记忆」两套实现。
Reglos App
伴侣 / 助手。画像随对话演化,每日回顾,到期承诺主动提醒。
Memory API / SDK
写入、检索、溯源、导出、级联删除全开放。Python / TypeScript / MCP。
语音可穿戴
时间与场景锚定,随身、长期、跨设备共用同一个大脑。
Reglos Cloud
托管 API,分钟级接入,多租户隔离与行级安全已在库侧落地。
私有化部署
VPC 内部署,数据留在你自己的网络里。模型可换成你自己的 key(BYOK);向量层已在五家引擎上跑通,可按你现有的库选。
我们为什么做这四条
「静默」是记忆系统的头号敌人
下面六件事都在我们自己的系统里真实发生过,也都被修掉了。它们的共同点不是「出错」——是出错了却什么都不说。四条能力不是理念,是我们被这六件事逼出来的。
- 静默少召回01
过滤发生在检索之后
pgvector 的 hnsw 索引只建在向量列上、不含租户字段,于是先取近邻再过滤租户 —— 少召回多少条,没有任何地方会告诉你。
- 静默消失02
掉 12 个点,零告警
一次多租户重构改了向量租户名的算法,重构前写入的向量全部变成孤儿。而向量库开着自动建租户,查一个不存在的租户不报错、自动建个空的返回空结果。准确率 65.3% → 53.3%。
- 静默换题集03
整组 191 题被丢掉,均分照算
第三方评测框架里,判官拿到一次空响应就抛异常,一整组 191 题被丢弃,而均分照样在剩下的 1349 题上算出来写进结果文件,只在末尾打一行「1 groups had errors」。
- 静默损坏04
名叫 upsert,其实只会 insert
遇到已存在的 id 抛 422,而调用点普遍包在 try/except 里(影子索引不该阻塞真相写入)。于是所有「更新已有向量」的写入长期失败,向量与事实文本慢慢对不上。
- 静默污染05
「大家」「国家」「专家」都含「家」
单字中文别名做子串匹配,把这些词全判成了「家庭场景」。检索结果一直是脏的,而没有任何一条日志是红色的。
- 静默漏计06
静默的计量缺失 = 静默的收入缺失
计量失败不该把我们的 Redis 抖动变成客户的 5xx,所以它不阻断请求 —— 但必须记日志。不记,账单就少了一笔而没人知道。
这六件事没有一件会报错。可解释、可审计、可控制、可证明 —— 四条能力要解决的就是这个:让沉默的东西开口。
场景
一套内核,落到不同的行业里
记忆的形态各行不同,但「查得到、改得动、删得干净」这三条要求是共同的 —— 越是受监管的行业,越先问这三条。
AI 伴侣与陪伴硬件
1 / 5跨会话记住偏好与承诺,「它记得我」的时刻是设计出来的。承诺单独进任务表并带到期时间,到点落进 /v1/reminders 的待办队列,由你的产品决定怎么告诉用户。
证据
每个数字都带口径
下面的数字来自不同的尺子。混在一起报是耍流氓,所以我们分开报,并且把尺子一并写出来。
我们自己把对手也跑了一遍
变量全部对齐,只换记忆系统| 记忆系统 | LoCoMo 准确率 | 我们领先 |
|---|---|---|
| Reglos | 59.8% | — |
| MemOS | 51.8% | +8.0 pt |
| mem0 开源版 | 47.2% | +12.6 pt |
口径 · 业界口径(排除 cat5,与 MemOS / OpenViking / memobase / supermemory / mem0 五家一致)· 判官 gemini-2.5-pro · 抽取与答题模型 gpt-4o-mini 同一中转 · 除记忆系统外变量全部对齐
判官换人就是换尺子。同一批数据在四个判官下的实测区间是 55.3%–63.5%,所以引用任何绝对值都必须注明判官型号——上表是 gemini-2.5-pro。
领先幅度在含 cat5 与排除 cat5 两种口径下都成立(+7.7 与 +8.0)。我们采用了对自己更不利的那次口径更正,不是挑对自己有利的算法。
外部基准,我们没针对它调过参
LongMemEval-S · 数据集 MIT 许可这两项合计 211 题、占全量 42%,恰好是三时间轴与冲突消解的设计目标。在一个我们从未调过参的外部基准上,它们同样是最强的两项。
第三方 harness,判官与 prompt 不由我们定
OmniMemEval · 与 15 家记忆产品同框架口径 · OmniMemEval · LoCoMo 全量 1540 题 · 判官与答题 prompt 由第三方固定 · 单轮(2026-09-02)
2,321token/题注入上下文的平均体量口径 · OmniMemEval · LoCoMo 全量 1540 题 · 总计 3,574,112 token · 该列受判官影响小
没有口径的准确率,不是一个数字。
我们实测过两家开源实现,分数与其自报值相差 30 个百分点以上 —— 差的不是能力,是口径。所以本页每个数字都写明口径;拿不到口径的对比,我们不做。
判官失灵 → 整轮作废
判分模型一旦失效,所有需 LLM 判分的类别齐刷刷零分,而跑批「正常结束」并写出结果文件 —— 那份文件看起来完全正常,却是假的。现在的规则:失灵率超 2%,不保存结果。
上下文被打空 → 整轮作废
并发过高时检索超时、上下文变空,答题模型正确地回答「无相关信息」,却被判为答错 —— 分数系统性偏低约 23 个点而毫无报错。现在只要有一题拿到空上下文,整轮作废。
这两条护栏不是纸面纪律:它们在我们自己的跑批里真实触发过,并且推翻过我们已经写下的结论 —— 之后才被加进代码。
还没做好的地方
时间维度是四类里最低的一类,也是与同行差距最大的一类 —— 而三时间轴恰恰是我们自己主张的差异化能力。这条我们摆在明面上,下一轮优先做时间维度的失败样本归类。
不靠客户 logo,靠能复现的东西
一家数字分身产品团队
对方给出六层架构与 13 个认知模型,其中被他们自己标注为「项目核心壁垒」的那两层 —— 仿生终身记忆与存储安全 —— 我们能直接承接。外围的端、网关、调度是常规工程,不是壁垒,但也确实要从头做。
对照数据的脚本进了仓库
向量库选型的每一张表都能重跑。最初这批脚本写在 /tmp、跑完就该没了 —— 那样「实测」会退化成「一堆数字」。
客户具名需对方授权,暂不列出。这一段里的每一项都不依赖任何客户关系,可独立核验。
定价
按用量计费,私有化按部署谈
记忆是长期资产,计费不该逼你删数据。写入与检索分开计价,存量不因为「放久了」而涨价。
价格以商务确认为准。企业方案可按部署范围、设备规模、年度用量与 QPS 需求定制。