详细说一下写入与召回过程
回复 群友 8525 先给结论:Hy-Memory 2.0 的核心不是简单的向量切块存取,而是把读写拆成了场景路由(Chat / Working / Coding 三条管线)和双系统演进(快写 + 慢整理)。写入靠 3B 激活的专用小模型做结构化抽取与冲突消解,代码改动则完全绕开大模型、直接用零 LLM 成本挂接真实 Git Diff;召回则按场景走多通道检索 + 条件过滤 + Diff 装饰器挂载。 具体拆解一下它的写入和召回全链路: 一、写入过程(Write Path):先路由,再按场景分层落库 当你调用 client.add 传入一段对话或 Agent 执行轨迹时,写入分四步走: 1. 入口场景路由(Scene Router) 如果没手动指定 scene,路由器先看消息里有没有工具调用(tool_calls 或 role=tool): 没有工具调用的纯对话,0 次 LLM 调用直接进 Chat 管线。 包含工具调用的轨迹,调一次模型分类进 Chat、Working 或 Coding 管线。 2. 三条管线各自的抽取与更新机制 第一条:Chat 管线(L0 到 L7 八层认知架构 + 双系统) System 1(快路径,每次写入触发):先把原始对话追加到 L1(RAW),然后由写入模型(如 Hy-Memory-30B-A3B)抽取出 L0 基本信息、L2 原子事实(不可变、带版本)、L3 会话摘要和 L7 远期意图(带过期时间,过期自动降级为普通事实)。在这个阶段会同步做冲突消解(Reconcile):比如用户以前说只看美股,现在说改盯有色和半导体,旧事实不会直接物理覆写丢掉,而是归档标记为被取代、保留演化链,新事实成为当前有效状态。 System 2(慢路径,在 ultra 模式下调用 evolve 触发):后台异步扫描跨会话的事实,归纳出 L6 心智模型(Schema,抽象叙事模板),写入图数据库(默认 Kuzu 或 Neo4j),把零散事实连成跨领域的长期画像。 第二条:Working 管线(面向生产力任务的双层结构) 一段带工具调用的会话进去,会同时产出两层且双向绑定(通过 ID 互链): 事实层(WorkingFact,无门槛必存):每个会话固定生成 1 条,记录这次干了什么、用了什么方法、涉及哪些文件、结果如何。如果同一个任务跨会话推进,新 Fact 会把旧 Fact 串成一条任务进度链(fact_chain_summary)。 经验层(Experiences,过价值门槛才存):每个会话提取 0 到 N 条可复用套路,结构里强制包含 task、search_keys、solution、boundary_envs(适用边界与环境前提)和 confidence(置信度)。 第三条:Coding 管线(双层结构 + 零 LLM 的代码版本演化链) 复用 Working 的双层结构,但有两个专门针对 ca 的硬改造: 一是抽取规范变了:严禁往 Fact 里大段贴代码(极其浪费 token 且容易过期),只准记录精确坐标(文件路径 / 函数名 / 分支名)和决策原因。 二是旁路挂载版本演化链(Version-Evolution Diff Chain):这是最精妙的一步。大模型做摘要一定会漏掉后来被 revert 或覆盖掉的中间代码版本,而这些中间态在当前 Git HEAD 里也读不到。所以 Coding 管线在写入时,直接从本地 Git diff 或工具调用里的路径与前后替换内容(old/new)中,按「单分支 + 单文件 + 单函数代码块」的粒度,把每次修改的真实 Diff 和用户当时的原话直接存进本地 SQLite(coding_memory_cv.db),全程 0 次 LLM 调用。 二、召回过程(Read / Search Path):多路召回 + 前置条件校验 + 装饰器挂载 调用 client.search 时,同样支持先走检索路由:search_mode 设为 default 时直接查 Chat(0 LLM 开销);设为 agentic 时,先做场景分类、Query 改写和时间范围解析。 1. Chat 场景的三通道召回 检索结合向量库(默认 ChromaDB,可选 Qdrant/FAISS)、图数据库(Kuzu/Neo4j 多跳关联)和本地 Cross-Encoder 重排(Rerank),最终按三个通道返回给 Agent: profile 通道:用户的稳定画像与基础偏好。 normal 通道:与当前问题语义及图谱多跳最相关的事件脉络与最新有效事实(已剔除被取代的旧冲突信息)。 proactive 通道:L7 层未过期的远期意图或待办事项,让 Agent 能在对话里主动提起。 2. Working 与 Coding 场景的分层召回与「装饰器」组装 在 ca 或办公场景下,召回返回三个核心块(facts、experiences、chain_block): 第一步,向量层检索 Facts 与 Experiences:根据当前任务描述,先召回相关的历史工作事实和候选经验。 第二步,经验适用性判断:拿到候选 Experience 后,先核对它的 boundary_envs(环境与前置条件)和当前工作区是否匹配,只在条件满足时才采用,防止把 A 项目的老经验硬套到 B 项目上造成记忆污染。 第三步,Diff 链装饰器挂载(Coding 专属):注意它的版本演化链本身不做检索器(Retriever),而是做装饰器(Decorator)。当向量层决定了召回哪几条 Coding Fact 后,系统顺着 Fact 里记下的文件与函数坐标,去本地 SQLite 链里把那块代码历史上改过几次、每次用户怎么说的、真实 Diff 是什么,原封不动打包成 chain_block 挂在 Fact 下面一起返回。这样 ca 既看到了宏观的决策摘要,又拿到了精确到行的历史试错 Diff。