Hindsight 为 Pydantic AI Agent 提供类型安全、异步原生的长期记忆:retain / recall / reflect 接入实战
2026/9/14 18:25:43 网站建设 项目流程

Hindsight 为 Pydantic AI Agent 提供类型安全、异步原生的长期记忆:retain / recall / reflect 接入实战

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

本篇技术指南围绕 Hindsight 的 Pydantic AI 官方集成展开:如何在保持 Pydantic AI 异步原生与强类型契约的前提下,通过create_hindsight_tools(...)memory_instructions(...)为 Agent 接入 retain(存储)、recall(检索)、reflect(综合)三把长期记忆工具,并深入剖析其源码实现、配置优先级与常见陷阱,帮助读者在生产环境中构建可预测、可复现的记忆流程。

为什么异步原生的记忆对 Pydantic AI 至关重要

Pydantic AI 的 Agent 运行在asyncio事件循环之上:agent.run(...)是可等待的、工具调用是被await的、模型调用是非阻塞的。其核心价值在于——单个 Agent 可以并发扇出多个任务,同时不阻塞事件循环。

记忆能力应当参与这套并发模型,而不是与之对抗。Hindsight 的 Pydantic AI 集成直接使用 Pydantic AI 的异步工具接口,因此hindsight_retainhindsight_recallhindsight_reflect与 Agent 中的其他任何工具一样被await。一次运行中的 recall 不会阻塞事件循环:当记忆调用在途时,其他被 await 的工作可以继续推进。

相反的选择——在异步 Agent 内部调用同步记忆客户端——会在每次记忆操作的持续时间内阻塞整个事件循环。在一个并发处理多个请求的服务中,一次 recall 就可能拖住无关的工作。异步原生的记忆从根本上绕开了这一问题。

拒绝线程池包装(thread-pool hacks)

当某个记忆库只提供同步客户端时,异步 Agent 中常见的变通方案是把每次调用丢到线程池执行器(executor)上。这种方式能跑,但代价明显:

  • 延迟与开销:每一次 retain 或 recall 都要跳到工作线程上,产生线程切换与上下文开销;
  • 错误不透明:异常跨越 executor 边界后,会丢失自然的异步堆栈上下文,排查困难;
  • 推理困难:调用流程不再是一条被 await 的直线,心智模型被打破。

Hindsight 的 Pydantic AI 工具端到端可等待,以上问题都不存在。从实现上看,tools.py 中三个工具闭包(hindsight_retainhindsight_recallhindsight_reflect)全部定义为async def,内部依次调用客户端 hindsight_client.py 中的aretain(第 1053 行)、arecall(第 1115 行)、areflect(第 1249 行)三个异步方法。工具直接 await 在 Agent 所在的事件循环上,心智模型保持简单:Agent 等待它的工具,而记忆只是又一个被等待的工具。

记忆工具挂载到 Pydantic AI Agent 的两个位置

有两条清晰的挂载路径,分别对应两种不同的设计意图。

工具(Tools)——将create_hindsight_tools(...)传入 Agent 的tools=[...]。这赋予 Agent 三个明确的、可等待的动作,由模型自主决定何时调用:存储事实(hindsight_retain)、搜索记忆(hindsight_recall)、基于记忆综合答案(hindsight_reflect)。是否触及记忆由模型判断。

指令(Instructions)——将memory_instructions(...)传入 Agent 的instructions=[...]。它在运行开始之前就完成记忆召回并将其注入系统提示词,因此上下文天然在场,Agent 无需先决定去取。

两者的完整组合示例如下(摘自 集成 README 与 集成文档):

from hindsight_client import Hindsight from hindsight_pydantic_ai import create_hindsight_tools, memory_instructions from pydantic_ai import Agent client = Hindsight(base_url="https://api.hindsight.vectorize.io", api_key="hsk_...") agent = Agent( "openai:gpt-4o", tools=create_hindsight_tools(client=client, bank_id="user-123"), instructions=[memory_instructions(client=client, bank_id="user-123")], ) result = await agent.run("What do you remember about my preferences?") print(result.output)

三种组合策略:

  • 工具 + 指令都用:既想要自动上下文注入,又想要显式记忆动作;
  • 只用工具:希望 Agent 自行决定何时使用记忆;
  • 只用指令:只想自动注入召回上下文,不把记忆工具暴露给模型。

如果只需要其中部分工具,include_retaininclude_recallinclude_reflect三个参数可以精确控制挂载哪些工具。这一点有测试直接验证:tests/test_tools.py 中的test_include_retain_onlytest_include_recall_onlytest_include_reflect_only分别断言只挂载对应单个工具,而test_no_tools_when_all_excluded验证三个开关全关时返回空列表。

连接 Pydantic AI 与 Hindsight

安装与连接细节由标准的 Pydantic AI 记忆接入指南 完整覆盖,核心三步:

  1. 安装依赖:pip install hindsight-pydantic-ai(依赖仅包含pydantic-ai-slim>=1.0.0hindsight-client>=0.4.0,见 pyproject.toml,不拖入全部模型提供方,保持轻量);
  2. 将客户端指向 Hindsight Cloud 或本地自托管服务器;
  3. 将工具接入你的 Agent。

本指南聚焦设计层面:为什么异步原生记忆契合 Pydantic AI、记忆工具挂载在哪里、如何让整个流程在生产环境中保持类型安全与可预测。安装一次之后,再回到这里看设计细节。

保持记忆流程类型安全且可预测

可预测性来自几处关于配置与作用域的刻意设计选择。

选定一种 bank 策略并保持稳定。recall 与 retain 都以bank_id为键。个人助手场景对每个用户使用稳定 ID;一个用户驱动多个无关系统时,按项目划分。若每次请求都轮换bank_id,即使集成本身正确,Agent 也会表现得像无状态一样——这是最常见的隐性错误来源。

配置一次,按需覆盖。你可以把 client 传给每次调用,也可以只调用一次configure(...),此后创建工具时不再传 client。从源码看,config.py 维护一个模块级全局配置_global_configconfigure()会解析HINDSIGHT_API_KEY环境变量并落库;而 tools.py 中的_resolve_client()遵循严格的优先级:显式传入的client优先,其次是hindsight_api_url/api_key参数,最后回落到全局配置。每调用级的构造参数(如budgettags)会覆盖全局配置——所以当某个值看起来没生效时,先检查是不是有 per-call 参数在"赢"。

用 tags 收敛 recall 范围。recall_tagsrecall_tags_match(取值any/all/any_strict/all_strict)能限定一次运行可以"看见"哪些记忆,从而让注入的上下文保持相关、跨运行结果可复现。测试test_recall_passes_tags验证了tagstags_match会原样透传到arecall的调用参数中。

参数参考

create_hindsight_tools()关键参数(默认值以当前仓库源码为准):

参数默认值说明
bank_id必填Hindsight 记忆库 ID
clientNone预配置的 Hindsight 客户端(优先)
hindsight_api_urlNoneAPI 地址(未传 client 时使用)
api_keyNoneAPI 密钥(未传 client 时使用)
budget"mid"recall/reflect 预算级别(low/mid/high)
max_tokens4096recall 结果的最大 token 数
tagsNoneretain 存储记忆时附加的标签
recall_tagsNone检索记忆时过滤的标签
recall_tags_match"any"标签匹配模式
include_retain/include_recall/include_reflectTrue是否挂载对应工具

memory_instructions()关键参数:

参数默认值说明
query"relevant context about the user"注入前的召回查询词
budget"low"召回预算级别(默认比工具更省,保持注入轻快)
max_results5最多注入的记忆条数
max_tokens4096recall 结果最大 token 数
prefix"Relevant memories:\n"记忆列表前的前缀文本
tags/tags_matchNone/"any"召回结果的标签过滤

一个值得注意的实现细节:memory_instructions(...)返回的是一个async可调用对象,Pydantic AI 会在每次运行时重新求值 instructions,因此即使复用message_history,注入的记忆也能保持新鲜。当召回异常时它会静默返回空字符串(见 tools.py 第 243-245 行),确保记忆失败不会阻断 Agent 主流程——这一行为由测试test_error_returns_empty_stringtest_empty_results_returns_empty_string双重锁定。

验证记忆是否真的在工作

  1. 使用稳定的bank_id运行一次 Agent,让它存储一条偏好或运行规则;
  2. 用同一个bank_id开启一次全新运行,询问刚才那条信息;
  3. 检查在任何显式工具调用发生之前,答案是否就反映了先前的记忆——如果是,说明memory_instructions(...)已成功注入召回上下文;
  4. 若没有,检查指令输出,确认 recall 使用了预期的 bank。

如果第二次运行能基于第一次运行的记忆作答,说明整套链路已经打通。需要更低层行为时,可进一步阅读客户端源码 hindsight_client.py 中aretain/arecall/areflect的完整实现。

常见错误

仍然把客户端包装进线程池

工具本身已经可等待。直接 await 才是正确做法——推进 executor 只增加开销、隐藏错误,毫无收益。

工具和指令用了不同的 bank ID

这样 recall 读取的 bank 与 retain 写入的 bank 不一致,注入的上下文看起来总是空的。请确保两处的bank_id完全一致。

指望只挂工具就能自动注入

工具只给 Agent选择调用记忆的选项。若希望在运行开始前上下文就已就位、无需工具调用,请额外添加memory_instructions(...)

忘记 per-call 覆盖优先级更高

per-call 的budgettagsmax_tokens会覆盖全局configure(...)中的值。某个设置看起来被忽略时,优先检查是否有构造参数在覆盖它。

FAQ

为什么异步原生对 Pydantic AI 尤其重要?因为 Agent 运行在事件循环上。可等待的记忆工具让记忆停留在这个循环里,一次 recall 不会阻塞无关的并发工作,流程始终是一串干净的 awaited 调用。

工具和 memory instructions 必须二选一吗?不需要。两者可以共存——既要自动注入、又要显式记忆动作时一起用;否则按 Agent 设计选择其一即可。

必须使用 Hindsight Cloud 吗?不是。自托管 Hindsight 服务器同样可行——把客户端指向本地服务即可,例如Hindsight(base_url="http://localhost:8888")(本地开发可参考 scripts/dev 下的启动脚本)。

能限制 Agent 获得的记忆工具吗?可以。在create_hindsight_tools(...)上通过include_retaininclude_recallinclude_reflect只挂载需要的工具。

进一步阅读

  • 完整的安装与接线步骤:Pydantic AI 持久记忆接入指南
  • 集成能力总览与完整参数表:Pydantic AI 集成文档
  • 集成源码与示例:hindsight_pydantic_ai 包
  • 底层异步客户端实现:aretain/arecall/areflect位于 hindsight_client.py
  • 集成测试用例:tests/test_tools.py 与 tests/test_config.py

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

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

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

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

立即咨询