使用 Hindsight 为 Strands Agent 添加持久记忆:retain / recall / reflect 工具与 memory_instructions 实战指南
【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight
本篇技术指南讲解如何在 Strands Agents SDK 的 Agent 中接入 Hindsight 持久记忆能力:通过hindsight-strands集成包创建原生@tool风格的hindsight_retain、hindsight_recall、hindsight_reflect三个记忆工具,并用memory_instructions()把预召回的记忆注入系统提示词,让 Agent 在不同会话之间获得稳定、可隔离的长期记忆。读完本文你将掌握安装集成、连接 Hindsight Cloud 或本地 API、按用户/项目设计 bank ID、验证记忆生效以及常见坑位的完整方案。
为什么这套方案成立
Strands SDK 在工具与提示词上已经有自己的约定,因此 Hindsight 只需要两个插入点就能接入:工具函数(承载显式的记忆读写动作)和可选的注入指令(承载自动召回)。这意味着你不需要在 Agent 运行时内部再挂一个独立的记忆守护进程,集成面小而可预期。
从 hindsight-integrations/strands/hindsight_strands/tools.py 的源码看,该集成把 Strands 的@tool装饰器直接用于普通 Python 函数,bank_id和 Hindsight 客户端在构造时通过闭包捕获,因此返回的工具列表可以直接传给Agent(tools=...),无需修改 Agent 上下文。这正是"Strands 已把工具视为普通函数,Hindsight 顺势接入"这一设计思路的代码级印证。
前置条件
- 一个可运行的 Strands Agent(基于
strands-agentsSDK) - Python 环境,并已安装
hindsight-strands - 一套对同一用户或同一项目保持稳定的bank ID 命名方案
快速答案
- 安装 Strands 集成包
hindsight-strands; - 将其指向 Hindsight Cloud 或本地 Hindsight API;
- 用稳定的 bank ID 把记忆接入 Strands 运行时;
- 先存储一条偏好或项目事实,再启动一次全新的运行;
- 确认 recall 能自动把之前的上下文带回来。
Step 1:安装集成包
pip install hindsight-strands依据 hindsight-integrations/strands/pyproject.toml,该包要求 Python >= 3.10,依赖strands-agents与hindsight-client>=0.4.0,当前版本为 0.1.3。安装后即可从hindsight_strands导入公开 API:configure、get_config、reset_config、HindsightStrandsConfig、HindsightError、create_hindsight_tools、memory_instructions(见 hindsight-integrations/strands/hindsight_strands/init.py)。
Step 2:把 Strands 连接到 Hindsight
推荐使用 Hindsight Cloud(免费档位,无需自托管)。连接配置有两种等价写法。
方式一:全局配置(推荐单服务场景)
from hindsight_strands import configure configure( hindsight_api_url="https://api.hindsight.vectorize.io", api_key="hsk_...", # 或设置 HINDSIGHT_API_KEY 环境变量 budget="mid", max_tokens=4096, )方式二:每次调用显式传参
from strands import Agent from hindsight_strands import create_hindsight_tools, memory_instructions tools = create_hindsight_tools( bank_id="user-123", hindsight_api_url="https://api.hindsight.vectorize.io", api_key="hsk_...", )如果你在本地自托管 Hindsight,把 API URL 换成http://localhost:8888并去掉api_key即可。
关于配置解析的细节,可参考 hindsight-integrations/strands/hindsight_strands/config.py:configure()中api_key优先使用显式参数,否则回退到HINDSIGHT_API_KEY环境变量;hindsight_api_url缺省时使用默认生产地址https://api.hindsight.vectorize.io。HindsightStrandsConfig还额外支持tags(写入记忆时的默认标签)、recall_tags(召回过滤标签)、recall_tags_match(标签匹配模式,any/all/any_strict/all_strict)以及verbose开关。
Step 3:把记忆接入 Strands 运行时
from strands import Agent from hindsight_strands import create_hindsight_tools, memory_instructions tools = create_hindsight_tools( bank_id="user-123", hindsight_api_url="https://api.hindsight.vectorize.io", api_key="hsk_...", ) memories = memory_instructions( bank_id="user-123", hindsight_api_url="https://api.hindsight.vectorize.io", api_key="hsk_...", ) agent = Agent( tools=tools, system_prompt=f"You are a helpful assistant. {memories}", )如果不想做自动注入,去掉memory_instructions(),让 Agent 在需要时显式调用 recall 工具即可。
三个记忆工具的语义
create_hindsight_tools()默认生成三个@tool函数(可分别用enable_retain/enable_recall/enable_reflect开关裁剪):
| 工具 | 作用 | 底层调用 |
|---|---|---|
hindsight_retain(content) | 把信息写入长期记忆(事实、用户偏好、决策等) | 客户端retain,并在首次使用时自动create_bank确保 bank 存在 |
hindsight_recall(query) | 检索相关记忆,返回编号列表;无结果时返回 "No relevant memories found." | 客户端recall,透传budget/max_tokens,可选tags/tags_match |
hindsight_reflect(query) | 基于记忆综合出一条连贯、经过推理的回答(多条记忆需要合并时尤其有用) | 客户端reflect,返回response.text |
对应的实现与单元测试分别在 hindsight-integrations/strands/hindsight_strands/tools.py 和 hindsight-integrations/strands/tests/test_tools.py。测试中还验证了:bank 只会被创建一次、retain 失败会被包装为HindsightError并记录日志、recall 未命中时返回固定兜底文案、reflect 返回空文本时同样走兜底文案。
线程池与事件循环的兼容处理
Strands 在自身的 asyncio 事件循环内运行工具,而hindsight-client内部也使用 asyncio(包括asyncio.timeout),直接在同循环内调用会冲突。因此tools.py中通过ThreadPoolExecutor(max_workers=4)把每个记忆操作放到独立线程中执行,获得一个全新的事件循环——这是集成实现中值得注意的底层细节。
客户端生命周期管理
- 如果你传入预先创建的
client(外部拥有),集成不会关闭它,tools.close()/await tools.aclose()不会触碰外部客户端; - 如果你通过
hindsight_api_url/api_key让集成内部创建客户端,返回的HindsightTools容器(一个 list 兼容对象)会在close()/aclose()时关闭内部客户端,也支持with/async with上下文管理器。
在 FastAPI 这类服务中,推荐在应用 lifespan 里创建共享客户端并显式await client.aclose()关闭,再以client=...方式传给工具工厂(参见 hindsight-integrations/strands/README.md 的 FastAPI Lifecycle 示例)。
Step 4:选择正确的 bank 策略
- 按用户建 bank(Per-user):通常适合助手类应用,每个用户一个独立记忆空间;
- 按项目建 bank(Per-project):适合同一用户在不同无关工作流之间切换的场景;
- 无论选择哪种,务必保证
memory_instructions()与记忆工具使用同一个 bank 值,否则会出现"工具写入 A bank、提示词从 B bank 召回"的错位。
Step 5:验证记忆确实生效
- 在第一次运行中存储一条偏好或工作事实;
- 用相同的 bank ID 启动第二次运行;
- 询问之前的事实,确认 Agent 能前后一致地回答;
- 换一个不同的 bank ID 测试,确认记忆隔离符合预期。
如果第二次运行能回答出第一次运行中的细节,说明配置成功。如果不行,打开 debug 日志、检查配置的 bank ID,并确认 retain 调用确实完成。
全局配置 vs 每次调用传参
全局配置(configure())适合单一服务:一次设置后,create_hindsight_tools(bank_id=...)与memory_instructions(bank_id=...)会自动读取全局默认值(API URL、api_key、budget、max_tokens、tags、recall_tags 等),无需重复传连接参数。
每次调用传参则更安全,适合不同 Agent 需要不同记忆行为(不同 bank、不同 budget、不同标签策略)的场景。从 hindsight-integrations/strands/tests/test_config.py 可以看到,configure()每次调用都会生成并替换新的配置实例,显式参数优先于环境变量与全局配置。_resolve_client()的解析优先级为:显式client> 显式hindsight_api_url/api_key> 全局配置 > 报错(HindsightError: No Hindsight API URL configured),并且在内部创建客户端时会设置 30 秒超时与hindsight-strands/<version>的用户代理标识。
常见错误与排查
- 工具与提示词使用不同 bank:用
memory_instructions()构建的提示词来自一个 bank,而工具指向另一个 bank,导致召回与写入隔离失效; - 忘记自动注入是可选行为:
memory_instructions()必须显式加入 system prompt 才会生效; - 共享 bank 误用:应用需要严格用户隔离时却选择了共享 bank,会造成记忆串扰;
- 调用失败排查:确认 API URL 可达、
api_key正确、retain 实际完成(开启 verbose 或 debug 日志观察)。
值得一提的容错设计:memory_instructions()内部召回失败时会静默返回空字符串,避免记忆注入故障阻塞 Agent 主流程(见 hindsight-integrations/strands/tests/test_tools.py 的test_returns_empty_on_exception)。
FAQ
可以只用基于工具的记忆吗?
可以。如果你希望由 Agent 自行决定何时查询记忆,工具本身已经足够,不需要memory_instructions()。
reflect 相比 recall 多提供了什么?
Recall 返回的是原始记忆条目的编号列表;Reflect 则基于记忆综合生成一段合成回答,当需要把多条记忆合并推理时更有价值。
应该全局配置还是每次调用配置?
全局配置适合单一服务、统一行为;每次调用传参适合不同 Agent 需要不同记忆行为(不同 bank、预算、标签)的场景。
下一步
- 在 hindsight-integrations/strands/README.md 查看完整参数对照表(
create_hindsight_tools()、memory_instructions()、configure()的每个参数默认值与含义); - 阅读 hindsight-docs/docs-integrations/strands.md 获取集成文档中的更多细节;
- 阅读 cookbook/README.md 了解其他落地范例;
- 结合源码 hindsight-integrations/strands/hindsight_strands/tools.py 与测试 hindsight-integrations/strands/tests/test_tools.py 深入理解工具工厂的边界行为与容错逻辑。
【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考