使用 Hindsight 为 Haystack Agent 接入持久化长期记忆:工具集成与自动记忆实战指南
2026/9/13 17:10:17 网站建设 项目流程

使用 Hindsight 为 Haystack Agent 接入持久化长期记忆:工具集成与自动记忆实战指南

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

导读

本文基于 hindsight-docs/docs-integrations/haystack.md 与仓库内hindsight-haystack包的完整源码,系统讲解如何让基于 Haystack 构建的 Agent 通过 Hindsight 获得跨会话的持久化长期记忆。你将掌握两种互补的集成模式——create_hindsight_tools(...)显式工具模式与HindsightMemoryWrapper自动记忆模式,理解 retain / recall / reflect 三个记忆原语的底层行为,并能按需配置 budget、tags、response_schema 等参数,把记忆能力平滑接入生产级 Haystack 流水线。

Hindsight 与 Haystack 的集成方式

Haystack 是 deepset 推出的开源 LLM 应用框架,其Agent组件允许通过Tool/Toolset扩展工具调用能力。Hindsight 则为 Agent 提供「会学习」的长期记忆服务,两者通过hindsight-haystack包桥接。该包位于仓库的 hindsight-integrations/haystack 目录,对外暴露两种互补的使用模式:

  • create_hindsight_tools(...):返回一组 HaystackToolretain_memoryrecall_memoryreflect_on_memory),由模型在对话回合内自主决定何时调用——适合希望模型主动管理记忆的场景;
  • HindsightMemoryWrapper:一个 HaystackToolset,将上述工具打包,并额外提供**自动召回(auto-recall)自动留存(auto-retain)**两个开关——在每轮对话前自动把相关记忆注入系统提示词,在每轮对话后自动把用户与助手消息写入记忆,全程无需模型主动调用工具。

两种模式共享同一个底层后端_HindsightToolBackend(见 tools.py),因此显式调用与自动记忆使用完全一致的参数语义与数据流。

安装与依赖要求

通过 pip 安装集成包:

pip install hindsight-haystack

依据 pyproject.toml 的声明,环境需满足:

依赖版本要求
Python>= 3.10
haystack-ai>= 2.12.0
hindsight-client>= 0.4.0

其中hindsight-client是 Hindsight 的官方 Python 客户端,负责与服务端通信;hindsight-haystack在其之上将异步 API(aretain/arecall/areflect/acreate_bank)封装为 Haystack 可调用的同步Tool

快速开始:为 Agent 挂载三个记忆工具

最小可运行示例

from hindsight_client import Hindsight from hindsight_haystack import create_hindsight_tools from haystack.components.agents import Agent from haystack.components.generators.chat import OpenAIChatGenerator from haystack.dataclasses import ChatMessage client = Hindsight(base_url="http://localhost:8888") tools = create_hindsight_tools( client=client, bank_id="user-123", mission="Track user preferences", ) agent = Agent( chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"), tools=tools, system_prompt=( "You are a helpful assistant with long-term memory. " "Use retain_memory to store important facts. " "Use recall_memory to search memory before answering." ), ) result = agent.run(messages=[ChatMessage.from_user("Remember that I prefer dark mode")]) print(result["messages"][-1].text)

要点说明:

  • bank_id必填参数,标识本次记忆操作所属的「记忆银行」(memory bank),不同用户/租户应使用不同 bank_id 实现数据隔离;
  • mission是可选参数,用于描述该银行的事实抽取语境(如 "Track user preferences"),会随acreate_bank一并提交给服务端,指导其从原始文本中提炼事实;
  • 系统提示词应明确指导模型何时调用记忆工具,否则模型可能不会主动使用它们——这是显式工具模式能否生效的关键。

三个工具各自的职责

依据 tools.py 中_TOOL_DEFS的静态定义,三个工具的语义如下:

工具名参数用途对应客户端 API
retain_memorycontent(必填)将重要事实、用户偏好、决策等写入长期记忆,供跨会话检索aretain
recall_memoryquery(必填)在长期记忆中检索相关信息,返回带编号的匹配结果列表arecall
reflect_on_memoryquery(必填)基于已有记忆综合出连贯的总结或推理式回答,而非罗列原始事实areflect

三者各自带有独立的 JSON Schema 参数定义(type: object+properties+required),可直接被 HaystackAgent序列化后用于 LLM 的 function calling 描述。仓库测试 test_tools.py 验证了工具名称集合恒为{retain_memory, recall_memory, reflect_on_memory},且每个工具都具备完整的 name、description 与参数 Schema。

自动记忆:HindsightMemoryWrapper

如果不希望依赖模型自觉调用工具,可使用HindsightMemoryWrapper让记忆行为完全自动化:

from hindsight_haystack import HindsightMemoryWrapper toolset = HindsightMemoryWrapper( client=client, bank_id="user-123", mission="Track user preferences", auto_recall=True, # 每轮对话前把相关记忆注入系统提示词 auto_retain=True, # 每轮对话后存储用户 + 助手消息 ) agent = Agent( chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"), tools=toolset, system_prompt="You are a helpful assistant with long-term memory.", ) # 通过 toolset.run() 获得自动记忆行为 result = toolset.run(agent, messages=[ChatMessage.from_user("I prefer dark mode")])

run() 的内部三步流水线

从 tools.py 的run()实现可以看出,自动记忆在单次调用内完成三步:

  1. Auto-recall(若开启):从消息列表中提取最后一条用户消息文本(_extract_last_user_text),以其为 query 调用arecall,将命中的记忆按默认模板注入系统提示词。默认模板定义于DEFAULT_MEMORY_PROMPT

    Below are relevant memories from previous conversations: {memories} Use these memories to provide more personalized and contextual responses.

    若原始系统提示词非空,记忆块会被追加在末尾;若没有命中记忆,则原样透传基础提示词,不影响对话。

  2. Agent 执行:以「富化后的 system_prompt + 原始消息」调用agent.run(...)

  3. Auto-retain(若开启):将本轮所有 user 与 assistant 消息逐条调用aretain写入记忆,并在 metadata 中合并rolesource: haystack字段,便于后续按角色溯源(见 tools.py)。

此外还提供异步版本run_async(),语义与同步版完全一致(tools.py)。

防止提示词膨胀的两个内置机制

  • max_recall_results:默认10,限制注入系统提示词的记忆条数上限,防止无限增长拖垮上下文窗口——测试 test_tools.py 验证了当召回 20 条记忆而max_recall_results=3时,提示词中只出现前 3 条;
  • 空结果短路:无记忆命中时直接返回基础提示词,不插入任何模板占位内容。

选择性工具:按需裁剪记忆能力

create_hindsight_toolsHindsightMemoryWrapper均支持通过include_retain/include_recall/include_reflect三个开关裁剪工具集合:

# 仅保留 retain + recall,去掉 reflect tools = create_hindsight_tools( client=client, bank_id="user-123", include_reflect=False, )
# 更细粒度:只保留 recall tools = create_hindsight_tools( client=client, bank_id="user-123", include_retain=False, include_recall=True, include_reflect=False, )

当三个开关全部为False时返回空列表(测试见 test_tools.py)。HindsightMemoryWrapper同样接受这三个参数,且其自动记忆行为只依赖 retain/recall 后端能力——例如仅开启auto_recall时,你甚至可以裁剪掉 retain 工具。

全局配置 configure():一次配置,处处省略

当多个 Agent 需要共享同一套连接与默认参数时,可调用configure()一次性设置全局默认值,之后所有工具调用都能省略client=/hindsight_api_url=等参数:

from hindsight_haystack import configure configure( hindsight_api_url="http://localhost:8888", api_key="your-api-key", budget="mid", tags=["source:haystack"], context="my-app", mission="Track user preferences", ) tools = create_hindsight_tools(bank_id="user-123")

配置项的默认值与优先级

依据 config.py 中HindsightHaystackConfigconfigure()的默认值:

参数默认值说明
hindsight_api_urlhttps://api.hindsight.vectorize.ioHindsight API 服务地址,默认指向 Hindsight Cloud
api_keyNone(回退到环境变量)认证密钥,未显式传入时读取HINDSIGHT_API_KEY环境变量
budget"mid"recall/reflect 的预算等级,取值范围low/mid/high
max_tokens4096recall 结果的最大 token 数
tagsNoneretain 写入记忆时附加的默认标签
recall_tagsNonerecall 检索时用于过滤的标签
recall_tags_match"any"标签匹配模式:any/all/any_strict/all_strict
context"haystack"retain 操作的来源标签(source label),可用retain_context覆盖
missionNoneBank 任务描述,供事实抽取使用
verboseFalse是否开启详细日志

参数解析优先级由 resolve_client 与后端回退逻辑共同决定:显式传入的参数 > 全局configure()配置 > 内置默认值。例如显式budget="low"会覆盖configure(budget="high")(测试见 test_tools.py)。客户端还默认携带 30 秒超时(TIMEOUT_DEFAULT = 30.0)与hindsight-haystack/{version}形式的 User-Agent。

另外注意:即使不调用configure(),只要设置了HINDSIGHT_API_KEY环境变量,工具也能正常工作——resolve_client会直接读取该环境变量(测试 test_tools.py 验证了这一点)。

源码级原理:五个值得了解的实现细节

1. 持久化事件循环桥:同步 Tool 包装异步客户端

hindsight_client的核心 API(aretain/arecall/areflect)是异步的,而 HaystackTool要求同步可调用。hindsight-haystack的解法是在守护线程中常驻一个事件循环_loop,通过asyncio.run_coroutine_threadsafe提交协程并阻塞等待结果(tools.py)。这样做是因为 aiohttp 的 session 绑定在创建它的事件循环上,若每次用asyncio.run()新建循环会导致后续调用连接失效。测试 test_tools.py 验证了该桥在「无事件循环」与「事件循环运行中」两种上下文中均能正确工作。

2. Bank 自动创建:懒初始化 + 幂等重试

当传入mission时,后端在首次真正执行记忆操作前会自动调用acreate_bank创建/更新银行(tools.py),且具有幂等性:

  • 若返回 "already exists" / 409 / conflict 类错误,视为创建成功并标记初始化完成,后续不再重复调用;
  • 若为网络抖动等瞬时错误,则标记初始化,下次调用会重试。

对应测试覆盖了「bank 只创建一次」「瞬时失败重试」「已存在不再重试」等场景(test_tools.py)。未传mission时不会触发 bank 创建,直接使用现有银行。

3. 工具调用永不抛异常

三个工具的实现都采用「捕获异常并返回错误字符串」的策略(如Failed to store memory: ...),让 Agent 能感知失败并自主应对,而不是中断整个对话流程(见 tools.py)。连接配置的解析则始终成功——API URL 默认指向 Hindsight Cloud,缺失 API key 只会在真正发起调用时才暴露。测试 test_tools.py 验证了 retain 失败时返回友好错误信息而非抛出异常。

4. 序列化安全:api_key 永不落盘

_HindsightTool重写了to_dict()/from_dict(),将工具配置(bank_id、API URL 等)序列化以便 Haystack 流水线可被转储为 YAML 检查/共享。但api_key被刻意排除在序列化之外——反序列化时通过resolve_clientHINDSIGHT_API_KEY环境变量重新读取,从而避免密钥泄漏进 YAML 转储(见 tools.py 与测试 test_tools.py)。

5. retain 的 document_id 自动生成

未显式指定retain_document_id时,每次 retain 都会生成{session_id}-{uuid_hex12}格式的唯一文档 ID(session 前缀来自后端初始化时的随机短 ID),保证同一银行内多次写入互不冲突(tools.py)。

运行前提:Hindsight Cloud 或自托管

在接入工具之前,你需要一个可访问的 Hindsight 实例:

  • Hindsight Cloud(推荐):注册即用,无需自建基础设施;

  • 自托管

    pip install hindsight-all export HINDSIGHT_API_LLM_API_KEY=your-api-key hindsight-api # 启动于 http://localhost:8888

自托管时,将base_url/hindsight_api_url指向http://localhost:8888即可。集成包自带的端到端测试(test_e2e.py)展示了完整的验证路径:它通过HINDSIGHT_API_URL环境变量(默认http://localhost:8888)探测/health端点,随后创建随机 bank、调用 retain 写入、再轮询 recall 直到记忆浮现(因为事实抽取与索引需要时间)。运行方式:

uv run pytest tests/test_e2e.py -v

该模块属于真实 LLM/真实服务测试桶(requires_real_llm),默认在 PR CI 中排除,需在具备运行中 Hindsight 实例的环境单独执行。

完整参数速查:create_hindsight_tools / HindsightMemoryWrapper

综合 tools.py 与 config.py 的函数签名,两个入口的完整参数如下(除bank_id外均为可选):

分组参数默认值/说明
连接client预配置的Hindsight客户端(优先使用)
连接hindsight_api_urlAPI 地址,未传 client 时生效
连接api_key认证密钥,未传 client 时生效
通用budgetrecall/reflect 预算,low/mid/high,默认mid
通用max_tokensrecall 结果最大 token 数,默认4096
通用tagsretain 写入时的标签
通用recall_tags/recall_tags_matchrecall 过滤标签与匹配模式(默认any
retainretain_metadataretain 操作的默认 metadata 字典
retainretain_document_id显式文档 ID,缺省自动生成
retainretain_contextretain 来源标签,默认haystack
recallrecall_types按事实类型过滤(world/experience/observation
recallrecall_include_entities召回结果中是否包含实体信息,默认False
reflectreflect_contextreflect 的额外上下文
reflectreflect_max_tokensreflect 结果最大 token,缺省回退到max_tokens
reflectreflect_response_schemaJSON Schema,约束 reflect 输出为结构化 JSON
reflectreflect_tags/reflect_tags_matchreflect 的记忆过滤,缺省回退到 recall 对应配置
bankmissionBank 任务描述,触发自动创建银行
裁剪include_retain/include_recall/include_reflect是否包含对应工具,默认均为True
自动记忆auto_recall/auto_retainWrapper 专属,默认False
自动记忆max_recall_resultsWrapper 专属,默认10
自动记忆memory_prompt_templateWrapper 专属,记忆注入模板,须含{memories}占位符

其中reflect_response_schema值得一提:设置后,reflect 返回的将是符合 Schema 的结构化 JSON 字符串(json.dumps(structured_output)),而非自然语言段落(见 tools.py),适合需要稳定结构化输出的下游解析场景,测试见 test_tools.py。

小结

至此,你已经掌握了在 Haystack 生态中接入 Hindsight 长期记忆的完整路径:

  • create_hindsight_tools为 Agent 挂载 retain/recall/reflect 三个显式工具,让模型自主记忆;
  • HindsightMemoryWrapper开启auto_recall+auto_retain,让记忆行为完全自动化;
  • configure()与优先级规则统一管理连接与默认参数,用裁剪开关按需组装工具集;
  • 理解了背后的持久化事件循环桥、Bank 幂等创建、错误容错与序列化安全等实现细节,为排查线上问题与二次开发提供了依据。

仓库内的 hindsight-integrations/haystack/README.md 提供简明版入门,tools.py 是全部行为的权威实现,tests 目录下的单测与端到端测试则是最好的行为规范文档。

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

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

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

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

立即咨询