尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

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

Hindsight 为 Pydantic AI Agent 提供类型安全、异步原生的长期记忆:retain / recall / reflect 接入实战 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_retain、hindsight_recall、hindsight_reflect与 Agent 中的其他任何工具一样被await。一次运行中的 recall 不会阻塞事件循环当记忆调用在途时其他被 await 的工作可以继续推进。相反的选择——在异步 Agent 内部调用同步记忆客户端——会在每次记忆操作的持续时间内阻塞整个事件循环。在一个并发处理多个请求的服务中一次 recall 就可能拖住无关的工作。异步原生的记忆从根本上绕开了这一问题。拒绝线程池包装thread-pool hacks当某个记忆库只提供同步客户端时异步 Agent 中常见的变通方案是把每次调用丢到线程池执行器executor上。这种方式能跑但代价明显延迟与开销每一次 retain 或 recall 都要跳到工作线程上产生线程切换与上下文开销错误不透明异常跨越 executor 边界后会丢失自然的异步堆栈上下文排查困难推理困难调用流程不再是一条被 await 的直线心智模型被打破。Hindsight 的 Pydantic AI 工具端到端可等待以上问题都不存在。从实现上看tools.py 中三个工具闭包hindsight_retain、hindsight_recall、hindsight_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_urlhttps://api.hindsight.vectorize.io, api_keyhsk_...) agent Agent( openai:gpt-4o, toolscreate_hindsight_tools(clientclient, bank_iduser-123), instructions[memory_instructions(clientclient, bank_iduser-123)], ) result await agent.run(What do you remember about my preferences?) print(result.output)三种组合策略工具 指令都用既想要自动上下文注入又想要显式记忆动作只用工具希望 Agent 自行决定何时使用记忆只用指令只想自动注入召回上下文不把记忆工具暴露给模型。如果只需要其中部分工具include_retain、include_recall、include_reflect三个参数可以精确控制挂载哪些工具。这一点有测试直接验证tests/test_tools.py 中的test_include_retain_only、test_include_recall_only、test_include_reflect_only分别断言只挂载对应单个工具而test_no_tools_when_all_excluded验证三个开关全关时返回空列表。连接 Pydantic AI 与 Hindsight安装与连接细节由标准的 Pydantic AI 记忆接入指南 完整覆盖核心三步安装依赖pip install hindsight-pydantic-ai依赖仅包含pydantic-ai-slim1.0.0与hindsight-client0.4.0见 pyproject.toml不拖入全部模型提供方保持轻量将客户端指向 Hindsight Cloud 或本地自托管服务器将工具接入你的 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参数最后回落到全局配置。每调用级的构造参数如budget、tags会覆盖全局配置——所以当某个值看起来没生效时先检查是不是有 per-call 参数在赢。用 tags 收敛 recall 范围。recall_tags与recall_tags_match取值any/all/any_strict/all_strict能限定一次运行可以看见哪些记忆从而让注入的上下文保持相关、跨运行结果可复现。测试test_recall_passes_tags验证了tags与tags_match会原样透传到arecall的调用参数中。参数参考create_hindsight_tools()关键参数默认值以当前仓库源码为准参数默认值说明bank_id必填Hindsight 记忆库 IDclientNone预配置的 Hindsight 客户端优先hindsight_api_urlNoneAPI 地址未传 client 时使用api_keyNoneAPI 密钥未传 client 时使用budgetmidrecall/reflect 预算级别low/mid/highmax_tokens4096recall 结果的最大 token 数tagsNoneretain 存储记忆时附加的标签recall_tagsNone检索记忆时过滤的标签recall_tags_matchany标签匹配模式include_retain/include_recall/include_reflectTrue是否挂载对应工具memory_instructions()关键参数参数默认值说明queryrelevant context about the user注入前的召回查询词budgetlow召回预算级别默认比工具更省保持注入轻快max_results5最多注入的记忆条数max_tokens4096recall 结果最大 token 数prefixRelevant memories:\n记忆列表前的前缀文本tags/tags_matchNone/any召回结果的标签过滤一个值得注意的实现细节memory_instructions(...)返回的是一个async可调用对象Pydantic AI 会在每次运行时重新求值 instructions因此即使复用message_history注入的记忆也能保持新鲜。当召回异常时它会静默返回空字符串见 tools.py 第 243-245 行确保记忆失败不会阻断 Agent 主流程——这一行为由测试test_error_returns_empty_string与test_empty_results_returns_empty_string双重锁定。验证记忆是否真的在工作使用稳定的bank_id运行一次 Agent让它存储一条偏好或运行规则用同一个bank_id开启一次全新运行询问刚才那条信息检查在任何显式工具调用发生之前答案是否就反映了先前的记忆——如果是说明memory_instructions(...)已成功注入召回上下文若没有检查指令输出确认 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 的budget、tags或max_tokens会覆盖全局configure(...)中的值。某个设置看起来被忽略时优先检查是否有构造参数在覆盖它。FAQ为什么异步原生对 Pydantic AI 尤其重要因为 Agent 运行在事件循环上。可等待的记忆工具让记忆停留在这个循环里一次 recall 不会阻塞无关的并发工作流程始终是一串干净的 awaited 调用。工具和 memory instructions 必须二选一吗不需要。两者可以共存——既要自动注入、又要显式记忆动作时一起用否则按 Agent 设计选择其一即可。必须使用 Hindsight Cloud 吗不是。自托管 Hindsight 服务器同样可行——把客户端指向本地服务即可例如Hindsight(base_urlhttp://localhost:8888)本地开发可参考 scripts/dev 下的启动脚本。能限制 Agent 获得的记忆工具吗可以。在create_hindsight_tools(...)上通过include_retain、include_recall、include_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),仅供参考
返回列表