ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

使用 Hindsight 为 LangGraph 智能体构建持久化记忆:工具、节点与记忆注入完整实战指南

2026/9/13 22:24:31 拓冰建站 浏览量
使用 Hindsight 为 LangGraph 智能体构建持久化记忆:工具、节点与记忆注入完整实战指南 使用 Hindsight 为 LangGraph 智能体构建持久化记忆工具、节点与记忆注入完整实战指南【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight本文以hindsight-langgraph集成包为主线讲解如何为 LangGraph以及普通 LangChain应用接入 Hindsight 的长期记忆能力让智能体在多次运行之间记住用户的偏好与项目事实。读完本文你将掌握三种接线方式工具、记忆节点、记忆指令注入的完整写法理解 bank 的作用域策略与动态解析机制并学会如何验证记忆真正跨会话生效。快速结论安装hindsight-langgraph集成包指向 Hindsight Cloud 或本地 Hindsight API用一个稳定的 bank ID 把记忆接入 LangGraph 运行时先存储一条偏好或项目事实再开启一次全新运行确认 recall 能自动带回之前的上下文。为什么这种接线方式有效LangGraph 本身就有清晰的执行图StateGraph 边记忆的放置位置因此非常明确recall 节点运行在 LLM 节点之前负责把相关记忆注入上下文retain 节点运行在 LLM 节点之后负责把本轮对话沉淀为记忆。同时LangGraph 的RunnableConfig天然支持运行时配置传递这让“每次运行动态解析 bank ID”成为可能——无需在图中硬编码任何用户标识符就能实现按用户隔离的持久记忆。从源码看create_recall_node与create_retain_node返回的都是兼容StateGraph的异步节点函数见 hindsight-integrations/langgraph/hindsight_langgraph/nodes.py 与 create_retain_node 定义可以直接通过builder.add_node(...)注册进图。前置条件一个可运行的 LangGraph 或 LangChain 应用Python 3.10并已安装hindsight-langgraph一个稳定的用户或线程标识符用于映射到 Hindsight bank一个可用的 Hindsight 后端Hindsight Cloud 账户或自托管的 Hindsight 实例本地 API 默认端口8888。关于依赖版本pyproject.toml 明确了langchain-core0.3.0、hindsight-client0.4.0节点模式额外要求langgraph0.3.0需通过pip install hindsight-langgraph[langgraph]安装。第一步安装集成包pip install hindsight-langgraph如果使用节点模式需要在StateGraph中插入 recall/retain 节点请一并安装 langgraph 依赖pip install hindsight-langgraph[langgraph]从源码结构看hindsight_langgraph包对 langgraph 采用惰性导入create_recall_node/create_retain_node只在真正被访问时才导入若此时未安装 langgraph 会抛出明确的提示错误见 hindsight-integrations/langgraph/hindsight_langgraph/init.py。因此纯 LangChain 场景可以只装基础包无需引入 langgraph。第二步连接 LangGraph 与 Hindsight连接的核心是一个Hindsight客户端实例from hindsight_client import Hindsight client Hindsight(base_urlhttp://localhost:8888)使用 Hindsight Cloud 时将base_url设为https://api.hindsight.vectorize.io并在客户端配置中传入你的 API token。使用自托管实例时指向本地地址如http://localhost:8888。客户端解析的底层逻辑集成包内部通过resolve_client统一解析客户端见 hindsight-integrations/langgraph/hindsight_langgraph/_client.py优先级如下显式传入的client参数hindsight_api_url/api_key参数之前调用过configure()时保存的全局配置默认 URLhttps://api.hindsight.vectorize.io 环境变量HINDSIGHT_API_KEY见 config.py。也就是说即使完全不调用configure()只要设置了HINDSIGHT_API_KEY环境变量create_hindsight_tools(bank_iduser-123)也能直接工作。API key 在构造阶段是可选的——缺失时只在真正发起调用时才报错。全局配置 configure()需要统一设置连接参数和默认行为时可以调用configure()见 hindsight-integrations/langgraph/hindsight_langgraph/config.pyfrom hindsight_langgraph import configure configure( api_keyyour-api-key, # 或设置 HINDSIGHT_API_KEY 环境变量 budgetmid, tags[source:langgraph], )自托管实例的全局配置configure( hindsight_api_urlhttp://localhost:8888, )也可以在任意工厂函数上直接传hindsight_api_url进行单点覆盖tools create_hindsight_tools(bank_iduser-123, hindsight_api_urlhttp://localhost:8888)所有工厂函数都接受client、hindsight_api_url、api_key三个参数用于覆盖全局配置。核心参数含义如下参数说明默认值hindsight_api_urlHindsight API 地址https://api.hindsight.vectorize.ioapi_keyAPI key或HINDSIGHT_API_KEY环境变量Nonebudgetrecall 预算等级low/mid/highmidmax_tokensrecall 结果的最大 token 数4096tags应用于 retain 存储操作的标签Nonerecall_tags用于过滤 recall 结果的标签Nonerecall_tags_match标签匹配模式any/all/any_strict/all_strictany第三步把记忆接入运行时三种模式官方集成包提供了三种接线方式本文档主推前两种第三种适合纯 LangChain 链路完整说明见 hindsight-integrations/langgraph/README.md工具Tools——把 retain / recall / reflect 暴露为 LangChaintool由智能体自主决定何时读写记忆同时兼容 LangChain 与 LangGraph记忆节点Nodes——在图中 LLM 节点前后自动插入 recall / retain 节点无需智能体主动调用记忆指令Memory Instructions——预取记忆并拼进系统提示词适用于任何 LangChain 模型无需构图。模式一工具调用Toolscreate_hindsight_tools()会返回一组 LangChain 工具实例可直接绑定到模型或挂进ToolNode实现见 hindsight-integrations/langgraph/hindsight_langgraph/tools.pyfrom hindsight_langgraph import create_hindsight_tools from langchain_openai import ChatOpenAI from langgraph.prebuilt import create_react_agent # 设置 HINDSIGHT_API_KEY 环境变量即可完成鉴权 tools create_hindsight_tools(bank_iduser-123) agent create_react_agent( ChatOpenAI(modelgpt-4o), toolstools, ) result await agent.ainvoke( {messages: [{role: user, content: Remember that I prefer dark mode}]} )默认返回三个工具hindsight_retain存储信息、hindsight_recall检索相关记忆返回编号列表、hindsight_reflect基于记忆综合生成有推理的回答。若需要裁剪可分别用include_retain/include_recall/include_reflect开关控制仓库中的单元测试验证了“默认三个工具”以及“只保留 retain 时仅返回一个工具”等行为见 hindsight-integrations/langgraph/tests/test_tools.py。动态 bank ID 与工具如果智能体只构建一次、却要服务多个用户就省略静态bank_id改为在每次请求时从config[configurable]中解析tools create_hindsight_tools(bank_id_from_configuser_id) agent create_react_agent(ChatOpenAI(modelgpt-4o), toolstools) result await agent.ainvoke( {messages: [{role: user, content: Remember that I prefer dark mode}]}, config{configurable: {user_id: user-456}}, )传入bank_iduser-123则会把所有工具调用固定到该 bank且优先级高于bank_id_from_config。模式二记忆节点Nodes在图中 LLM 节点前后插入自动化的 recall 与 retain 节点from hindsight_client import Hindsight from hindsight_langgraph import create_recall_node, create_retain_node from langgraph.graph import StateGraph, MessagesState, START, END client Hindsight(base_urlhttp://localhost:8888) recall create_recall_node(clientclient, bank_id_from_configuser_id) retain create_retain_node(clientclient, bank_id_from_configuser_id) builder StateGraph(MessagesState) builder.add_node(recall, recall) builder.add_node(agent, agent_node) # 你的 LLM 节点 builder.add_node(retain, retain) builder.add_edge(START, recall) builder.add_edge(recall, agent) builder.add_edge(agent, retain) builder.add_edge(retain, END) graph builder.compile()recall 节点的工作方式见 nodes.py从state[messages]中取出最新一条HumanMessage作为查询调用arecall将命中的记忆格式化成一个SystemMessage内容为Relevant memories about this user:开头的编号列表追加回messages。max_results控制注入条数上限tags/tags_match/recall_types/recall_include_entities均可透传。相关行为在 test_nodes.py 中有完整覆盖。retain 节点的工作方式见 nodes.py默认只取最新一条HumanMessage文本内容存入记忆retain_humanTrue可通过retain_aiTrue同时存储 AI 回复。ToolMessage/FunctionMessage会被有意跳过避免把工具调用协议噪音存进记忆tags、metadata、document_id可附加到存储操作上。关于消息顺序的注意点默认把记忆SystemMessage追加进messages时由于MessagesState的add_messagesreducer 是追加语义该消息会出现在已有消息之后而非最前。如果 LLM 提供商要求系统消息置顶建议用output_key把记忆文本写入独立的 state 字段再在 agent 节点手动拼进系统提示词from typing import Optional from langgraph.graph import MessagesState class AgentState(MessagesState): memory_context: Optional[str] None recall create_recall_node( clientclient, bank_iduser-123, output_keymemory_context ) # 在 agent 节点中读取 state[memory_context]拼接到系统提示词头部模式三记忆指令Memory Instructions不想构图时可以用memory_instructions预取记忆并注入系统提示词任何 LangChain 模型都适用见 tools.pyfrom hindsight_langgraph import memory_instructions from langchain_openai import ChatOpenAI get_instructions memory_instructions( bank_iduser-123, base_instructionsYou are a helpful assistant., ) # 每次调用都会重新拉取记忆保持最新 instructions await get_instructions() response await ChatOpenAI(modelgpt-4o).ainvoke([ {role: system, content: instructions}, {role: user, content: What do you know about me?}, ])与 recall/retain 节点“失败即抛HindsightError”不同memory_instructions面向提示词构建路径当 Hindsight 调用失败如网络异常时它会记录日志并原样返回base_instructions让 LLM 调用继续执行实现优雅降级。关于 BaseStore 适配器指南中还提到了HindsightStore适配器用于需要 LangGraph 原生存储语义BaseStore的场景。需要说明的是当前仓库的hindsight-langgraph包hindsight-integrations/langgraph中源码结构确认提供的三种现成模式是工具、节点与记忆指令如果你需要 BaseStore 原生模式请以对应版本的包说明与集成文档为准。工具、节点、BaseStore 三者的选择原则是要智能体自主控制记忆调用选工具要自动注入与自动存储选节点要 LangGraph 原生存储语义选 BaseStore。第四步选择正确的 bank 策略只要拥有稳定的用户或租户键就应该从RunnableConfig动态解析 bank ID让记忆在多次图运行之间始终挂到正确的人身上# 动态解析每次运行从 config 中读取 recall create_recall_node(bank_id_from_configuser_id) retain create_retain_node(bank_id_from_configuser_id) result await graph.ainvoke( {messages: [{role: user, content: hello}]}, config{configurable: {user_id: user-456}}, )解析逻辑位于 nodes.py工具侧见 tools.py 的 _resolve_bank_id静态bank_id优先否则从config[configurable][bank_id_from_config]读取都拿不到时recall/retain 节点会记录告警并跳过本次记忆操作而工具会抛出HindsightError。作用域建议给团队内部单一助手使用时共享 bank 可行但绝大多数生产图应当按用户、租户或线程作用域隔离记忆——按用户隔离是最安全默认值需要更强隔离时再叠加租户或线程上下文。第五步验证记忆是否真正生效按以下步骤做一次端到端验证用测试用户运行一次图存储一条偏好或项目事实用相同的user_id放在configurable中再次调用图提出一个依赖之前事实的问题确认 recall 能把上下文带回来换一个不同的user_id重复同样的测试确认记忆按用户隔离。如果第二次运行能回答出第一次运行留下的细节说明配置成功。如果不能按顺序排查打开调试日志、核对解析到的 bank ID、确认 retain 调用确实执行完毕仓库中节点失败会抛HindsightError错误信息包含Recall node failed/Retain node failed见 test_nodes.py。仓库还提供了更高层的验证test_graph_flow.py与test_e2e.py覆盖完整的图流程与端到端集成见 hindsight-integrations/langgraph/tests可作为你本地验证的参考模板。常见错误在纯 LangChain 中绑定了工具却忘记运行工具执行循环——工具模式在 LangChain 下同样可用但工具调用需要你自己驱动第二次运行使用了不同的运行时键——bank_id_from_config读取到的键不同会静默创建一个全新 bank导致记忆“丢失”所有用户共用一个 bank——当应用真正需要按用户隔离记忆时共享 bank 会造成串记忆。FAQ应该用工具、节点还是 BaseStore想由智能体自主控制记忆调用用工具想在图中自动 recall / retain用节点想要 LangGraph 原生存储模式用BaseStore。纯 LangChain 也能用吗可以。工具模式在 LangChain 中同样可用但你需要自己处理工具执行循环。应该怎样划分 bank 作用域按用户隔离是最安全的默认值。当应用需要更强隔离时再叠加租户或线程上下文。下一步需要托管记忆后端从 Hindsight Cloud 开始阅读完整集成说明 hindsight-integrations/langgraph/README.md查阅 Python 客户端与 recall / retain API 的实现细节 hindsight-clients/python/README.md 与 hindsight_client.pyrecall见 L504、retain见 L346、reflect见 L590参考测试用例 hindsight-integrations/langgraph/tests/test_nodes.py 与 hindsight-integrations/langgraph/tests/test_tools.py加深对节点与工具行为边界的理解若使用纯 LangChain 场景优先尝试memory_instructions模式它无需 langgraph 依赖即可完成记忆注入。【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考