Hindsight × Google ADK:为 ADK Agent 接入持久化长期记忆的两种实战模式
2026/9/15 14:57:08 网站建设 项目流程

Hindsight × Google ADK:为 ADK Agent 接入持久化长期记忆的两种实战模式

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

Hindsight 为 Google ADK(Agent Development Kit)Agent 提供持久化的长期记忆能力,官方集成包hindsight-google-adk通过自动记忆(HindsightMemoryService,实现 ADK 的BaseMemoryService显式工具(create_hindsight_tools,返回hindsight_retain/hindsight_recall/hindsight_reflect三个FunctionTool两种互补模式接入会话生命周期。本文基于仓库中 google-adk 集成文档 与 集成包源码,完整讲解安装、配置、Bank ID 推导、标签隔离与生产实践,并深入到源码与测试验证底层行为,读完即可在项目中落地可跨会话复用的 Agent 记忆。

集成原理:两种互补的接入模式

hindsight-google-adk(源码位于 hindsight-integrations/google-adk)是 Hindsight 与 Google ADK 之间的桥梁,其init.py 对外暴露了核心 API。两种模式解决的是不同层面的问题:

  • HindsightMemoryService:实现 ADK 的BaseMemoryService。将其传给Runner(memory_service=...)后,会话结束时由 Runner 自动触发记忆保留;Agent 调用search_memory时,从 Hindsight 返回匹配结果。适合"零侵入、全自动"的接入方式。
  • create_hindsight_tools(...):返回一组 ADKFunctionToolhindsight_retainhindsight_recallhindsight_reflect),由模型在单轮对话内自主决定何时调用。适合需要精细控制记忆写入/读取时机的场景。

两种模式可以同时使用:Runner(memory_service=...)负责会话结束时的自动 retain,tools=create_hindsight_tools(...)负责轮次中的 Agent 主动 recall,只要 Bank ID 对齐,两者共享同一个记忆库。

安装与环境要求

pip install hindsight-google-adk

根据 pyproject.toml 声明,运行时要求如下:

要求版本
Python>=3.10(支持 3.10 / 3.11 / 3.12)
google-adk>=2.0
hindsight-client>=0.4.0

仓库内已提供 uv.lock 锁定依赖版本,开发组件的测试依赖(pytest、pytest-asyncio、ruff)定义在pyproject.toml[dependency-groups]中。

模式一:自动记忆(BaseMemoryService)

HindsightMemoryService注入 Runner,会话结束后记忆自动落库:

import asyncio from google.adk.agents import LlmAgent from google.adk.runners import Runner from google.adk.sessions import InMemorySessionService from hindsight_google_adk import HindsightMemoryService memory = HindsightMemoryService.from_url( hindsight_api_url="https://api.hindsight.vectorize.io", api_key="hsk_...", ) agent = LlmAgent(name="assistant", model="gemini-2.0-flash") runner = Runner( app_name="my-app", agent=agent, session_service=InMemorySessionService(), memory_service=memory, ) # ... 正常使用 runner.run_async(...),记忆完全自动

源码层面的行为验证

从 memory.py 可以确认自动记忆的完整链路:

  • 会话写入add_session_to_memory(session)将会话内所有事件的文本部分按"author: text"格式逐行拼接(_events_to_document,见 memory.py),并以session.id作为document_id调用aretain写入 Hindsight;会话为空或没有文本内容时直接跳过,不产生空文档。
  • 事件级写入add_events_to_memory(...)支持增量保留单批事件,document_id形如{session_id}-{随机8位hex}(无 session_id 时前缀为events-),并自动附加session:{session_id}标签。
  • 记忆条目写入add_memory(...)将 ADK 的MemoryEntry逐条转换为 Hindsight retain 调用,authorcustom_metadata会并入 metadata。
  • 查询映射search_memory(...)调用arecall,把返回结果映射为MemoryEntryauthor="hindsight"、携带timestamp),再包装为 ADK 的SearchMemoryResponse返回。

关键的设计决策是容错:所有add_*search_memory在 Hindsight 调用失败时只记录 ERROR 日志、绝不向 Runner 抛异常,保证记忆后端故障不影响 Agent 主流程(见 memory.py)。相关行为在 tests/test_memory.py(retain 失败仅记录日志)与 tests/test_memory.py(recall 失败返回空结果)中有测试覆盖。

Bank ID 推导:记忆如何按用户隔离

默认情况下,每一对(app_name, user_id)拥有独立的 Hindsight Bank:

"{app_name}::{user_id}"

例如测试用例 test_bank_id_default_template 验证("apple", "alice")对应bank_id == "apple::alice"。该模板是HindsightAdkConfig.bank_id_template的默认值(见 config.py),并通过_bank_id()方法用str.format渲染(见 memory.py)。

可通过bank_id_template覆盖,实现不同的隔离粒度:

# 按用户隔离、跨应用共享 HindsightMemoryService.from_url( hindsight_api_url="https://api.hindsight.vectorize.io", api_key="hsk_...", bank_id_template="user::{user_id}", ) # 静态 Bank,全用户共享 HindsightMemoryService.from_url( hindsight_api_url="https://api.hindsight.vectorize.io", api_key="hsk_...", bank_id_template="my-shared-bank", )

模板中必须含{app_name}{user_id}占位符才能动态推导;静态字符串则让所有用户/应用落同一个 Bank。

模式二:显式工具(FunctionTool)

当希望模型在轮次内自主决定读写记忆时,使用工具工厂:

from google.adk.agents import LlmAgent from hindsight_google_adk import create_hindsight_tools tools = create_hindsight_tools( bank_id="user-123", hindsight_api_url="https://api.hindsight.vectorize.io", api_key="hsk_...", ) agent = LlmAgent( name="assistant", model="gemini-2.0-flash", tools=tools, )

Agent 会获得三个工具(可用include_retain/include_recall/include_reflect开关裁剪,默认全部开启,见 tools.py):

  • hindsight_retain(content)— 将信息存入长期记忆(调用aretain),成功返回"Memory stored successfully."
  • hindsight_recall(query)— 搜索记忆并返回编号列表,例如"1. ...\n2. ...",无结果时返回友好提示"No relevant memories found."
  • hindsight_reflect(query)— 基于记忆综合生成连贯答案(调用areflect),返回response.text

工具实现细节(tools.py)值得注意:

  • 三个工具均为异步函数,通过FunctionTool(...)包装后可直接传给LlmAgent(tools=[...])
  • hindsight_recall支持recall_types(事实类型过滤:world/experience/observation)与recall_include_entities(结果附带实体信息);
  • hindsight_reflect额外支持reflect_context(补充上下文)、reflect_response_schema(JSON Schema 约束输出格式)、reflect_tags/reflect_tags_match(默认回退到recall_tags/recall_tags_match);
  • 与自动模式不同:显式工具在失败时会将底层异常包装为HindsightError抛出(见 tools.py),让 Agent 感知失败并做出反应。测试见 tests/test_tools.py。

全局配置 configure():统一默认值

在应用启动时调用一次configure(...),后续所有HindsightMemoryService.from_url()/create_hindsight_tools()都会以全局配置作为回退默认值:

from hindsight_google_adk import configure configure( hindsight_api_url="https://api.hindsight.vectorize.io", api_key=None, # 未提供时回退到 HINDSIGHT_API_KEY 环境变量 budget="mid", max_tokens=4096, bank_id_template="{app_name}::{user_id}", )

其实现位于 config.py:configure()会把参数解析为HindsightAdkConfig存入模块级全局变量,api_key为空时读取HINDSIGHT_API_KEY环境变量;HindsightMemoryService构造与create_hindsight_tools内部分别通过get_config()回退取值(见 memory.py 与 tools.py)。测试中还提供了reset_config()用于清理全局状态。

注意:configure()返回HindsightAdkConfig且全局只保留一份,多次调用会覆盖。若同时显式传参(如from_url(url=..., api_key=...)),显式参数优先于全局配置。

配置参考(Configuration Reference)

完整参数语义如下(默认值与文档 google-adk.md 及 config.py 一致):

参数默认值说明
hindsight_api_urlhttps://api.hindsight.vectorize.ioHindsight API 地址,默认指向 Cloud
api_keyHINDSIGHT_API_KEY环境变量Hindsight Cloud 的 Bearer Token
bank_id_template"{app_name}::{user_id}"由 ADK 的app_name/user_id推导 Bank ID 的格式串
budget"mid"召回预算等级:low/mid/high
max_tokens4096召回结果的最大 token 数
tagsNone追加到每条 retain 文档的标签;app:<name>user:<id>总是被自动加入
recall_tagsNone追加到 recall 查询的标签;user:<id>总是被自动加入
recall_tags_match"any"标签匹配模式:any/all/any_strict/all_strict
missionNone若设置,首次使用时以该事实提取使命幂等创建 Bank
context"google-adk"附加到 retain 内容的来源标签(provenance)
verboseFalse是否启用详细日志(源码中新增参数)

客户端解析与超时

HindsightMemoryService.from_url()create_hindsight_tools()共用 resolve_client() 完成客户端解析:优先级为显式client=> 显式 URL/Key > 全局配置;未配置任何 URL 时抛出HindsightError。客户端还会附带hindsight-google-adk/{版本}的 User-Agent,并为不同操作预设了超时(retain 15s、recall 10s、reflect 30s、bank 15s、默认 30s,见 _client.py)。

生产实践

按环境给记忆打标签

HindsightMemoryService.from_url( hindsight_api_url="https://api.hindsight.vectorize.io", api_key="hsk_...", tags=["env:prod"], recall_tags=["env:prod"], )

app:user:标签总会叠加在自定义标签之上。回忆侧总是附加user:<id>,从而天然隔离不同用户——测试 test_user_tag_added_to_recall 验证了 recall 时user:aliceenv:prod同时出现在标签中。

自托管 Hindsight(Self-hosted)

HindsightMemoryService.from_url( hindsight_api_url="http://localhost:8888", )

未认证的本地服务无需api_key

自动记忆 + 显式工具组合

runner = Runner( app_name="my-app", agent=agent, session_service=InMemorySessionService(), memory_service=HindsightMemoryService.from_url(...), # 会话结束自动 retain ) # 同时给 Agent 挂上 mid-turn 主动 recall 的工具 tools = create_hindsight_tools(bank_id="my-app::user-123", ...)

自动 retain 与 Agent 驱动的 mid-turn recall 各司其职;只要bank_id_template推导出的 Bank 与工具传入的bank_id一致,二者共享同一记忆库。更多细节可参阅集成包自身的 README 与 变更记录。

总结

hindsight-google-adk为 Google ADK 开发者提供了"自动记忆"与"显式工具"两条互补路径:前者通过实现BaseMemoryService实现零侵入的会话级记忆持久化与查询,后者通过三个FunctionTool让模型在轮次内自主读写记忆。二者共享同一套以bank_id_template驱动的 Bank 隔离机制与app:/user:标签体系,既支持开箱即用的 Hindsight Cloud,也支持http://localhost:8888的自托管部署,且所有自动记忆操作对 Runner 完全容错。结合源码中的超时配置、标签匹配模式与mission幂等建库等细节,开发者可以按生产需求精细调整记忆的写入、隔离与检索行为。

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

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

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

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

立即咨询