用 Hindsight 为 CrewAI Agents 注入跨运行持久记忆:hindsight-crewai 集成实战指南

用 Hindsight 为 CrewAI Agents 注入跨运行持久记忆:hindsight-crewai 集成实战指南 用 Hindsight 为 CrewAI Agents 注入跨运行持久记忆hindsight-crewai 集成实战指南【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsightCrewAI 的智能体团队Crew在每次kickoff()结束后会清空所有记忆导致跨运行、跨会话的知识无法累积。hindsight-crewai通过实现 CrewAI 的Storage接口将任务输出自动写入 Hindsight 记忆引擎并在每个任务开始前自动召回相关上下文——只需三行配置即可让 Crew 真正越跑越懂。本文基于仓库中 CrewAI 集成文档 与 hindsight-crewai 源码 展开从架构原理、分步接入、配置参数到源码级实现细节带你完整落地这套持久记忆方案。Hindsight 与 CrewAI 的品牌联名图象征着两者通过记忆管线完成数据流动与集成。问题背景无状态的 CrewCrewAI 本身具备一套记忆系统——短期记忆Short-term、长期记忆Long-term、实体记忆Entity memory它们在单次kickoff()内部运行良好。然而一旦进程退出下一次运行Crew 从零开始。每条学到的事实、每个做出的决策、每个发现的实体——全部消失。这在构建反复运行的 Crew 时尤其致命研究型 Crew需要随运行次数加深对主题的理解客服型 Crew需要记住客户的历史交互规划型 Crew需要跨 Sprint 追踪决策脉络。CrewAI 内置的记忆后端RAG 存储、SQLite在设计上偏向单次运行的持久化。要获得真正跨运行、跨会话、能持续累积compounding的记忆需要一个外部记忆引擎——这正是hindsight-crewai的定位它实现了 CrewAI 的Storage接口用 Hindsight 的记忆引擎作为后端让 Crew 的记忆跨越运行、跨越天数、跨越数周持续存在。架构CrewAI 驱动Hindsight 存储整个集成链路如下CrewAI Crew └─ ExternalMemory └─ HindsightStorage (implements Storage interface) ├─ save() → Hindsight retain (extract facts, entities, relationships) ├─ search() → Hindsight recall (semantic graph temporal retrieval) └─ reset() → Hindsight delete_bank recreateCrewAI 会在每个任务完成后调用save()在每个任务开始前调用search()。你不需要手动管理记忆生命周期——CrewAI 负责驱动Hindsight 负责存储。在底层Hindsight 并非简单地存储文本。它从任务输出中抽取结构化事实facts、识别实体entities、构建知识图谱knowledge graph并在召回阶段执行多策略检索语义搜索、BM25、图谱遍历、时间排序最后经cross-encoder 重排reranking输出结果。因此你的 Crew 获得的是一个真正的记忆系统而不是一个向量倾倒场vector dump。在源码层面这一映射关系在 storage.py 的类注释中写得很清楚save(value, metadata, agent)→client.retain(bank_id, content)search(query, limit)→client.recall(bank_id, query)reset()→client.delete_bank() 按需重建Step 1 —— 启动 Hindsight 记忆服务器首先安装并启动记忆服务端pip install hindsight-allexport HINDSIGHT_API_LLM_API_KEYYOUR_OPENAI_KEY hindsight-apihindsight-api会在本机http://localhost:8888运行内置嵌入式 Postgres、向量嵌入与重排能力无需任何外部基础设施。对于希望跳过自建环境的场景也可以选择 Hindsight Cloud 托管服务并获取 API Key对应源码中 config.py 里DEFAULT_HINDSIGHT_API_URL https://api.hindsight.vectorize.io的默认云端地址。Step 2 —— 安装集成包pip install hindsight-crewai该包会自动拉入hindsight-client与crewai两个依赖。从 pyproject.toml 可以看到其依赖约束为crewai0.86.0,1.10与hindsight-client0.4.0并声明requires-python 3.10。注意版本边界crewai1.10 将Storage更名为StorageBackend需要迁移因此当前版本锁定在1.10。安装时请留意这个上游约束。Step 3 —— 接线三行接入持久记忆以下是一个 Researcher Writer 双 Agent 的完整示例来自博客原文可直接复制运行from hindsight_crewai import configure, HindsightStorage from crewai.memory.external.external_memory import ExternalMemory from crewai import Agent, Crew, Task # Point at your Hindsight instance configure(hindsight_api_urlhttp://localhost:8888) # Create agents researcher Agent( roleResearcher, goalFind accurate, detailed information on the given topic., backstoryYou are a thorough researcher who digs deep into topics., llmopenai/gpt-4o-mini, ) writer Agent( roleWriter, goalWrite clear, well-structured content based on research., backstoryYou are a technical writer who values clarity and precision., llmopenai/gpt-4o-mini, ) # Create a task research_task Task( descriptionResearch the benefits of Rust for CLI tools., expected_outputA detailed summary of Rusts strengths for CLI development., agentresearcher, ) write_task Task( descriptionWrite a short article based on the research., expected_outputA polished 3-paragraph article., agentwriter, ) # Create the crew with persistent memory crew Crew( agents[researcher, writer], tasks[research_task, write_task], external_memoryExternalMemory( storageHindsightStorage( bank_idresearch-crew, missionTrack research findings, technical comparisons, and writing preferences., ) ), ) crew.kickoff()其中HindsightStorage的构造函数定义在 storage.py支持bank_id、hindsight_api_url、api_key、budget、max_tokens、tags、recall_tags、recall_tags_match、per_agent_banks、bank_resolver、mission、verbose共 12 个参数。就这样。kickoff()之后每个任务的输出都会被 retain 到 Hindsight下一次运行同一 Crew它会在每个任务开始前召回相关的历史工作成果。Step 4 —— 再次运行知识开始复利第二次运行换一个主题research_task Task( descriptionResearch how Go compares to Rust for CLI tools., expected_outputA comparison of Go vs Rust for CLI development., agentresearcher, )此时 Researcher 已拥有第一次运行的上下文——它知道自己在 Rust 上已经调研过什么Writer 也记得上一篇的风格与结构。第三次运行research_task Task( descriptionWhich language should I pick for a new CLI tool?, expected_outputA recommendation based on all prior research., agentresearcher, )Crew 现在可以基于前两次调研成果作答。知识随运行次数持续复利累积。Step 5 —— 用 Reflect 实现更深层的综合推理CrewAI 的Storage接口只有save和search。但 Hindsight 还支持reflect——一种跨所有相关记忆进行推理的综合synthesis操作返回的不是原始事实而是经过推理的连贯答案。由于reflect无法映射到Storage接口它被暴露为一个CrewAI Toolfrom hindsight_crewai import HindsightReflectTool reflect_tool HindsightReflectTool( bank_idresearch-crew, budgetmid, reflect_contextYou are helping a development team evaluate programming languages., ) researcher Agent( roleResearcher, goalProvide deep, synthesized analysis on technical topics., backstoryYou are a senior researcher. Use the hindsight_reflect tool to review what you already know before starting new research., tools[reflect_tool], llmopenai/gpt-4o-mini, )当 Agent 调用hindsight_reflect工具时它会得到一个基于完整知识图谱综合推理后的回应而不仅仅是 top-k 的向量匹配。从 tools.py 可以看到该工具的定义namehindsight_reflect描述明确指引 Agent需要连贯总结而非原始事实时使用。其_run()方法tools.py将bank_id、query、budget以及可选的context即reflect_context透传给client.reflect()若无相关记忆可推理则返回友好的提示文本No relevant memories found to reflect on.避免 Agent 拿到空结果后误判。Per-Agent Memory Banks按 Agent 隔离记忆默认情况下所有 Agent共享同一个 bank。若希望每个 Agent 拥有隔离记忆storage HindsightStorage( bank_idresearch-crew, per_agent_banksTrue, )Researcher 会写入research-crew-researcherWriter 会写入research-crew-writer——每个 Agent 构建自己的知识库。如需完全控制命名规则可使用自定义 resolverstorage HindsightStorage( bank_idresearch-crew, bank_resolverlambda base, agent: f{base}-{agent.lower()} if agent else base, )从源码看per_agent_banks的默认实现是将 agent 角色名小写化并把空格替换为连字符后拼接到bank_id之后storage.py即f{bank_id}-{sanitized_agent}。当传入bank_resolver时它优先于per_agent_banks生效。这一点在 test_storage.py 的测试中也有验证Data Analyst会被解析为crew-data-analyst。注意search()在调用时传入agentNonestorage.py即按 Agent 隔离的 bank 主要用于写入隔离而搜索仍作用于基础 bank_id。配置参数全解全局配置与逐实例覆盖集成支持全局配置 构造函数覆盖的两级配置体系。全局配置通过configure()设置一次、处处生效from hindsight_crewai import configure configure( hindsight_api_urlhttps://api.hindsight.vectorize.io, # Hindsight Cloud (default) api_keyyour-api-key, # Or set HINDSIGHT_API_KEY env var budgetmid, # Recall budget: low/mid/high max_tokens4096, # Max tokens for recall results tags[env:prod], # Tags for stored memories recall_tags[scope:global], # Tags to filter recall recall_tags_matchany, # Tag match mode: any/all/any_strict/all_strict verboseTrue, # Enable logging )HindsightStorage的构造函数参数会覆盖全局配置storage HindsightStorage( bank_idmy-crew, budgethigh, # Override global budget max_tokens8192, # Override global max_tokens tags[team:alpha], # Override global tags )从源码看这一构造函数优先于全局配置的解析逻辑位于 storage.py对应的配置模型定义在 config.py。api_key优先取构造函数参数其次取环境变量HINDSIGHT_API_KEYconfig.py。test_storage.py 对覆盖优先与回退默认值两条路径均有断言。参数速查表参数默认值说明hindsight_api_urlhttps://api.hindsight.vectorize.ioHindsight API 地址api_keyHINDSIGHT_API_KEY环境变量API 认证密钥budgetmid召回预算级别low/mid/highmax_tokens4096召回结果最大 token 数tagsNone存储记忆时附加的标签recall_tagsNone搜索时的标签过滤条件recall_tags_matchany标签匹配模式per_agent_banksFalse是否为每个 Agent 分配独立 bankbank_resolverNone自定义(bank_id, agent) - bank_id解析函数missionNonebank 的使命描述用于指导记忆组织verboseFalse开启详细日志源码级原理save / search / reset 到底做了什么save()自动 retain 任务输出save()storage.py在每次任务完成后由 CrewAI 自动调用。实现细节解析 bank_id根据per_agent_banks/bank_resolver决定写入哪个 bank确保 bank 存在通过_ensure_bank()懒创建且同一会话内通过_created_banks集合去重storage.py构建 retain 元数据强制写入sourcecrewai若传入agent则附加agent字段CrewAI 传入的metadata字典中的每个值都会str()字符串化后并入因为 Hindsight 要求dict[str, str]——test_storage.py 专门验证了42和True会被转换为字符串调用 retainclient.retain(bank_id..., contentvalue, contextfcrewai:task_output:{agent or unknown}, metadata..., tags...)失败语义任何异常都会被包装为HindsightError(Failed to store memory: ...)抛出errors.py方便上层感知写入失败。search()召回并转换为 CrewAI 期望的格式search()storage.py在任务开始前由 CrewAI 自动调用查询串由 CrewAI 从任务描述构造。实现要点调用client.recall(bank_id, query, budget, max_tokens)若配置了recall_tags则同时透传tags与tags_match将 Hindsight 的RecallResponse转换为 CrewAI 期望的list[dict]每个结果包含context记忆文本、score、metadata三键合成分数由于 Hindsight 结果本身按相关性排序代码按1.0 - (i / total)生成递减的合成分数低于score_threshold默认 0.5即截断——test_storage.py 验证了分数严格递减且首个为 1.0富元数据被完整透传type、source_context、occurred_start、document_id、tags以及 recall 返回的原始metadata都会被并入结果的metadata字段供 Agent 理解记忆来源与时间。reset()清空并重建reset()storage.py通过delete_bank()删除整个 bank连同其中的事实、实体与心智模型若设置了mission则随后按原使命重建。它是**尽力而为best-effort**的删除失败仅记录 warning不会抛出异常——test_storage.py 明确测试了delete 失败不抛错这一语义。异步兼容专用线程池CrewAI 运行在 async 事件循环内而hindsight-client的同步方法内部会调用loop.run_until_complete()在已有事件循环运行时或跨线程访问时会失败。解决方案在 _compat.pycall_sync()将调用提交到一个最大 2 个 worker 的专用线程池每个线程持有自己的持久事件循环aiohttp session 始终绑定单一稳定的 loop并设置 60 秒超时。这就是文档中所说的通过专用线程池透明处理 async 兼容的底层实现。陷阱与边界情况1. Bank ID 冲突。若多个无关的 Crew 共用同一个bank_id它们的记忆会混在一起。请为每个 Crew 或项目使用唯一 bank ID。2. 过大的任务输出。CrewAI 会把完整任务输出传给save()。若任务产出极长文本Hindsight 虽会自行处理分块chunking但 retain 延迟会上升。建议在任务定义中设置合理的expected_output长度。3. 召回预算调优。默认budgetmid在速度与充分性之间取得平衡。延迟敏感的 Crew 用low深度分析用high。预算直接影响执行多少种检索策略以及重排的力度。4. Async 事件循环冲突。集成已通过专用线程池透明处理该问题但如果你在自定义工具里同时做 async 工作不要直接从同一个事件循环调用hindsight-client请统一使用HindsightStorage与HindsightReflectTool抽象。5. 上游版本边界。crewai1.10 改名了Storage接口hindsight-crewai当前锁定1.10。升级 CrewAI 大版本前需确认集成兼容性。小结hindsight-crewai为 CrewAI 智能体提供持久、可复利的记忆它实现 CrewAI 的Storage接口接入仅需三行代码任务完成后自动存储记忆任务开始前自动召回相关上下文HindsightReflectTool提供按需的综合推理能力让 Agent 跨越原始事实做深度分析按 Agent 隔离的 bankper-agent banks让你按需隔离或共享知识。集成已经处理了所有困难的部分异步兼容、线程安全、事实抽取、多策略检索与重排。你只需要把它指向一个 bank然后让 Crew 开始学习。延伸实践本地试跑pip install hindsight-all hindsight-crewai运行本文的完整示例标签分区记忆在 retain 时用tags、在 search 时用recall_tags按项目、环境或主题切分记忆空间可视化检视记忆本地运行hindsight-control-plane控制平面源码位于 hindsight-control-plane浏览 facts、entities 与 mental models组合 per-agent banks让专业 Agent 拥有独立记忆同时共享一个公共 bank 沉淀跨 Agent 知识深入源码完整的实现与测试可在 hindsight-integrations/crewai 目录下查阅包括 storage.py、tools.py、_compat.py 及对应的 test_storage.py、test_tools.py、test_config.py。【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考