LlamaIndex 持久化记忆集成指南:用 Hindsight 为 Agent 构建跨会话长期记忆
【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight
本篇技术指南讲解如何在 LlamaIndex 生态中接入 Hindsight(hindsight-llamaindex包),为 ReActAgent 等 Agent 提供跨会话的持久化长期记忆。你将掌握两条互补的接入路径——基于BaseMemory接口的全自动记忆,以及基于BaseToolSpec的 Agent 主动记忆工具(retain/recall/reflect),并学会通过 mission、tags、budget 等参数完成生产级配置。文中所有参数与行为均以仓库内实现源码与测试用例为准。
集成概览:两种互补的记忆模式
hindsight-llamaindex在 hindsight-integrations/llamaindex 目录下实现,它围绕 Hindsight 的三类核心记忆操作构建:
- retain(存储):把用户偏好、决策、项目上下文等信息写入长期记忆;
- recall(检索):根据当前问题召回相关记忆片段;
- reflect(反思):基于记忆库中的事实合成连贯、有推理的答案。
对应地,该包对外提供两种使用模式:
| 模式 | 实现类 | 驱动方式 | 适用场景 |
|---|---|---|---|
| 自动记忆 | HindsightMemory(实现 LlamaIndexBaseMemory) | 每轮对话自动 retain、自动 recall 注入上下文 | 想让 Agent "开箱即忘不掉"的最简方案 |
| 主动工具 | HindsightToolSpec(继承 LlamaIndexBaseToolSpec) | Agent 自主决定何时调用 retain/recall/reflect | 需要显式控制记忆行为的复杂 Agent |
两种模式共享同一套客户端解析逻辑(见 hindsight-integrations/llamaindex/hindsight_llamaindex/_client.py)与全局配置系统,可以混合使用。
安装与依赖
pip install hindsight-llamaindex根据 hindsight-integrations/llamaindex/pyproject.toml 的声明,包要求:
- Python 3.10+
llama-index-core >= 0.11.0hindsight-client >= 0.4.0
使用前需要有一个可访问的 Hindsight 服务端。本地自托管时通常通过Hindsight(base_url="http://localhost:8888")指定地址;若未显式提供任何地址,客户端解析逻辑会回退到默认云端地址DEFAULT_HINDSIGHT_API_URL(见 config.py),此时建议设置HINDSIGHT_API_KEY环境变量。
模式一:自动记忆(BaseMemory)
HindsightMemory是接入成本最低的方式:消息在每一轮对话中自动存储,相关记忆在每轮输入前自动召回并作为 system message 注入上下文。调用方式是在agent.run(..., memory=memory)时传入,而不是在构造 Agent 时传入:
import asyncio from hindsight_client import Hindsight from hindsight_llamaindex import HindsightMemory from llama_index.core.agent import ReActAgent from llama_index.llms.openai import OpenAI async def main(): client = Hindsight(base_url="http://localhost:8888") memory = HindsightMemory.from_client( client=client, bank_id="user-123", mission="Track user preferences and project context", ) agent = ReActAgent(tools=[], llm=OpenAI(model="gpt-4o")) response = await agent.run("Remember that I prefer dark mode", memory=memory) print(response) asyncio.run(main())自动记忆的工作机制
HindsightMemory遵循 Mem0 类 LlamaIndex 集成的经典模式:本地会话缓冲区 + 跨会话长期记忆。其生命周期由 memory.py 中的BaseMemory接口方法驱动:
| 事件 | 发生什么 |
|---|---|
| Agent 接收输入 | aget(input)向 Hindsight 召回相关记忆,以 system message 形式前置到消息列表 |
| Agent 产生输出 | aput(message)将消息 retain 到 Hindsight,供未来召回 |
| 新会话开始 | 通过 recall 获得历史记忆,本地对话缓冲区从空开始 |
源码中有几个值得注意的实现细节:
- 召回查询的自动回退:
_recall_query()在未显式传入input时,会回退到本地缓冲区中最近一条 USER 消息作为召回查询。这一点对llama_index.core.agent.workflow.ReActAgent等 workflow 式 Agent 至关重要——它们主路径调用aget()时不传input参数,若无此回退,自动召回将永远不触发(对应测试见 test_memory.py)。 - ReAct 推理痕迹清洗:
_extract_clean_content()会用正则识别 assistant 消息中的Thought:/Action:/Observation:推理痕迹,仅提取最后一个Answer:块存入记忆;若纯推理且无答案,则跳过 retain,避免把工具调用日志污染进记忆库(测试见 test_memory.py)。USER 消息则原样存储。 - 本地缓冲区裁剪:
put()/aput()在追加消息后按chat_history_limit裁剪,超出部分丢弃最旧消息;reset()仅清空本地缓冲区,不会删除 Hindsight 中的记忆。 - 故障静默降级:retain/recall 失败仅记录日志并返回空结果,绝不向上抛异常——记忆服务不可用时 Agent 依然能正常工作。
HindsightMemory.from_client()参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
client | Hindsight | 必填 | Hindsight 客户端实例 |
bank_id | str | 必填 | 记忆库(Memory Bank)ID |
mission | str | None | 记忆库使命描述,首次使用时自动创建 bank |
context | str | "llamaindex" | retain 操作的来源标签 |
budget | str | "mid" | 召回预算等级(low/mid/high) |
max_tokens | int | 4096 | 召回结果的最大 token 数 |
tags | list[str] | None | retain 操作附加的标签 |
recall_tags | list[str] | None | 召回时的标签过滤条件 |
recall_tags_match | str | "any" | 标签匹配模式 |
system_prompt | str | (内置模板) | 记忆 system message 模板,必须包含{memories}占位符 |
chat_history_limit | int | 100 | 本地缓冲区的最大消息数 |
内置 system prompt 模板为(见 memory.py):
Below are relevant memories from previous conversations: {memories} Use these memories to provide more personalized and contextual responses.召回结果会以- 记忆文本的列表形式填充{memories},再包装成SYSTEM角色消息。如果某轮召回为空,则不注入 system message(避免空模板污染上下文)。
其他构造方式:from_url 与 from_defaults
除from_client外,HindsightMemory还提供两种工厂方法:
from_url(hindsight_api_url, bank_id, api_key=..., ...):无需预先构造客户端,内部以base_url和 30 秒超时直接创建Hindsight实例(见 memory.py)。from_defaults(bank_id, ...):走与工具工厂完全一致的共享客户端解析路径——既不传client也不传 URL 时,回退到默认云端地址并读取HINDSIGHT_API_KEY环境变量(对应测试见 test_memory.py)。
模式二:Agent 主动记忆工具(BaseToolSpec)
当需要 Agent 自行判断"何时该记、何时该查"时,用HindsightToolSpec把 retain/recall/reflect 暴露成 LlamaIndex 工具。
快速开始:Tool Spec
import asyncio from hindsight_client import Hindsight from hindsight_llamaindex import HindsightToolSpec from llama_index.llms.openai import OpenAI from llama_index.core.agent import ReActAgent async def main(): client = Hindsight(base_url="http://localhost:8888") spec = HindsightToolSpec( client=client, bank_id="user-123", mission="Track user preferences", ) tools = spec.to_tool_list() agent = ReActAgent(tools=tools, llm=OpenAI(model="gpt-4o")) response = await agent.run("Remember that I prefer dark mode") print(response) asyncio.run(main())快速开始:工厂函数
from hindsight_llamaindex import create_hindsight_tools tools = create_hindsight_tools( client=client, bank_id="user-123", mission="Track user preferences", )选择要暴露的工具
工具按需裁剪有两种等价写法:
# 方式一:to_tool_list() 指定函数 tools = spec.to_tool_list(spec_functions=["recall_memory", "reflect_on_memory"]) # 方式二:工厂函数开关 tools = create_hindsight_tools( client=client, bank_id="user-123", include_retain=True, include_recall=True, include_reflect=False, )工具名与语义如下(均同时提供同步与异步实现,异步版本供 ReActAgent 等异步 Agent 使用,同步版本作为兜底,见 tools.py):
| 工具 | 作用 | 返回 |
|---|---|---|
retain_memory(content) | 将信息写入长期记忆 | 成功/失败提示字符串 |
recall_memory(query) | 检索相关记忆 | 带编号的记忆列表,无结果时返回No relevant memories found. |
reflect_on_memory(query) | 基于记忆合成有推理的答案 | 反思文本 |
三个工具都包含完整的方法名与 docstring 元数据,可作为 LLM 的 function schema;create_hindsight_tools的include_*三个开关都设为False时会返回空列表(测试见 test_tools.py)。
全局配置 configure()
通过configure()设置连接与默认值,之后创建工具/记忆时即可省略重复参数:
from hindsight_llamaindex import configure configure( hindsight_api_url="http://localhost:8888", api_key="your-api-key", # 或设置 HINDSIGHT_API_KEY 环境变量 budget="mid", tags=["source:llamaindex"], context="my-app", mission="Track user preferences", ) # 无需再传 client/url tools = create_hindsight_tools(bank_id="user-123")配置对象HindsightLlamaIndexConfig(见 config.py)支持的字段包括:hindsight_api_url、api_key、budget、max_tokens、tags、recall_tags、recall_tags_match、context、mission、verbose。配置解析遵循"显式参数 > 全局配置 > 内置默认值"的优先级链,例如configure(budget="high")后,未显式传budget的HindsightToolSpec会继承"high",而显式传入的值总是覆盖全局配置(测试见 test_tools.py)。
API key 的解析还支持纯环境变量路径:即使从未调用configure(),resolve_client()也会直接读取HINDSIGHT_API_KEY环境变量(见 _client.py),因此"只设环境变量即可跑通"是受测试保护的行为。
HindsightToolSpec()完整参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
bank_id | str | 必填 | 要操作的 Hindsight 记忆库 |
client | Hindsight | None | 预配置的 Hindsight 客户端 |
hindsight_api_url | str | None | API 地址(未提供 client 时使用) |
api_key | str | None | API key(未提供 client 时使用) |
budget | str | None→"mid" | 召回/反思预算:low、mid、high |
max_tokens | int | None→4096 | 召回结果最大 token 数 |
tags | list[str] | None | 存储记忆时附加的标签 |
recall_tags | list[str] | None | 召回结果过滤标签 |
recall_tags_match | str | None→"any" | 标签匹配:any、all、any_strict、all_strict |
retain_metadata | dict[str, str] | None | retain 操作的默认元数据 |
retain_document_id | str | None | retain 的文档 ID;未设置时自动生成{session}-{timestamp} |
retain_context | str | "llamaindex" | retain 操作的来源标签 |
recall_types | list[str] | None | 事实类型过滤:world、experience、observation |
recall_include_entities | bool | False | 召回结果是否包含实体信息 |
reflect_context | str | None | reflect 操作的额外上下文 |
reflect_max_tokens | int | None | reflect 结果最大 token(缺省时取max_tokens) |
reflect_response_schema | dict | None | 约束 reflect 输出的 JSON schema |
reflect_tags | list[str] | None | reflect 标签(缺省时取recall_tags) |
reflect_tags_match | str | None | reflect 标签匹配(缺省时取recall_tags_match) |
mission | str | None | 记忆库使命,首次使用时自动创建 bank |
自动生成的document_id实际格式为{session_id}-{uuid_hex_12},其中session_id是实例化时生成的 8 位随机串(见 tools.py),测试通过-分隔符与 12 位后缀校验该格式(见 test_tools.py)。
生产模式(Production Patterns)
记忆库使命(Bank Mission)
mission 为记忆引擎提供事实抽取的语义上下文。设置后,bank 会在首次使用时自动创建;若已存在则静默跳过创建(幂等):
# 工具模式 spec = HindsightToolSpec( client=client, bank_id="user-123", mission="Track user coding preferences, project context, and technical decisions", ) # 自动记忆模式 memory = HindsightMemory.from_client( client=client, bank_id="user-123", mission="Track user coding preferences, project context, and technical decisions", )源码层面,_ensure_bank()/_aensure_bank()在首次 retain/recall 前以create_bank(bank_id, name, mission)创建/更新 bank;创建失败(如已存在)仅记录 debug 日志并继续后续操作。这一幂等行为有测试专门保护:连续 retain 与 recall 只触发一次create_bank(见 test_memory.py、test_tools.py)。mission 也可通过configure()全局设置,工具构造时自动继承。
用 Tags 做记忆作用域隔离
在多用户、多会话共用一个服务端的场景下,用 tags 把记忆按来源/会话隔离:
spec = HindsightToolSpec( client=client, bank_id="user-123", tags=["source:chat", "session:abc"], # 应用到所有 retain recall_tags=["source:chat"], # 只召回 chat 来源的记忆 recall_tags_match="any", )标签匹配模式any/all/any_strict/all_strict控制多个标签的命中逻辑;reflect 若未单独指定reflect_tags/reflect_tags_match,会继承recall_tags/recall_tags_match(见 tools.py,测试见 test_tools.py)。
错误处理
两种模式都采用"优雅降级"策略:所有操作包裹在 try/except 中,失败时记录日志并返回友好提示(如Failed to store memory: ...),而不是抛出异常打断 Agent 主流程。这意味着即使 Hindsight 服务不可用,Agent 也能继续对话,只是暂时失去记忆能力。测试分别覆盖了 retain、recall、reflect 三种故障场景(见 test_tools.py、test_memory.py)。
工具 + 自动记忆组合使用
自动记忆负责"无感"的上下文注入,显式工具则留给 Agent 做主动反思,两者分工最合理:
from hindsight_llamaindex import create_hindsight_tools, HindsightMemory # 自动记忆负责上下文增强 memory = HindsightMemory.from_client(client=client, bank_id="user-123") # 显式工具只保留 reflect,避免与自动记忆职责重叠 tools = create_hindsight_tools( client=client, bank_id="user-123", include_retain=False, # memory 已自动处理 retain include_recall=False, # memory 已自动处理 recall include_reflect=True, # Agent 仍可显式反思 ) agent = ReActAgent(tools=tools, llm=llm) # 通过 run() 传入 memory response = await agent.run("What should I prioritize?", memory=memory)客户端解析与超时设计
工具与记忆适配器共用resolve_client()(见 hindsight-integrations/llamaindex/hindsight_llamaindex/_client.py),其解析顺序为:
- 显式传入的
client优先; - 否则取显式
hindsight_api_url/api_key; - 否则回退到
configure()的全局配置; - 否则使用
DEFAULT_HINDSIGHT_API_URL与HINDSIGHT_API_KEY环境变量。
构造客户端时还会附带hindsight-llamaindex/{version}形式的 User-Agent 标识。超时按操作类型分别设定(秒):retain 15s、recall 10s、reflect 30s、bank 创建 15s、默认 30s。这意味着复杂反思允许更长的等待时间,而高频召回查询限制在 10 秒内返回,避免拖慢 Agent 决策链路。
验证与测试
仓库为该集成提供了三层测试覆盖(目录 hindsight-integrations/llamaindex/tests):
- test_memory.py:自动记忆的构造方式、put/get 行为、本地缓冲区裁剪、ReAct 痕迹清洗、mission 幂等创建;
- test_tools.py:三个工具的调用参数透传、错误降级、配置回退链、以及与
ReActAgent+MockLLM的兼容性(工具同时具备同步_fn与异步_async_fn); - test_e2e.py:端到端联调(标记为
requires_real_llm,需要真实 Hindsight 服务与 LLM 密钥,从确定性 CI 中排除)。
其中"工具能被 ReActAgent 直接接受"与"FunctionTool.call() 能正确触发 retain/recall"两类测试(见 test_tools.py)直接证明了该集成与 LlamaIndex 生态的即插即用性。
小结
hindsight-llamaindex为 LlamaIndex Agent 提供了从"零成本自动记忆"到"完全显式控制"的完整光谱:HindsightMemory让每一轮对话自动沉淀与召回,HindsightToolSpec/create_hindsight_tools把记忆能力变成 Agent 手边的工具,configure()与客户端解析链则保证了自托管与云端两种部署形态的平滑切换。配合 mission、tags 与超时设计,你可以为多租户、多会话的生产环境构建真正"会学习"的 Agent 记忆层。进一步可阅读 hindsight-integrations/llamaindex/README.md 获取精简速览,或在 hindsight-clients/python 中了解底层hindsight-client的完整 API。
【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考