跳到主要内容

第 4 章:深入实现、巧思、边界与代码地图

本章讲什么: 前三章讲清了原理;这一章补齐"读源码要知道的落点"——数据怎么存、向量后端有哪几种、对外几种接口、哪些设计值得抄、它会在哪崩,最后给一张符号级跳转表。


1. 存储结构

核心是几张 SQLite 表(schema 见 migrations/001_initial.sql,但注意第 3 章提到的列名不一致):

装什么关键列
memories记忆主体idcontentprimary_sectorsaliencedecay_lambdasimhashmean_vecsegmentuser_id
vectors每记忆每脑区一个向量(id, sector) 主键、v(BLOB)、dim
waypoints联想边(src_id, dst_id)weight
users用户画像摘要user_idsummary
temporal_facts时间事实subjectpredicateobjectvalid_fromvalid_toconfidence
temporal_edges事实间关系边source_idtarget_idrelation_typeweight
  • 向量编码: struct.pack("{n}f", *vec) 存成紧凑 float32 BLOB(vector_store.py:40),读回用 struct.unpack
  • 分段(segment): 记忆按 env.seg_size 分批轮转(hsg.py:419-426),后台衰减按 segment 遍历,便于分片处理。

2. 向量后端:三选一

get_vector_store(vector_store.py:92)按环境变量 OPENMEMORY_VECTOR_STORE 选后端:

后端实现特点
sqlite(默认)SQLiteVectorStore(vector_store.py:35)零依赖、暴力全扫余弦
postgrescore/vector/postgres.py多用户、可扩展
valkey/rediscore/vector/valkey.py内存向量检索

三者都实现同一 VectorStore 抽象基类(vector_store.py:19),上层 hsg.py 只依赖接口。


3. 对外接口:一个门面、四种壳

所有接口最终都收敛到 Memory 门面(main.py)与 hsg.py:

  • Python SDK: from openmemory.client import Memory
  • Node SDK / CLI / HTTP 服务: packages/openmemory-js,路由汇总在 server/routes/index.ts(memory/temporal/sources/ide/dashboard 等)。
  • MCP server: ai/mcp.py(run_mcp_server)暴露 openmemory_query/store/get/list/delete 五个工具,store 支持 contextual(HSG)/factual(TKG)/both
  • VS Code 扩展: apps/vscode-extension,把 IDE 事件写进记忆。

4. 巧妙之处(可借鉴的技术)

  1. 自适应联想扩散。 向量命中够自信就不扩散,不自信才沿图 BFS 拉更多候选,且扩张量随不自信程度增大(hsg.py:560-568)。省算力又提召回。
  2. 冷记忆分级降级而非删除。 先压缩维度、再降级成 32 维指纹,查到再重嵌入还原(decay.py:157-176on_query_hit)。用精度换空间,且可逆。
  3. 召回即强化的闭环。 查询会回写 salience 并联想扩散(hsg.py:638-656)——记忆系统"越用越顺手",这是它区别于只读 RAG 的关键。
  4. 分脑区差异化遗忘。 情绪快忘、反思慢忘(SECTOR_CONFIGS),把"人类记忆的时间性"编码进 lambda。
  5. simhash + 汉明距离去重。 换句式的重复内容不再生成新记忆,只强化旧记忆(hsg.py:390-403)。
  6. 无 API 也能跑。 synthetic 嵌入用哈希 + n-gram + 位置编码本地造向量(ai/synthetic.py),开箱即用、离线友好。

5. 边界与局限(诚实清单)

  • README 首行明说"项目正在重写,预期 breaking changes 和 bug"——本文所述以当前 commit 为准。
  • 默认嵌入质量有限。 synthetic 是词面+n-gram 的伪语义,真语义相似度需配真实模型。
  • 检索无 ANN 索引。 SQLite 后端暴力全扫,规模上去会慢(vector_store.py:67)。
  • 反思聚类用词面 Jaccard(reflect.py:20),与检索用的向量语义是两套逻辑,可能聚不到"意思相近但用词不同"的记忆。
  • 代码存在冗余与疑似 bug: hsg.py 重复查询/赋值;compute_simhash 有死代码段;decay.py:206-207 salience 增量被覆盖;MCP factual 查询参数名与 query.py 签名不符(第 3 章 §6);迁移 SQL 列名(obj/relation)与代码(object/relation_type)不一致。
  • 无实体归一化。 TKG 主谓宾裸字符串精确匹配,大小写/别名不合并。
  • 多用户隔离靠 user_id 过滤,非强隔离——同库共享,靠查询条件区分。

6. 横向对比(memory-context 货架内)

OpenMemory 在"给 agent 的长期记忆"这一格的取舍:

维度OpenMemory 的选择
记忆模型五脑区分类 + 复合打分,而非单一向量相似度
时间性salience 衰减/强化 + 独立的时间事实图谱(双时态)
关联显式 waypoint 图 + 联想扩散,而非纯 kNN
部署自托管、本地优先(SQLite),对标 Mem0/Zep/Supermemory 的云 API(且自带从它们迁移的工具)
依赖可零外部依赖跑(synthetic 嵌入 + SQLite)

与纯 RAG 记忆库相比,它的差异化就一句:记忆有状态、会遗忘、会被想起、会互相联想。代价是逻辑更重、调参面更大、当前实现还在重写期。


7. 代码地图(导航索引)

以下符号名相对行号更抗漂移,agent 可直接 grep 定位(路径相对 packages/openmemory-py/src/openmemory/):

主题文件符号
对外门面 add/searchmain.pyMemoryMemory.addMemory.search
大文档拆分 root-childops/ingest.pyingest_documentsplit_textmk_rootmk_childlink
多格式抽取ops/extract.pyextract_textextract_pdfextract_url
写入核心:去重/分区/嵌入/建链memory/hsg.pyadd_hsg_memory
脑区分类memory/hsg.pycore/constants.pyclassify_contentSECTOR_CONFIGS
simhash 去重memory/hsg.pycompute_simhashhamming_dist
召回核心memory/hsg.pyhsg_querycompute_hybrid_scoreboosted_sim
联想扩散/建边memory/hsg.pyexpand_via_waypointscreate_single_waypointreinforce_waypointsprune_weak_waypoints
复合分权重/超参memory/hsg.pySCORING_WEIGHTSHYBRID_PARAMSSECTOR_RELATIONSHIPS
衰减公式memory/hsg.pycalc_decay
后台衰减 + 冷记忆降级memory/decay.pyapply_decaypick_tiercompress_vectorfingerprint_memon_query_hit
记忆动力学(共振/强化/扩散)ops/dynamics.pycalculateCrossSectorResonanceScoreapplyRetrievalTraceReinforcementToMemorypropagateAssociativeReinforcementToLinkedNodes
反思聚类memory/reflect.pyrun_reflectionclustersim_txt
嵌入分发memory/embed.pyai/synthetic.pyembed_multi_sectoremb_dispatchSyntheticAdapter._gen_syn_emb
向量存储/检索core/vector_store.pySQLiteVectorStoreget_vector_store
时间事实写入/自动关闭temporal_graph/store.pyinsert_factbatch_insert_factsapply_confidence_decay
时间事实查询temporal_graph/query.pyquery_facts_at_timeget_current_factfind_conflicting_facts
时间线/变化分析temporal_graph/timeline.pyget_subject_timelinecompare_time_pointsget_volatile_facts
分词/规范化/同义词utils/text.pycanonical_tokens_from_textcanonicalize_tokensynonyms_for
MCP 工具ai/mcp.pyrun_mcp_server
Node 等价实现入口../openmemory-js/src/core/memory.tsserver/routes/index.tsroutes