ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Hindsight Retain 记忆写入管线深度解析:从原始内容到结构化记忆的完整流程

2026/9/14 12:11:48 拓冰建站 浏览量
Hindsight Retain 记忆写入管线深度解析:从原始内容到结构化记忆的完整流程 Hindsight Retain 记忆写入管线深度解析:从原始内容到结构化记忆的完整流程【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight本文围绕 Hindsight 的retain()能力展开,完整覆盖其核心机制:富事实抽取(不止说了什么,还包括为什么、意味着什么)、experience/world双事实分类、实体识别与消歧、四类知识图谱连接、双时间维度建模、标签可见性控制、retain mission 抽取引导,以及 Memory Defense 安全拦截。读完之后,你将掌握如何配置 retain 以获得高质量的记忆库,并理解 retain 管线源码 中各阶段的实现原理与可验证依据。retain 做了什么:整体流程当调用retain()时,Hindsight 将对话与文档转化为结构化、可检索的记忆,同时保留语义与上下文。官方文档给出的核心流程是:即:原始内容 → 抽取事实 → 识别实体 → 建立连接 → 写入记忆库。需要特别注意的一点是:内容本身从不以原文形式存储——被存储的是 LLM 从内容中抽取出的结构化事实。这一设计在 Retain API 参考 中有明确说明:what gets stored are the structured facts the LLM extracts from it。从源码结构看,这条管线由 orchestrator.py 统一编排,各阶段职责分离:fact_extraction.py 负责事实/实体/时间抽取,entity_processing.py 负责实体处理,link_creation.py 与 link_utils.py 负责图谱连接,entity_labels.py 负责受控标签词汇表。富事实抽取:捕获为什么与意味着什么Hindsight 不仅存储说了什么,还捕获why(为什么)、how(如何)、what it means(意味着什么)。以这条输入为例:Alice joined Google last spring and was thrilled about the research opportunities。Hindsight 会抽取三层信息:核心事实:Alice 加入了 Google这件事发生在去年春天情绪与含义:她非常兴奋这代表一个重要机会推理链:她选择它是为了研究机会这种富抽取意味着,日后你可以问 Why did Alice join Google?,得到的将是有意义的回答,而不仅仅是 she joined Google。保留完整上下文传统系统会把信息切碎:Bob suggested Summer VibesAlice wanted something uniqueThey chose Beach BeatsHindsight 则保留完整叙事:Alice and Bob discussed naming their summer party playlist. Bob suggested Summer Vibes because its catchy, but Alice wanted something unique. They ultimately decided on Beach Beats for its playful tone.因此搜索结果包含的是完整上下文,而非彼此割裂的碎片。从实现上看,抽取结果中的context与metadata字段会被直接注入 LLM 抽取提示词中(见 Retain API 文档),因此提供一致的 context 标签是提升记忆质量最高杠杆率的手段之一。此外,fact_extraction.py中还有_infer_temporal_date()这类兜底逻辑:当 LLM 未给出occurred_start时,会用正则将 last night、yesterday、last week 等相对时间表达式按固定天数偏移锚定到事件时间戳上,保证时间维度不因模型遗漏而丢失。两类事实:experience 与 world每条事实都会按它捕获的是谁的视角进行分类——是记忆库所属的 agent,还是外部世界:类型捕获内容示例experience记忆库自身 agent 的行动、观察或交互——第一人称历史I recommended Python to Aliceworld关于其他人、地点、事物、事件的事实Alice works at Google这个划分由谁在说话决定,而不是由语法决定。第一人称陈述只有在说话者就是该库的 agent 时才是experience;同样的话如果是别人说的,则是关于那个人的world事实:Agent 自己的日志——I patched the auth bug →experience(agent 做的)用户对 agent 说——I bought a Tesla →world(关于用户的事实,不是关于 agent 的)源码印证了这套分类:fact_extraction.py 中抽取模型的输出 schema 直接声明了fact_type: Literal[world, experience],并配有明确的判定规则——提示词要求将用户偏好、规则、更正、约束等一律归为world(即使它们是在 agent 交互中陈述的),仅当动作/经验是 agent 实际执行时才归为assistant(内部映射为experience)。从源码结构看,解析侧还有降级路径:fact_type字段异常时会回退到fact_kind判断,最终默认为world,保证分类字段始终有确定取值。两个手段能确保分类正确:为 bank 设置人类可读的name(agent 的名字)。它标识谁是 agent。若未设置则默认取bank_id;而像my-agent::channel-456::user-789这样的路由型bank_id并非可用的说话人名称,所以务必给 bank 一个真实名字。在每条 item 的context中描述说话人,尤其在保留转录或第三方内容时。例如聊天日志中写明Customer Maria is speaking,她的第一人称陈述就会被存为关于 Maria 的world事实,而不是被误认为 agent 自己的经历。当context与 bank name 冲突时,context优先。注:观察(observations)会在retain()操作完成后在后台自动整合。该整合流程从新事实中归纳模式并汇入记忆库的知识库。实体识别:自动追踪重要的人物、组织与概念Hindsight 自动识别并追踪实体——重要的人物、组织与概念:人物:Alice、Dr. Smith、Bob Chen组织:Google、MIT、OpenAI地点:Paris、Central Park、California产品与概念:Python、TensorFlow、machine learning实体消解(Entity Resolution)同一实体以不同方式被提及时,会通过模糊名称匹配统一,并辅以共现与时序邻近性强化:Alice Alice Chen Alice C. → 同一个人因为消解以名称相似度为锚点,相近变体会自动合并。而彼此不像的名称(比如昵称与一个不相关的正式名字)不会仅凭名字被统一,尽管共享的共现实体仍可以把它们关联起来。为什么重要:你可以问 What do I know about Alice?,然后得到全部信息,即使她在某些对话中被叫作 Alice Chen。上下文感知消歧如果 Alice 多次与 Google 和 Stanford 一起出现,那么新出现的、同样提及这些实体的 Alice 很可能就是同一个人。Hindsight 利用共现模式来消歧常见名字。实体标签(Entity Labels)你可以定义一套key:value受控分类词汇表(例如pedagogy:scaffolding、engagement:active),在 retain 时抽取并作为实体存储。由于标签本身就是实体,它们会自动在知识图谱中串联相关记忆,同时提升语义检索与关键词检索的效果。标签还可以选择性地写入 memory unit 的 tags,从而在 recall 与 reflect 阶段支持标准标签过滤。源码中,entity_labels.py 定义了这套词汇表的完整模型:LabelGroup支持value、multi-values、text、multi-text、map五种类型,其中map类型支持嵌套递归(MapField),tag标志控制是否同步写入 memory unit 标签。fact_extraction.py 中的_extract_map_entities()负责把嵌套 map 实体展开为key:field:value形式的实体字符串。完整配置见 memory-banks 的 entity_labels 章节。构建连接:四类知识图谱边记忆不是孤立的——Hindsight 构建一个包含四类连接的知识图谱:实体连接所有提及同一实体的事实被串联在一起。支持:Tell me everything about Alice → 检索全部与 Alice 相关的事实。基于时间的连接时间上接近的事实被连接,日期越近,连接权重越强。支持:What else happened around then? → 找到上下文相关的事件。基于语义的连接语义相似的事实被连接,即使措辞不同。支持:Tell me about similar topics → 找到主题相关的信息。因果连接因果关系被显式追踪。支持:Why did this happen? → 追踪推理链。示例:Alice felt burned out ← 由 ← She worked 80-hour weeks 导致。源码层面,link_utils.py 生成了带权重的连接元组,时间边为对称的(temporal, weight)双向边,语义边则携带相似度得分(semantic, similarity)。因果边有独立的规范类型定义:causal_links.py 中CANONICAL_CAUSAL_LINK_TYPE caused_by,默认权重 1.0,并保留causes/enables/prevents作为历史类型——新增的 retain 输出只写规范类型,旧库的历史边在迁移导入时保持原语义。时间理解:两个时间维度Hindsight 追踪两个时间维度:事件何时发生对于事件(会议、旅行、里程碑),Hindsight 记录其发生时间:Alice got married in June 2024 → 发生于 2024 年 6 月对于一般事实(偏好、特征),则没有具体发生时间:Alice prefers Python → 持续性的偏好你何时得知它Hindsight 同时追踪你告知它每条事实的时间。为什么要两者都有?设想在 2025 年 1 月,有人告诉你 Alice got married in June 2024:历史查询可用:What did Alice do in 2024? → 找到这场婚礼新近性排序可用:近期提及在搜索中获得优先时间推理可用:What happened before her marriage? → 找到更早的事件没有这个区分,旧信息要么无法按日期检索,要么会被视为无关。这个机制由 retain 的timestamp参数落地(见 Retain API):时间戳会被注入 LLM 抽取提示词,让模型用它作为锚点解析 last Monday 这类相对时间引用;传unset时提示词显示Event Date: Unknown,模型会对每条事实的when字段返回N/A——适合参考文档、书籍等无真实事件时间的内容。用标签控制记忆可见性标签支持可见性作用域——当一个记忆库服务多个用户、但每个用户只应看到相关记忆时尤为有用:Item 标签:为单条记忆打上特定作用域Document 标签:为一批内容中的所有 item 统一打标签标签过滤:在 recall/reflect 时按标签过滤记忆只有在它的标签与 recall 请求中的标签过滤器有交集时才会返回。常见命名约定包括user:id(按用户隔离)、session:id(会话隔离)、room:id(聊天室)、topic:name(主题过滤)。代码示例见 Retain API,过滤选项见 Recall API。用 Retain Mission 引导抽取默认情况下,retain()会抽取内容中所有显著事实。你可以用retain mission(retain_mission)收窄这一焦点——用自然语言描述这个库应该关注什么:e.g. Always include technical decisions, API design choices, and architectural trade-offs. Ignore meeting logistics, greetings, and social exchanges.Mission 会与内置规则一起注入抽取提示词——它引导 LLM 但不替换抽取逻辑,且与所有抽取模式(concise、verbose、custom)兼容。还可以调整抽取模式获得更细粒度控制:模式适用场景concise(默认)通用——有选择性、快速verbose需要更丰富的事实,包含完整上下文与关系custom想完全自定义抽取规则retain_mission与retain_extraction_mode可通过 memory-banks 配置 API 或HINDSIGHT_API_RETAIN_MISSION环境变量设置。源码中,config.py 的_validate_extraction_mode()会校验取值、非法时回退默认值并告警;从源码结构看,当 LLM provider 配置为none时,系统还会强制切换为chunks模式(基于分块的兜底抽取,不调用 LLM)。当 mission 排除了文档的全部内容Mission 收窄的是什么成为记忆——不产生事实的内容就不会产生任何记忆。文档本身仍会被存储,但recall与reflect检索的是记忆,所以零记忆的文档两者都找不到它。收紧 mission 因此牺牲的是原始文本的可检索性,而不仅是事实的生成。这是正常结果而非错误:retain 成功,操作报告为已完成。两个信号可以确认它发生了:位置看什么retain.completedwebhookdata.memory_unit_count: 0Metricshindsight.retain.documents.total{outcomeno_facts}源码印证了该指标的存在:metrics.py 中hindsight.retain.documents.total计数器按outcomefacts/no_facts打标签,当memory_unit_count为 0 时归入no_facts。事后可审计:GET /documents返回每个文档的memory_unit_count,过滤为0即可列出当前所有不可达的文档。抽取并非完全确定——边界文档可能一次运行产出事实、另一次没有。请把零结果当作这份文档需要再处理一遍,而不是永久结论。要恢复某文档,放宽 mission 后重新处理即可——存储的文本会被重新抽取,无需重新上传:POST /v1/default/banks/{bank_id}/documents/{document_id}/reprocess观察整合(Observation Consolidation)retain()完成后,Hindsight 会在后台自动触发观察整合。该过程:将新事实与已有观察做比对分析当模式浮现时创建新观察用新证据精炼已有观察追踪哪些事实支撑每条观察这是异步发生的——你的retain()调用立即返回,整合在后台运行。详见 Observations 文档,实现位于 consolidation 模块。Memory Defense 与来源溯源receipt_uri(可选)类型:string。指向外部回执或联合签名系统的可选指针。原样存储,并在该 item 的任何 Memory Defense 判定中通过security_events.receipt_uri暴露。422 — Memory Defense 违规当目标 bank 启用了 Memory Defense 且批次中所有item 都被策略拦截时,请求返回 422 及违规列表:{ detail: { violations: [ { index: 0, detector: prompt_injection, severity: high, message: ... } ] } }部分拦截的批次返回 200 并处理未被拦截的 item;被拦截的 item 会从结果中静默丢弃,其判定记录在security_events中。源码层面,orchestrator.py 定义了BlockedViolation(含index、detector、message三个字段,与上文 422 响应体一一对应)与MemoryDefenseAllBlockedError,后者在整批被拦截时抛出并由 HTTP 层转成 422。完整指南见 Memory Defense 文档。retain 完成后你得到什么retain()完成后,你会获得:结构化事实:保留语义、情绪与推理统一实体:消解不同的名称变体知识图谱:含实体、时间、语义与因果四类连接时间锚定:同时支持历史查询与新近性查询可选标签:用于 recall 阶段的过滤所有数据都存储在你的隔离记忆库中,随时可供recall()与reflect()使用。下一步Observations — retain 之后知识如何被整合Recall — 多策略搜索如何检索相关记忆Reflect — 智能体循环如何使用观察Retain API — 代码示例与完整参数说明【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考