用 @vectorize-io/hindsight-eliza 为 elizaOS Agent 接入 Hindsight 长期记忆
2026/9/14 14:11:02 网站建设 项目流程

用 @vectorize-io/hindsight-eliza 为 elizaOS Agent 接入 Hindsight 长期记忆

【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight

本指南围绕 Hindsight 官方提供的 elizaOS 集成插件@vectorize-io/hindsight-eliza(源码位于 hindsight-integrations/eliza),讲解如何通过 Provider 与 Evaluator 两个组件,为基于 elizaOS 的 Agent 叠加由 Hindsight 支撑的长期记忆能力。读完本文,你将掌握插件的安装、配置、全部可调参数,以及底层 recall / retain 调用链与容错设计,可直接在自己的角色卡(character)中落地使用。

一、插件定位:一条插件,两条记忆通路

@vectorize-io/hindsight-eliza的目标非常聚焦:给 elizaOS Agent 提供"会学习"的长期记忆。它不做任何侵入式改造,而是以标准 elizaOS 插件的形式注册两个组件:

  • HINDSIGHT_MEMORYprovider(召回侧)——在每次模型调用之前,用当前消息文本向 Hindsight 发起语义召回,把相关记忆以 Markdown 列表的形式注入到 Prompt 上下文中;
  • HINDSIGHT_RETAINevaluator(留存侧)——在每一轮对话处理完之后,把会话消息写入 Hindsight 长期记忆库。

两个组件默认同时启用,且叠加在 elizaOS 现有记忆机制之上,不冲突、不替换。最关键的设计原则是失败安全(fail safe):Hindsight 服务一旦不可用,插件会静默吞掉错误,Agent 依然能正常响应,绝不会因为记忆服务故障而阻塞对话。

从源码看,插件的组装逻辑位于 plugin.ts:createHindsightPlugin根据recall.enabled/retain.enabled决定是否挂载 provider 与 evaluator,最终返回一个标准的 elizaOSPlugin对象(name@vectorize-io/hindsight-eliza)。

二、安装与依赖要求

在 Agent 项目中安装插件本体及其客户端依赖:

npm install @vectorize-io/hindsight-eliza @vectorize-io/hindsight-client

安装时需满足以下前置条件(见 package.json):

  • peer dependency@elizaos/core^1.7.2(开发环境锁定1.7.2);
  • Node.js>=22engines字段要求);
  • 打包与测试工具:tsup(构建)、vitest(测试)、typescript ^5.7.0

需要说明的是,本插件对 Hindsight 客户端采用的是结构化鸭子类型(structural subset):源码 client.ts 中定义的HindsightClient接口只要求recallretain两个方法,与@vectorize-io/hindsight-client的真实实现签名一致,但插件本身不硬依赖客户端包——因此你也可以传入任何实现了相同接口的自定义客户端。

三、快速接入:三步启用长期记忆

插件提供了开箱即用的createHindsightPlugin工厂函数,最小接入代码如下(与 README 示例一致):

import { createHindsightPlugin } from "@vectorize-io/hindsight-eliza"; import { Hindsight } from "@vectorize-io/hindsight-client"; const hindsightPlugin = createHindsightPlugin({ client: new Hindsight({ apiKey: process.env.HINDSIGHT_API_KEY }), recall: { budget: "high", includeEntities: true }, retain: { tags: ["source:eliza"] }, }); export const character = { name: "Ada", plugins: [hindsightPlugin], };

三个要点值得展开:

  1. client必填:传入一个 Hindsight 客户端实例,通常通过HINDSIGHT_API_KEY环境变量初始化;
  2. recall/retain均为可选配置块:不传则使用默认值(见下文参数表);
  3. 直接挂到角色卡:插件作为标准Plugin放进character.plugins数组即可,elizaOS 会自动加载 provider 与 evaluator。

记忆按"银行"隔离:bank 的解析逻辑

默认情况下,记忆按用户隔离存储——每条消息以message.entityId作为 bank 标识,即每个用户/Agent 拥有独立的记忆空间。你也可以传入固定字符串或按消息动态求值的函数:

// 固定 bank:所有消息读写同一个记忆库 createHindsightPlugin({ client, bank: "team-bank" }); // 动态 bank:按房间或用户维度隔离 createHindsightPlugin({ client, bank: (message) => `room:${message.roomId}`, });

这一逻辑的实现位于 options.ts 的resolveBank函数:函数形式优先调用求值;非空字符串作为固定 bank;否则回落到message.entityId。测试 plugin.test.ts 验证了bank: "team-bank"时 recall 会以"team-bank"作为第一个参数调用客户端。

四、完整参数表:一次读懂全部配置

以下参数表完整覆盖 README 内容,并结合 options.ts 的类型定义补充了语义说明:

OptionDescriptionDefault
client一个 Hindsight 客户端实例(必填)必填
bank固定 bank 字符串,或(message) => string函数message.entityId
recall.enabled是否启用 recall providertrue
recall.budget处理预算,"low" \| "mid" \| "high",控制延迟与深度权衡"mid"
recall.types限制召回的事实类型全部(all)
recall.maxTokens召回结果 token 上限API 默认
recall.includeEntities是否包含实体观测(entity observations)false
recall.heading召回记忆上方渲染的标题# Relevant long-term memories
retain.enabled是否启用 retain evaluatortrue
retain.async是否异步(fire-and-forget),不增加对话延迟true
retain.tags附加到每条留存记忆上的标签
retain.metadata附加到每条留存记忆上的元数据
retain.includeAgentMessages是否同时留存 Agent 自己的回复false

关于recall.typesbudget的底层类型

types支持的事实类型由 client.ts 定义为联合类型:"world" | "experience" | "observation"。其中"observation"对应实体观测,这也解释了为何recall.includeEntities默认关闭——开启后会把实体观测一并纳入召回结果。

budget的类型为"low" | "mid" | "high"(见 client.ts),它控制 Hindsight 在召回时投入的处理强度:"low"偏向低延迟、浅处理,"high"偏向深度处理、更高质量的召回,默认"mid"是两者之间的平衡点。

五、召回侧原理:HINDSIGHT_MEMORY Provider 的内部实现

recall provider 的实现位于 provider.ts,核心调用链如下:

  1. 空消息短路get首先取message.content?.text并 trim,若无文本则直接返回空结果,不会触发 recall 调用(测试 provider.test.ts 验证了这一点);
  2. 调用客户端:以resolveBank解析出的 bank、消息文本为 query,携带types/maxTokens/budget/includeEntities调用client.recall(...)
  3. 格式化注入formatMemories将每条结果的texttrim 后按- item的 Markdown 列表格式拼接,前面加上标题(默认# Relevant long-term memories),整体作为 provider 的text注入 Prompt;无结果时返回空字符串(不渲染标题);
  4. 结果透传:除了注入文本,provider 还在返回值中携带结构化数据——values.hindsightMemoryCount为召回条数,data.hindsight为完整召回响应,方便后续逻辑(如追踪)读取。

容错设计:整个 recall 包裹在try/catch中,任何异常(包括 Hindsight 服务 503)都会被吞掉,返回空文本并置hindsightMemoryCount = 0、把错误信息放入data.hindsightError。测试 provider.test.ts 分别验证了Error与普通字符串两种异常形态的兜底行为。这就是"记忆服务故障绝不阻塞 Agent 响应"的实现保证。

provider 的元信息(name: "HINDSIGHT_MEMORY"dynamic: false)在 provider.test.ts 中有对应断言。

六、留存侧原理:HINDSIGHT_RETAIN Evaluator 的内部实现

retain evaluator 的实现位于 evaluator.ts,它在每一轮对话结束后执行:

  • alwaysRun: true:每轮都运行;
  • validate:仅当消息content.texttrim 后非空才真正执行留存(空文本、纯空白消息直接跳过);
  • handler 逻辑
    • 解析 bank 后,判断触发消息是否来自 Agent 本身(message.entityId === runtime.agentId);
    • 默认只存用户消息:若触发消息来自 Agent 且未开启includeAgentMessages,则跳过(测试 evaluator.test.ts);
    • includeAgentMessages: true:除用户消息外,还会逐条留存本轮 Agent 的回复(responses数组),空文本回复同样会被跳过(测试见 evaluator.test.ts)。

异步与失败隔离retain.async默认为true,此时client.retain被 fire-and-forget 地触发,handler 立即返回,不会为对话增加任何延迟——即使底层 retain 永不返回(测试中模拟了永不 settle 的 Promise),handler 也能正常 resolve(见 evaluator.test.ts)。同时所有 retain 调用都带有.catch(() => undefined),同步模式下的写入失败同样不会让整轮对话报错(evaluator.test.ts)。

留存调用会把tagsmetadata一并透传给客户端(evaluator.ts),测试 evaluator.test.ts 验证了{ channel: "discord" }这类元数据会原样传递。

七、进阶:拆开用 Provider 与 Evaluator 自行组装

如果你的使用场景只需要"只召回不留存"或"只留存不召回",createHindsightPlugin内部其实只是把两个部件拼在一起(见 plugin.ts)。你也可以跳过工厂函数,直接使用导出的底层构造函数:

  • createHindsightProvider(client, bank, recallOptions)——返回HINDSIGHT_MEMORYprovider;
  • createHindsightEvaluator(client, bank, retainOptions)——返回HINDSIGHT_RETAINevaluator;
  • resolveBank(bank, message)——bank 解析工具函数。

所有公开 API 均从 index.ts 统一导出,包括类型HindsightPluginOptionsRecallOptionsRetainOptionsBankResolverHindsightClientRecallResultRecallResponseRetainResponseBudgetFactType。例如,若你想做一个"纯记忆写入"的 Agent,可以直接构造 evaluator 挂到自己的插件里,而不必引入 recall provider 的开销。

八、开发与验证:本地构建与测试

仓库内该插件是一个完整的 TypeScript 包,本地开发命令(见 package.json):

npm install npm test # vitest run,运行单元测试 npm run build # tsup 构建到 dist/

测试套件位于 hindsight-integrations/eliza/tests,共三组用例,可作为理解插件行为的权威参考:

  • plugin.test.ts——验证插件默认同时注册 provider 与 evaluator、可独立禁用 recall / retain、参数透传与失败兜底;
  • provider.test.ts——覆盖默认/自定义标题渲染、空结果、空白文本过滤、bank 解析、错误吞并等 11 个场景;
  • evaluator.test.ts——覆盖异步 fire-and-forget、tags/metadata 透传、Agent 消息留存开关等 11 个场景。

九、常见配置场景速查

  • 想让记忆更"深"recall: { budget: "high", includeEntities: true }——提升召回质量并纳入实体观测;
  • 只想记录、不注入recall: { enabled: false },保留纯留存管线;
  • 对话延迟敏感:保持retain.async: true(默认),留存完全异步化;
  • 给记忆打来源标记retain: { tags: ["source:eliza", "env:prod"] },便于后续按标签检索过滤;
  • 多用户/多房间隔离:传bank: (message) => \room:${message.roomId}`` 实现按房间分库;
  • 把 Agent 的回答也沉淀为记忆retain: { includeAgentMessages: true }

该插件遵循 MIT 许可证(见 hindsight-integrations/eliza/README.md 与 package.json),可直接集成到你的 elizaOS Agent 项目中。

【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询