ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Hindsight × elizaOS 集成指南:为 Agent 接入长期记忆的官方插件 @vectorize-io/hindsight-eliza

Hindsight × elizaOS 集成指南:为 Agent 接入长期记忆的官方插件 @vectorize-io/hindsight-eliza Hindsight × elizaOS 集成指南为 Agent 接入长期记忆的官方插件 vectorize-io/hindsight-eliza【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsightHindsight 在 v0.1.0 版本中正式发布了面向 elizaOS 的长期记忆集成插件vectorize-io/hindsight-eliza对应仓库目录 hindsight-integrations/eliza让 elizaOS 智能体能够通过 Hindsight 存储与检索持久化记忆。本文以该集成的变更日志为脉络结合插件源码与测试用例完整讲解插件的安装、接入方式、全部配置项、底层实现原理与故障安全行为帮助你在一小时内为自己的 eliza 角色接入可长期演进的记忆能力。一、从变更日志看这个集成的定位eliza 集成变更日志 记录了该集成的首个版本 v0.1.0 的核心变更Added a Hindsight long-term memory integration for elizaOS, enabling eliza to store and retrieve persistent memories via Hindsight.这是该插件唯一也是最重要的一个特性为 elizaOS 增加基于 Hindsight 的长期记忆能力——eliza 既能将对话记住store又能在后续对话中想起retrieve。该特性由 benfrank241 贡献提交号为 f36a462d1。集成以独立 npm 包vectorize-io/hindsight-eliza形式发布源码完整托管在仓库的 hindsight-integrations/eliza 目录下包含源码src/、测试tests/与打包配置package.json、tsup.config.ts。二、插件架构一个 Provider 一个 Evaluator从 plugin.ts 的源码可以看到这个插件只做两件事分别对应 elizaOS 的两个扩展点HINDSIGHT_MEMORYProvider读取在每次模型调用前用当前用户消息查询 Hindsight把相关记忆注入提示词上下文HINDSIGHT_RETAINEvaluator写入在每轮对话结束后把消息持久化到 Hindsight。// hindsight-integrations/eliza/src/plugin.ts核心逻辑 export function createHindsightPlugin(options: HindsightPluginOptions): Plugin { const { client, bank, recall {}, retain {} } options; const providers recall.enabled false ? [] : [createHindsightProvider(client, bank, recall)]; const evaluators retain.enabled false ? [] : [createHindsightEvaluator(client, bank, retain)]; return { name: vectorize-io/hindsight-eliza, description: Hindsight long-term memory: recall relevant memories and retain conversations., providers, evaluators, }; }两个组件默认同时开启并且是叠加在 elizaOS 自身既有记忆机制之上运行的而不是替换它。recall.enabled与retain.enabled可分别关闭任意一侧——例如只做召回、只做留存或干脆只保留 Provider/Evaluator 之一。这一行为在 tests/plugin.test.ts 中有对应用例覆盖can disable both recall and retain、can disable only recall…、can disable only retain…。createHindsightProvider与createHindsightEvaluator也从 index.ts 单独导出如果你想绕过插件、自己组装 Provider/Evaluator可以直接使用它们。三、安装与快速接入3.1 安装依赖需要同时安装插件本体和 Hindsight 官方客户端npm install vectorize-io/hindsight-eliza vectorize-io/hindsight-client环境要求来自 package.jsonpeerDependencyelizaos/core^1.7.2必须由宿主 eliza 项目提供Node.js 22包以ESM形式发布type: module主入口为dist/index.js类型声明为dist/index.d.ts。3.2 最小接入示例在角色定义character中挂载插件即可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], };接入后Ada的每一轮对话都会自动经历先召回相关记忆 → 模型基于记忆作答 → 结束后把本次对话留存到 Hindsight的完整闭环。3.3 关于 memory bank记忆库隔离插件默认按消息的entityId作为 bank 键——也就是每个用户/每个 agent 一套独立记忆。这是 options.ts 中resolveBank的默认行为export function resolveBank(bank: BankResolver | undefined, message: Memory): string { if (typeof bank function) return bank(message); if (typeof bank string bank.length 0) return bank; return message.entityId; }bank参数支持两种形态固定字符串所有消息读写同一个 bank例如团队共享记忆bank: team-bank函数(message) string按消息动态推导 bank典型用法是按房间隔离room:${message.roomId}或按用户隔离。resolveBank的解析优先级在 tests/options.test.ts 中有完整用例验证函数优先 → 非空字符串 → 回退entityId空字符串也会回退到entityId。四、完整配置项详解以下配置表完整继承自集成文档并补充了源码层面的默认值与语义源码见 options.tsOption说明默认值clientHindsight 客户端实例来自vectorize-io/hindsight-client必填bank固定 bank 字符串或(message) string函数message.entityIdrecall.enabled是否启用召回 Providertruerecall.budget处理预算low \| mid \| high权衡召回延迟与深度midrecall.types限定召回的事实类型world \| experience \| observation全部recall.maxTokens召回结果的最大 token 上限API 默认recall.includeEntities是否在召回中附带实体观测entity observationsfalserecall.heading注入提示词时召回记忆上方的标题# Relevant long-term memoriesretain.enabled是否启用留存 Evaluatortrueretain.async是否异步留存fire-and-forget不增加对话延迟trueretain.tags为每条留存记忆附加的标签数组—retain.metadata为每条留存记忆附加的元数据对象—retain.includeAgentMessages是否同时留存 agent 自己的回复false4.1 客户端最小接口structural subset插件并不直接依赖vectorize-io/hindsight-client而是在 client.ts 中定义了一个结构子集接口HindsightClient只要求实现两个方法export interface HindsightClient { retain(bankId: string, content: string, options?: { timestamp?: Date | string; context?: string; metadata?: Recordstring, string; documentId?: string; tags?: string[]; async?: boolean; }): PromiseRetainResponse; recall(bankId: string, query: string, options?: { types?: FactType[]; maxTokens?: number; budget?: Budget; includeEntities?: boolean; includeChunks?: boolean; }): PromiseRecallResponse; }这种设计意味着只要对象实现了recall/retain两个方法就能作为client传入——既方便在测试中注入 mock也便于接入自建网关或代理实现。五、底层实现原理5.1 Provider 的召回与提示词注入provider.ts 中Provider 名为HINDSIGHT_MEMORY、dynamic: false。每次get()被调用时取出message.content.text并trim()如果消息为空直接短路返回不会发起网络请求对应测试 returns empty text for an empty message without calling recall调用client.recall(bankId, query, {...})把types/maxTokens/budget/includeEntities原样透传将召回结果格式化为 Markdown 无序列表渲染在heading之下function formatMemories(results: RecallResult[], heading: string): string { const lines results .map((r) r.text?.trim()) .filter((text): text is string Boolean(text)) .map((text) - ${text}); if (lines.length 0) return ; return ${heading}\n${lines.join(\n)}; }返回结构包含三部分text注入提示词的渲染文本、values.hindsightMemoryCount命中记忆条数可被 eliza 的模板/状态系统读取、data.hindsight原始响应供调试追踪。RecallResult的字段client.ts包括id、text、type、entities、context、occurred_start/end、mentioned_at、document_id、metadata、chunk_id可见 Hindsight 回传的记忆带有完整的时间与溯源信息可在上层做进一步加工。5.2 Evaluator 的留存时机与去重逻辑evaluator.ts 中Evaluator 名为HINDSIGHT_RETAIN、alwaysRun: true。它选择在每轮对话处理完之后运行这正是持久化新记忆的天然时机。处理逻辑validate()只放行含非空文本的消息默认留存触发消息本身但如果该消息是 agent 自己的且未开启includeAgentMessages则跳过避免把 agent 的回复当成用户记忆存入对应测试 skips the agents own message by default开启includeAgentMessages后还会遍历responses把 agent 本轮的每条回复也依次留存对应测试 retains agent replies when includeAgentMessages is setasync: true默认时对外直接返回 resolved promise真正的留存请求在后台 fire-and-forget不增加对话时延async: false时才等待完成适合需要确认写入成功的场景。5.3 故障安全fail-safe设计集成文档明确承诺a Hindsight outage never blocks the agent from responding.Hindsight 宕机绝不会阻塞 agent 响应。这一点在源码与测试中都有硬保证Providerrecall抛错时被try/catch捕获返回空文本与hindsightError错误信息绝不向上抛出provider.ts对应测试 never throws when recall failsEvaluatorretain的 promise 被.catch(() undefined)吞掉即使写入失败也不会让回合失败evaluator.ts对应测试 does not reject the turn when retain fails (async mode)。也就是说记忆服务不可用时eliza 依然可以正常对话只是召回为空、留存失败记忆能力优雅降级。六、从配置项到客户端的完整调用链综合 options.ts、provider.ts、evaluator.ts 与 client.ts插件的调用链可以归纳为elizaOS 角色 (character.plugins) └─ createHindsightPlugin({ client, bank, recall, retain }) ├─ HINDSIGHT_MEMORY Provider每轮模型调用前 │ └─ resolveBank() → client.recall(bankId, query, {types, maxTokens, budget, includeEntities}) │ └─ 格式化 → 注入提示词heading 记忆列表→ values.hindsightMemoryCount └─ HINDSIGHT_RETAIN Evaluator每轮结束后 └─ resolveBank() → client.retain(bankId, text, {async, tags, metadata}) └─ 可选遍历 responses 留存 agent 回复测试 tests/plugin.test.ts 通过 mock client 验证了整条链路上的关键行为包括默认同时注册 Provider 与 Evaluator、bank覆盖、recall选项透传budget: high、types: [world]、includeEntities: true、maxTokens: 500均按原样传给客户端、空消息短路、故障容错等。这些用例本身就是很好的集成行为参考说明书。七、常见接入场景与建议按用户隔离记忆不传bank默认以entityId分库每个用户一套独立长期记忆适合 C 端助手按房间/群组共享记忆bank: (message) \room:${message.roomId}同房间成员共享上下文适合协作场景团队统一知识库bank: team-bank固定库所有消息读写同一个 bank降低召回噪音recall.types: [world]只召回世界性事实maxTokens限制注入的 token 量调试与追踪关注 Provider 返回的data.hindsight含trace/entities/chunks原始响应与values.hindsightMemoryCount本地开发验证在 hindsight-integrations/eliza 目录下执行npm install、npm test、npm run build即可跑通测试与打包项目使用 vitest tsup。八、小结vectorize-io/hindsight-eliza是 Hindsight 官方为 elizaOS 提供的长期记忆插件v0.1.0 以一个 Provider 一个 Evaluator的极简架构实现了记忆的召回与留存闭环默认按entityId分库隔离、支持bank自定义、全部召回/留存参数可调并以源码级的 try/catch 与 promise 吞错保证了记忆服务故障时的优雅降级。若想深入源码建议从 plugin.ts装配入口、provider.ts召回、evaluator.ts留存三个文件读起配合 tests/plugin.test.ts 验证你对各行为的理解。【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进