Hindsight × SmolAgents 集成指南:用 retain / recall / reflect 为 Agent 赋予持久记忆
【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight
导读:Hindsight 是一个"会学习"的 Agent 记忆系统,而
hindsight-smolagents是它在 Hugging Face SmolAgents 生态中的官方集成包。本文以 hindsight-integrations/smolagents/README.md 为主线,结合仓库内 tools.py、config.py 与测试源码,完整讲解安装、三件套记忆工具(Retain 存储 / Recall 检索 / Reflect 综合)、系统提示词注入、全局配置与客户端解析优先级,让你能直接照抄代码给 SmolAgents Agent 加上跨会话的长期记忆。
一、集成包定位:给 SmolAgents 的三件记忆工具
SmolAgents 本身是无状态的:每个会话结束后,Agent 就"忘记"了之前说过的话、用户的偏好和已经做出的决定。hindsight-smolagents通过 SmolAgents 原生的Tool基类模式,把 Hindsight 的持久记忆能力封装成三个可直接挂载到 Agent 上的工具:
| 工具名 | 底层操作 | 作用 |
|---|---|---|
hindsight_retain | Hindsightretain | 把重要事实、用户偏好、决策等存储到长期记忆 |
hindsight_recall | Hindsightrecall | 按语义相似度搜索长期记忆,返回编号列表 |
hindsight_reflect | Hindsightreflect | 基于记忆综合出一个经过推理的回答,而非原始事实罗列 |
该包的核心特性(对应源码 tools.py 与 pyproject.toml):
- 原生 Tool 子类:三个类分别继承
smolagents.Tool,声明了name、description、inputs与output_type,能被 SmolAgents 的CodeAgent/ToolCallingAgent直接识别; - 记忆指令(Memory Instructions):提供
memory_instructions()在构造期预检索记忆并格式化为文本,供注入 Agent 的system_prompt; - 工厂函数:
create_hindsight_tools()一次调用创建全部(或部分)工具,且所有工具共享同一个 Hindsight 客户端实例; - 全局配置:
configure()一次配置,后续所有工具免传连接参数,也支持直接传入预构建的Hindsight客户端。
二、安装与环境要求
pip install hindsight-smolagents根据 pyproject.toml 的声明,包依赖与运行环境如下:
- Python >= 3.10(官方分类器覆盖 3.10 / 3.11 / 3.12);
- smolagents:Hugging Face 的轻量 Agent 框架,提供
Tool基类与CodeAgent; - hindsight-client >= 0.4.0:Hindsight 的 Python 客户端,提供
Hindsight类及retain/recall/reflect/create_bank等方法; - 一个可访问的 Hindsight API 服务:可以是 Hindsight Cloud,也可以是本地自托管的服务。
需要说明的是,API 连接默认指向 Hindsight Cloud(https://api.hindsight.vectorize.io),仓库中另提供自托管方案:本地开发可用 scripts/dev/start-api.sh 启动 API 服务,容器化部署可参考 docker/docker-compose 下的各编排文件(如 external-pg、pg_search 等),完整安装步骤可查阅仓库根目录 README.md。
三、快速开始:10 行代码接入记忆
from smolagents import CodeAgent, HfApiModel from hindsight_smolagents import create_hindsight_tools tools = create_hindsight_tools( bank_id="user-123", hindsight_api_url="https://api.hindsight.vectorize.io", api_key="hsk_...", # 或设置 HINDSIGHT_API_KEY 环境变量 ) agent = CodeAgent( tools=tools, model=HfApiModel(), ) agent.run("Remember that I prefer dark mode") agent.run("What are my preferences?")第一轮对话中,Agent 调用hindsight_retain把"偏好深色模式"写入记忆库;第二轮对话即使属于全新会话,Agent 也能通过hindsight_recall(或hindsight_reflect)取回该偏好,从而正确回答"我的偏好是什么"。bank_id是记忆库的唯一标识,通常按用户维度划分(如user-123),不同bank_id之间记忆相互隔离。
自托管(本地开发)
如果你在用 scripts/dev/start-api.sh 在本地运行 Hindsight,把hindsight_api_url指向本地服务即可:
tools = create_hindsight_tools( bank_id="user-123", hindsight_api_url="https://api.hindsight.vectorize.io", # 替换为你本地服务的地址 )注意:包内默认 URL 是生产环境地址,本地开发时务必显式覆盖
hindsight_api_url,否则请求会打到云端。
四、记忆指令(Memory Instructions):把记忆预注入系统提示词
SmolAgents 没有像某些框架那样的记忆自动注入机制,因此hindsight-smolagents提供memory_instructions():在 Agent 构造阶段同步执行一次 recall,把命中的记忆格式化成字符串,由你手动拼进system_prompt:
from hindsight_smolagents import create_hindsight_tools, memory_instructions tools = create_hindsight_tools( bank_id="user-123", hindsight_api_url="https://api.hindsight.vectorize.io", ) memories = memory_instructions( bank_id="user-123", hindsight_api_url="https://api.hindsight.vectorize.io", ) agent = CodeAgent( tools=tools, model=HfApiModel(), system_prompt=f"You are a helpful assistant.\n\n{memories}", )从源码看(tools.py),memory_instructions()的默认行为是:
- 使用默认查询
"relevant context about the user"与预算budget="low"执行client.recall(...); - 截取前
max_results=5条结果,用"Relevant memories:\n"前缀 + 编号列表格式化; - 任何异常都被静默吞掉并返回空字符串——记忆注入失败绝不应阻塞 Agent 启动,这是刻意的容错设计(测试 test_tools.py 中
test_returns_empty_on_exception验证了这一点); - 若未配置客户端或 URL,则抛出
HindsightError("No Hindsight API URL configured"),这是唯一会向外暴露的异常路径。
memory_instructions() 参数速查
| 参数 | 默认值 | 说明 |
|---|---|---|
bank_id | 必填 | Hindsight 记忆库 ID |
client | None | 预配置的 Hindsight 客户端(优先) |
hindsight_api_url | None | API 地址(未传 client 时使用) |
api_key | None | API 密钥(未传 client 时使用) |
query | "relevant context about the user" | 记忆注入用的检索查询 |
budget | "low" | 检索预算等级(low/mid/high) |
max_results | 5 | 注入的最大记忆条数 |
max_tokens | 4096 | 检索结果的最大 token 数 |
prefix | "Relevant memories:\n" | 记忆列表前拼接的文本 |
tags | None | 过滤检索结果的标签 |
tags_match | "any" | 标签匹配模式 |
五、三个记忆工具的原理与使用
5.1 HindsightRetainTool:存储记忆
hindsight_retain接收单个字符串输入content,把信息写入长期记忆:
from hindsight_smolagents import HindsightRetainTool retain_tool = HindsightRetainTool( bank_id="user-123", hindsight_api_url="https://api.hindsight.vectorize.io", )从 tools.py 可以看到两个值得注意的实现细节:
- 自动建库:首次调用
forward()前,工具会先调用client.create_bank(bank_id=..., name=bank_id),并通过self._created_banks集合在会话内去重,确保一个会话中只建库一次(对应测试test_retain_creates_bank/test_retain_creates_bank_only_once); - 容错建库:若建库抛异常(例如库已存在),会被捕获并视为成功,不阻断后续 retain(对应测试
test_retain_bank_already_exists)。
forward(content)最终调用client.retain(bank_id=..., content=..., tags=...),成功返回字符串"Memory stored successfully.";失败时统一包装为HindsightError(已是HindsightError的异常原样透传),并记录 error 日志。所有异常统一在 errors.py 中定义。
5.2 HindsightRecallTool:检索记忆
hindsight_recall接收查询字符串query,返回编号列表形式的记忆文本:
from hindsight_smolagents import HindsightRecallTool recall_tool = HindsightRecallTool( bank_id="user-123", hindsight_api_url="https://api.hindsight.vectorize.io", budget="mid", # 检索预算:low/mid/high max_tokens=4096, # 结果最大 token 数 recall_tags=["scope:global"], # 过滤标签 recall_tags_match="any", # 标签匹配模式 )其forward()调用client.recall(...)(对应底层客户端实现 hindsight_client.py),然后把response.results逐条格式化为"1. <text>\n2. <text>...";无结果或results为None时返回"No relevant memories found."。
值得注意的是标签匹配模式的语义(源自底层客户端的类型定义):any(OR,包含无标签项)、all(AND,包含无标签项)、any_strict(OR,排除无标签项)、all_strict(AND,排除无标签项)。hindsight-smolagents默认取"any"。
5.3 HindsightReflectTool:综合记忆
hindsight_reflect接收问题query,让 Hindsight 基于记忆库综合出有推理的回答,而非返回原始事实:
from hindsight_smolagents import HindsightReflectTool reflect_tool = HindsightReflectTool( bank_id="user-123", hindsight_api_url="https://api.hindsight.vectorize.io", budget="mid", )其forward()调用client.reflect(bank_id=..., query=..., budget=...)(底层实现见 hindsight_client.py),返回response.text;若文本为空或None,回退为"No relevant memories found."。适合"基于我了解的信息,总结一下…… / 推断一下……"这类需要综合推理的提问。
六、直接使用单个工具类
工厂函数不是唯一入口,你也可以把工具类实例直接塞进tools列表,自由组合:
from hindsight_smolagents import HindsightRetainTool, HindsightRecallTool agent = CodeAgent( tools=[ HindsightRetainTool( bank_id="user-123", hindsight_api_url="https://api.hindsight.vectorize.io", ), HindsightRecallTool( bank_id="user-123", hindsight_api_url="https://api.hindsight.vectorize.io", ), ], model=HfApiModel(), )七、按需选择工具
create_hindsight_tools()提供三个开关参数,默认全部为True。当你的场景只需要部分能力时(例如只存不查、或只查不存),显式关闭多余工具可以减小 Agent 的工具面、降低误调用概率:
tools = create_hindsight_tools( bank_id="user-123", hindsight_api_url="https://api.hindsight.vectorize.io", enable_retain=True, enable_recall=True, enable_reflect=False, # 关闭 reflect )测试 test_tools.py 验证了四种组合:默认创建 3 个工具、仅 retain、仅 recall、仅 reflect、以及全部关闭时返回空列表。三个工具各自拥有独立的name(hindsight_retain/hindsight_recall/hindsight_reflect),便于 Agent 区分调用。
八、全局配置:一次配置,处处使用
当多个 Agent 或多次创建工具时,反复传 URL / key 很繁琐。configure()把连接参数与默认值写入进程级全局配置,之后创建工具只需传bank_id:
from hindsight_smolagents import configure, create_hindsight_tools configure( hindsight_api_url="https://api.hindsight.vectorize.io", # Hindsight Cloud(默认值) api_key="your-api-key", # 或设置 HINDSIGHT_API_KEY 环境变量 budget="mid", # 检索预算:low/mid/high max_tokens=4096, # 检索结果最大 token 数 tags=["env:prod"], # 存储记忆时附加的标签 recall_tags=["scope:global"], # 检索时过滤的标签 recall_tags_match="any", # 标签匹配模式:any/all/any_strict/all_strict ) # 之后无需再传连接参数 tools = create_hindsight_tools(bank_id="user-123")从 config.py 的实现可以看到几个关键机制:
- 默认 URL:
DEFAULT_HINDSIGHT_API_URL = "https://api.hindsight.vectorize.io"; - 环境变量回退:
api_key未显式传入时,自动读取HINDSIGHT_API_KEY环境变量(test_configure_reads_api_key_from_env验证); - 配置即数据类:配置存为
HindsightSmolAgentsConfigdataclass 实例,configure()返回该实例,get_config()读取当前配置,reset_config()清空全局配置; - 重复配置覆盖:多次调用
configure()会整体替换旧配置实例,而非增量合并。
configure() 参数速查
| 参数 | 默认值 | 说明 |
|---|---|---|
hindsight_api_url | Hindsight Cloud(https://api.hindsight.vectorize.io) | Hindsight API 地址 |
api_key | HINDSIGHT_API_KEY环境变量 | 认证密钥 |
budget | "mid" | 默认检索预算等级 |
max_tokens | 4096 | 默认检索最大 token 数 |
tags | None | retain 操作默认附加的标签 |
recall_tags | None | recall 操作默认过滤的标签 |
recall_tags_match | "any" | 默认标签匹配模式 |
verbose | False | 是否启用详细日志 |
create_hindsight_tools() 参数速查
| 参数 | 默认值 | 说明 |
|---|---|---|
bank_id | 必填 | Hindsight 记忆库 ID |
client | None | 预配置的 Hindsight 客户端(优先使用) |
hindsight_api_url | None | API 地址(未传 client 时使用) |
api_key | None | API 密钥(未传 client 时使用) |
budget | "mid" | recall/reflect 预算等级(low/mid/high) |
max_tokens | 4096 | recall 结果最大 token 数 |
tags | None | retain 存储时附加的标签 |
recall_tags | None | recall 检索时过滤的标签 |
recall_tags_match | "any" | 标签匹配模式 |
enable_retain | True | 是否包含 retain 工具 |
enable_recall | True | 是否包含 recall 工具 |
enable_reflect | True | 是否包含 reflect 工具 |
九、客户端解析优先级(源码级细节)
无论走工厂函数、单个工具类还是memory_instructions(),最终都会经过 tools.py 中的_resolve_client()来解析Hindsight客户端。结合测试 test_tools.py 的用例,解析优先级可归纳为:
- 显式传入的
client优先:只要client非None,hindsight_api_url与api_key一律被忽略; - 未传 client 时,
url = 显式 hindsight_api_url or 全局配置的 url,key = 显式 api_key or 全局配置的 key; - 显式参数覆盖全局配置(如
test_explicit_url_overrides_config); - 构造客户端时:
Hindsight(base_url=url, timeout=30.0),若 key 存在则追加api_key=key; - 兜底校验:既没有 client、也没有任何 URL(包括
configure()未设置默认值时)→ 抛出HindsightError("No Hindsight API URL configured. ...")。
另外注意create_hindsight_tools()内部只解析一次客户端并让三个工具共享同一个实例(测试test_shares_client_across_tools断言三个工具的_client是同一对象),避免重复创建连接。
十、错误处理与故障排查
- 统一异常类型:所有记忆操作失败都会以
HindsightError(定义于 errors.py)向 Agent 暴露;原始异常已记录在hindsight_smolagents的 logger 中(Retain failed/Recall failed/Reflect failed前缀)。 - 记忆指令静默降级:
memory_instructions()在 recall 失败时返回空字符串,保证 Agent 正常启动。 - 建库自动容错:retain 首次调用自动建库,库已存在等异常不会阻断写入。
- 连接缺失:最常见的报错是
No Hindsight API URL configured,此时请检查是否传了client=/hindsight_api_url=,或先调用configure()。 - 本地 vs 云端:务必确认
hindsight_api_url指向的环境(本地自托管或 Hindsight Cloud)与你的api_key匹配。
十一、测试覆盖与质量保障
仓库为集成包提供了完整的单元测试:
- test_tools.py:覆盖客户端解析优先级(显式 client > 参数 > 全局配置)、三个工具的属性与
forward()行为(含编号格式化、空结果回退、tags/budget/max_tokens 透传、异常包装与日志)、工厂函数的工具组合、记忆指令的格式化与容错; - test_config.py:覆盖默认值、环境变量读取、显式参数覆盖环境变量、配置替换与重置。
运行测试(在hindsight-integrations/smolagents目录下):
pip install -e ".[dev]" pytest十二、小结
hindsight-smolagents用最符合 SmolAgents 生态的方式(原生Tool子类 + 工厂函数)把 Hindsight 的持久记忆能力封装成了开箱即用的三个工具:retain存储、recall检索、reflect综合,再辅以memory_instructions()的提示词预注入与configure()的全局配置。无论是个人助手记住用户偏好,还是业务 Agent 跨会话记住领域知识,这套集成都能在几分钟内完成接入。
更多参考:
- 集成包源码:hindsight-integrations/smolagents/hindsight_smolagents/
- 底层 Python 客户端:hindsight-client(
retain/recall/reflect/create_bank的完整签名) - 自托管部署:仓库根目录 README.md 与 docker/docker-compose 编排文件、scripts/dev/start-api.sh
【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考