
使用 Hindsight 记忆构建电影推荐助手从 retain / recall / reflect 到个性化推荐的完整实战【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight本文基于 Hindsight 官方 Cookbook 中的 Movie Recommendation Assistant 配方一步步带你在本地 Docker 环境中搭建一个会记住你的电影推荐助手。它将演示 Hindsight 三个核心记忆操作——retain()存储记忆、recall()检索相关记忆、reflect()综合洞察——如何让推荐系统记住用户的喜好、看片历史与口味偏好从而随时间推移给出越来越精准的建议。读完本文你将掌握 Hindsight Python 客户端的初始化、记忆写入与检索调用方式并能将其迁移到任意带记忆的个性化应用场景。1. 配方核心一个会成长的个性化推荐器这个配方要解决的是推荐系统最常见的痛点每次对话都从零开始。传统聊天式推荐器没有长期记忆用户必须反复重复自己的偏好。而本配方借助 Hindsight让推荐助手具备三项关键能力记住用户的偏好喜欢哪些类型、导演和演员追踪看片历史看过什么、喜欢什么、不喜欢什么基于心情给上下文推荐例如用户说今晚想看轻松点的助手能结合历史偏好做出调整。这与 hindsight-docs/src/pages/cookbook/recipes/quickstart.md 中描述的 Hindsight 记忆模型一脉相承记忆被组织为World关于世界的客观事实、ExperiencesAgent 自身的经历与Observation通过反思沉淀出的复杂心智模型三类恰好对应本配方中用户偏好World/Experience 每轮对话记录Experience 口味总结Observation的数据形态。2. 前置条件与本地启动开始前需要准备两样东西OpenAI API key同时供 Hindsight 服务端用于记忆提取与反思和演示程序用于生成推荐使用Hindsight 本地实例通过 Docker 一条命令启动。在终端中启动 Hindsightexport OPENAI_API_KEYyour-openai-api-key docker run --rm -it --pull always -p 8888:8888 -p 9999:9999 \ -e HINDSIGHT_API_LLM_API_KEY$OPENAI_API_KEY \ -e HINDSIGHT_API_LLM_MODELgpt-4o-mini \ -v $HOME/.hindsight-docker:/home/hindsight/.pg0 \ ghcr.io/vectorize-io/hindsight:latest这条命令的几个关键点-p 8888:8888API 端口同时也是 MCP 端点Python 客户端默认通过http://localhost:8888连接-p 9999:9999可选的 Web 管理界面用于浏览记忆库中的文档例如访问http://localhost:9999/banks/bank_id?viewdocuments查看已存储的记忆-e HINDSIGHT_API_LLM_API_KEY把本地的OPENAI_API_KEY注入容器Hindsight 服务端需要用它做记忆提取retain 时的实体/时间/关系抽取与反思reflect 时的综合推理-e HINDSIGHT_API_LLM_MODELgpt-4o-mini指定服务端使用的 LLM 模型-v $HOME/.hindsight-docker:/home/hindsight/.pg0将嵌入式 Postgres 数据目录持久化到宿主机。不加这个参数容器停止后记忆就会丢失——这是会记住的前提。3. 安装依赖并配置 API Key在 Jupyter Notebook 中安装所需依赖!pip install -q hindsight-client openai nest-asyncio三个包的分工hindsight-clientHindsight 的官方 Python SDKopenaiOpenAI 官方 SDK用于生成推荐文本nest-asyncio在 Jupyter 中必不可少。Notebook 本身已经运行着一个 asyncio 事件循环而 hindsight-client 内部使用loop.run_until_complete()Python 默认不允许嵌套事件循环nest_asyncio通过打补丁解决这一冲突。然后配置 OpenAI API Keyimport getpass import os # Set OpenAI API key (used by both Hindsight and the demo) if not os.getenv(OPENAI_API_KEY): os.environ[OPENAI_API_KEY] getpass.getpass(Enter your OpenAI API key: ) print(API key configured!)4. 初始化客户端与记忆库初始化 Hindsight 客户端和 OpenAI 客户端import nest_asyncio nest_asyncio.apply() from openai import OpenAI from hindsight_client import Hindsight # Initialize Hindsight client (connects to local Docker instance) hindsight Hindsight( base_urlos.getenv(HINDSIGHT_BASE_URL, http://localhost:8888), ) # Initialize OpenAI client openai_client OpenAI(api_keyos.getenv(OPENAI_API_KEY)) # Unique identifier for this users memory bank USER_ID movie-fan-demo print(Clients initialized!)关键概念是USER_ID movie-fan-demoHindsight 以记忆库bank为单位隔离记忆bank_id就是这个用户的记忆容器标识。在 hindsight-clients/python/hindsight_client/hindsight_client.py 的实现中retain()会校验/创建对应 bank因此即使这个 bank 尚不存在第一次retain时也会自动就绪。多用户场景下只需为每个用户使用不同的bank_id即可实现记忆隔离——这也是本仓库 hindsight-all/hindsight/client_wrapper.py 中BanksAPI.create()所管理的能力。5. 定义三个核心辅助函数本配方用三个函数分别演示 Hindsight 的三大核心操作。先看它们的语义与 quickstart 配方一致retain()把新信息写入记忆。底层会调用 LLM 抽取关键事实、时间、实体与关系后落库recall()基于查询检索相关记忆。它在底层并行执行多种检索策略语义向量、BM25 关键词、实体/时间/因果关系的图检索、时间范围过滤后融合打分reflect()对已有记忆做更深层分析形成新的连接并沉淀为 observation观察型记忆。完整代码如下def get_recommendation(user_query: str) - str: Get a movie recommendation based on user query and remembered preferences. # Recall relevant memories about this users movie preferences memories hindsight.recall( bank_idUSER_ID, queryfmovie preferences tastes genres {user_query}, budgetmid, ) # Build context from memories memory_context if memories and memories.results: memory_context \n.join( f- {m.text} for m in memories.results[:5] ) # Generate recommendation with context system_prompt fYou are a helpful movie recommendation assistant. You remember the users preferences and past conversations to give personalized suggestions. What you know about this user: {memory_context if memory_context else No previous preferences recorded yet.} Give thoughtful, personalized recommendations based on their tastes. If they mention new preferences, acknowledge them. response openai_client.chat.completions.create( modelgpt-4o-mini, messages[ {role: system, content: system_prompt}, {role: user, content: user_query}, ], temperature0.7, max_tokens500, ) recommendation response.choices[0].message.content # Store this interaction for future context hindsight.retain( bank_idUSER_ID, contentfUser asked: {user_query}\nRecommendation given: {recommendation}, metadata{category: movie_recommendation}, ) return recommendation def store_preference(preference: str) - None: Store an explicit user preference. hindsight.retain( bank_idUSER_ID, contentfUser preference: {preference}, metadata{category: preference}, ) print(fStored preference: {preference}) def get_preference_summary() - str: Get a summary of what we know about the users movie tastes. summary hindsight.reflect( bank_idUSER_ID, querySummarize this users movie preferences, favorite genres, actors they like, and movies theyve mentioned enjoying or disliking., budgethigh, ) return summary.text if hasattr(summary, text) else str(summary) print(Helper functions defined!)这段代码体现了一个完整的记忆增强推荐闭环回忆recall()用queryfmovie preferences tastes genres {user_query}检索与该用户相关的记忆。这里把原始问题拼进查询词是为了让语义检索更好地命中口味/类型类记忆生成把召回的记忆拼进 system prompt让 LLM 基于记忆给出个性化推荐——冷启动时memory_context为空也能正常给出建议只是没有个性化依据回写retain()把用户问了什么 助手推荐了什么存回记忆库并打上metadata{category: movie_recommendation}分类标签。这样每轮对话都会沉淀为下一轮的记忆素材推荐质量随时间累积提升。5.1 参数细节budget 的取值与默认值从 hindsight-clients/python/hindsight_client/hindsight_client.py 的签名可以看到两个budget参数的默认行为recall(budgetmid)预算级别low | mid | high默认 mid控制召回阶段投入的检索/打分资源与返回结果的 token 上限reflect(budgetlow)默认 low本例显式传入high因为口味总结需要更充分的记忆覆盖。此外recall()还支持max_tokens结果 token 上限默认 4096、types按事实类型过滤 world/experience/observation、tags与tags_match按标签过滤、temporal_window时间窗口加权等参数reflect()还支持response_schema结构化输出 JSON Schema、include_facts返回based_on字段列出回答所依据的记忆、max_tokens等。本配方只用了最小子集但理解这些扩展参数有助于把同一套模式复用到更复杂的场景。5.2 metadata 的作用retain()的metadata参数是用户自定义的键值元数据见 hindsight_client.py。在本例中category用来区分对话记录与显式偏好两类记忆。虽然本配方未显式使用该字段过滤但在生产场景中可以配合recall(tags...)或客户端命名空间 API如 client_wrapper.py 的memories.list(bank_id, search_query...)做精细化查询。6. 运行演示观察跨会话学习接下来模拟一段跨越多次会话的连续对话观察助手如何逐步积累对用户口味的理解import time print( * 60) print( Movie Recommendation Assistant with Memory) print( * 60) print() # Simulate a conversation over time conversations [ Im looking for a movie to watch tonight. Any suggestions?, I really loved Inception and Interstellar. Christopher Nolan is amazing!, Can you suggest something similar to those? I like mind-bending plots., Actually, Im not in the mood for something heavy. Something lighter?, I watched The Grand Budapest Hotel last week and loved it!, What should I watch tonight? Remember what I like!, ] for i, query in enumerate(conversations, 1): print(f\n[Conversation {i}]) print(fUser: {query}) print(- * 40) response get_recommendation(query) print(fAssistant: {response}) print() time.sleep(1)这段对话设计得非常巧妙覆盖了记忆系统需要应对的各种情形冷启动第 1 轮尚无记忆助手给出泛化建议显式偏好注入第 2、5 轮用户自曝喜欢 Nolan 的作品、偏爱烧脑剧情、也爱 Wes Anderson 的《布达佩斯大饭店》——这些信息经retain进入记忆库基于历史记忆的追问第 3 轮recall命中第 2 轮的Inception/Interstellar/Nolan记忆助手应能给出mind-bending风格的片单口味迁移第 4 轮用户表示想要轻松的片子助手需要结合已知的导演/类型偏好做反常识推荐显式要求记住第 6 轮验证助手确实记住了前面所有轮次的信息。time.sleep(1)只是为了放慢节奏便于观察输出。7. 查看学习到的偏好总结用reflect()综合所有记忆让 Hindsight 总结它学到的用户口味print( * 60) print( What Ive learned about your movie tastes:) print( * 60) print(get_preference_summary())这一步与recall有本质区别recall是找出最相关的原始记忆而reflect是跨记忆做推理综合其产出observation本身会被持久化成为后续recall/reflect可检索的新记忆。执行到这里你可以看到一段类似这位用户偏爱 Christopher Nolan 的烧脑科幻片同时也欣赏 Wes Anderson 的视觉风格喜剧之类的自然语言总结——这正是 Hindsight记忆会学习的直接体现。8. 自定义查询与清理体验你自己的偏好# Try your own query! your_query Im in the mood for a sci-fi thriller # Change this! print(fYou: {your_query}) print(- * 40) print(fAssistant: {get_recommendation(your_query)})演示结束后关闭客户端连接hindsight.close() print(Client connection closed.)close()会关闭底层 HTTP 连接见 hindsight_client.py 的实现在无运行事件循环时同步关闭在异步上下文中则调度关闭任务异步代码建议改用aclose()。如果你还想彻底清理数据可以删除整个记忆库例如参考 quickstart.md 的做法通过 HTTP 删除 bank或者直接删除本机的$HOME/.hindsight-docker数据目录容器停止后。9. 从配方到生产本配方背后的源码要点最后从仓库源码层面梳理本配方背后的几个可深挖要点SDK 同步/异步双接口hindsight_client.py 中retain/recall/reflect均为同步包装底层对应aretain/arecall/areflect异步实现在 asyncio 应用如 FastAPI中应优先使用异步版本批量写入能力retain_batch()支持一次写入多条记忆hindsight_client.py并支持retain_asyncTrue后台异步处理与operation_id幂等重试——电影推荐场景若需要批量导入用户历史观影记录可直接复用命名空间客户端本仓库的 client_wrapper.py 提供了HindsightClient增强客户端通过client.banks、client.memories、client.mental_models、client.directives命名空间组织管理类 API适合在更复杂的 Agent 工程中使用召回策略细节quickstart 配方明确指出recall并行执行语义向量、关键词BM25、图实体/时间/因果链接、时间范围四种检索策略再融合这解释了为什么记得我说过喜欢 Nolan这类跨关键词表述也能被稳定召回。10. 小结本配方虽然以电影推荐为场景但recall 历史 → LLM 生成 → retain 回写的闭环是构建任何带长期记忆的个性化 Agent 的通用范式。把USER_ID换成真实用户 ID、把记忆内容换成业务数据、把推荐 prompt 换成业务指令你就能快速复刻出健身教练、学习伴侣、健康助理等同构应用仓库 cookbook 目录 下还有大量同类配方可供参考。Hindsight 的记忆即服务设计让你无需关心向量库、抽取管线与反思调度的内部实现把精力集中在业务层即可。【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考