Hindsight 集成 LiteLLM:为 100+ LLM 供应商接入持久化记忆的通用方案与版本演进解析
【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight
本文以 hindsight-docs/src/pages/changelog/integrations/litellm.md 的 LiteLLM 集成 Changelog 为时间轴骨架,结合 hindsight-integrations/litellm 的完整源码与 README,系统讲解
hindsight-litellm的安装配置、记忆注入/存储机制、reflect 与 recall 双模式、原生客户端封装,以及 0.5.x 各版本的修复与演进。读完本文,你将能够在任意 LiteLLM 支持的 LLM 应用中接入 Hindsight 持久化记忆,并理解其底层实现与调试手段。
一、hindsight-litellm 是什么:一条连接 LLM 与持久化记忆的通用通道
Hindsight 是一个"会学习的 Agent 记忆"系统,而hindsight-litellm是它面向 LiteLLM 生态的官方集成包。由于 LiteLLM 本身屏蔽了 100+ 供应商(OpenAI、Anthropic、Groq、Azure、AWS Bedrock、Google Vertex AI 等)的接口差异,hindsight-litellm因此获得"通用性"——只需几行代码,就能让任何基于 LiteLLM 的 LLM 应用拥有自动记忆注入与对话存储能力。
在仓库中,该集成位于 hindsight-integrations/litellm,包结构如下:
- hindsight_litellm/init.py:对外主入口,
configure/set_defaults/enable/disable及completion/acompletion包装器 - hindsight_litellm/config.py:
HindsightConfig与HindsightCallSettings两级配置模型 - hindsight_litellm/wrappers.py:
recall/reflect/retain直接记忆 API 与 OpenAI/Anthropic 原生客户端封装 - hindsight_litellm/callbacks.py:基于 LiteLLM
CustomLogger的回调实现与HindsightError异常 - hindsight_litellm/_async.py:事件循环管理工具
- tests:配置、注入、流式、异步与端到端测试
从 pyproject.toml 看,包当前版本为0.5.4,要求 Python >= 3.10,依赖hindsight-client>=0.4.0与litellm>=1.93.0(macOS 上为litellm>=1.91.3,<1.92),并对aiohttp、filelock、urllib3、requests等传递依赖做了安全版本下限约束。
二、版本演进时间线:0.5.0 → 0.5.4 的完整 Changelog
Changelog 页面记录了该集成从首次发布到当前版本的演进,是理解能力边界与坑位修复的最佳入口(各版本内部修正详见 hindsight-docs/src/pages/changelog/integrations/litellm.md)。
0.5.0:功能首发
0.5.0 是hindsight-litellm的首个正式实现版本,奠定了能力基调:
- 流式支持:使用 LiteLLM 包装器集成时可处理流式响应;
- 异步 retain 与 reflect:提供
aretain、areflect等异步记忆 API,同时清理了整体 API 形态; - 标签与 mission 元数据:支持将 tags 与 mission 元数据随调用下发,改善记忆的组织与检索;
- 两个关键修复:当未显式提供 Hindsight 查询时,自动使用最近一条用户消息作为查询,避免空查询导致记忆查不到(对应源码init.py 中 "custom_query > defaults.query > 最后一条 user 消息" 的解析顺序);将配置的
api_key正确传递到 Hindsight 客户端,修复鉴权缺失。
0.5.1:类型信息与依赖安全加固
- 打包内置类型信息(
py.typed),为类型化 Python 项目提供更好的 type-check 支持; - 收紧 LiteLLM 依赖版本并排除一个已确认存在安全问题的版本(对应 pyproject.toml 中针对多个 GHSA 漏洞的版本下限注释);
- 在所有 HTTP 请求上设置可识别的 User-Agent 头,改善与供应商、代理的兼容性(源码中由
USER_AGENT = f"hindsight-litellm/{_VERSION}"统一生成,见 config.py)。
0.5.2:流式对话存储修复
修复使用 LiteLLM 流式响应时的对话存储问题——即流式场景下对话内容未被正确写入记忆库。在源码层面,这一修复由_LiteLLMStreamWrapper/_LiteLLMAsyncStreamWrapper承担:它们逐块收集choices[0].delta.content,在流迭代结束(StopIteration/StopAsyncIteration)或上下文退出时统一落库,见init.py。
0.5.3:内部维护
该版本仅包含内部维护与基础设施变更,不涉及面向用户的功能改动。
0.5.4:注入行为与状态恢复修复
当前版本聚焦集成可靠性:
- 修正注入模式行为:确保
system_message与prepend_user两种注入模式行为正确; - 上下文管理器状态恢复:确保
hindsight_memory()退出后全局状态被正确还原(源码中由_restore_config原子性恢复快照实现,见 config.py); - 验证与错误处理一致性:统一校验逻辑与异常抛出路径。
三、四步接入:Quick Start 与完整配置体系
3.1 安装与最小可用示例
pip install hindsight-litellm四个步骤即可启用记忆集成:
import hindsight_litellm # Step 1: 配置静态设置 hindsight_litellm.configure( hindsight_api_url="http://localhost:8888", verbose=True, ) # Step 2: 设置默认值(bank_id 必填) hindsight_litellm.set_defaults( bank_id="my-agent", use_reflect=True, # 使用 reflect 生成综合上下文 ) # Step 3: 启用记忆集成 hindsight_litellm.enable() # Step 4: 调用时显式传入 hindsight_query(inject_memories=True 时必填) response = hindsight_litellm.completion( model="gpt-4o-mini", messages=[{"role": "user", "content": "What did we discuss about AI?"}], hindsight_query="What do I know about AI discussions?", # 必填! )注意:当inject_memories=True(默认开启)时,必须提供hindsight_query来指明要从记忆中检索什么。从源码看,若不提供,集成会自动退回使用最后一条用户消息作为查询(init.py),但显式查询能让记忆检索更有意图性。
3.2 两级配置:configure() 与 set_defaults()
配置模型刻意拆成两个函数(源码见 config.py):
configure()—— 静态连接设置,通常会话中不变:
hindsight_litellm.configure( # 必填 hindsight_api_url="http://localhost:8888", # Hindsight API 服务地址 # 可选 - 认证 api_key="your-api-key", # 不传则读取 HINDSIGHT_API_KEY 环境变量 # 可选 - 记忆行为 store_conversations=True, # 调用后存储对话 inject_memories=True, # 调用前注入相关记忆 sync_storage=False, # False = 异步存储(默认,性能更好) # True = 同步存储(阻塞,立即抛错) # 可选 - 高级 injection_mode="system_message", # 注入方式:"system_message" 或 "prepend_user" excluded_models=["gpt-3.5*"], # 按 glob 排除某些模型(如 gpt-3.5* 前缀匹配) verbose=True, # 开启详细日志与调试信息 )set_defaults()—— 每次调用的默认值,可被单次调用的hindsight_*参数覆盖:
hindsight_litellm.set_defaults( bank_id="my-agent", # 必填:记忆库 ID # 可选 - 记忆检索 budget="mid", # 预算档位:"low" / "mid" / "high" fact_types=["world", "observation"], # 过滤要检索的事实类型 max_memories=10, # 最多注入的记忆条数(None = 不限制) max_memory_tokens=4096, # 记忆上下文的 token 上限 include_entities=True, # recall 时包含实体观测 # 可选 - Reflect 模式 use_reflect=True, # 用 reflect API(综合)而非 recall(原始记忆) reflect_include_facts=False, # 调试信息中是否包含来源事实 reflect_context="I am a delivery agent finding recipients.", # 影响推理而非检索 reflect_response_schema={...}, # reflect 结构化输出的 JSON Schema # 可选 - 调试 trace=False, # 开启 trace 信息 session_id="conversation-1", # 会话 ID,映射到 Hindsight 的 document_id )单次调用覆盖:任何默认值都可通过hindsight_*前缀参数在单次调用中覆盖(如hindsight_bank_id="other-bank")。源码中_merge_call_settings会自动把hindsight_开头的 kwargs 与默认值合并(config.py),新增字段会自动生效。
3.3 用 set_bank_mission() 塑造记忆库的"学习目标"
set_bank_mission()用于告诉记忆库应该学习和记住什么,供 mental model(心智模型)综合使用:
hindsight_litellm.set_bank_mission( mission="""This agent routes customer support requests to the appropriate team. Remember which types of issues should go to which teams (billing, technical, sales). Track customer preferences for communication channels and past issue resolutions.""", name="Customer Support Router", # 可选显示名 )从源码看,这会通过hindsight_client的create_bank创建或原地更新记忆库(config.py),若未指定bank_id则回退到当前默认库,缺失时会抛出HindsightError。
四、两种记忆模式:Recall(原始检索)与 Reflect(综合上下文)
use_reflect决定注入到 prompt 中的记忆形态:
| 模式 | 行为 | 适用场景 |
|---|---|---|
Recall(use_reflect=False,默认) | 检索原始记忆事实,以编号列表注入,如1. [WORLD] User prefers Python | 需要精确、独立的单条记忆 |
Reflect(use_reflect=True) | 用 LLM 将记忆综合为连贯的上下文段落 | 追求自然、对话式的记忆上下文 |
# Recall 模式 - 原始记忆 hindsight_litellm.set_defaults(bank_id="my-agent", use_reflect=False) # 注入内容:"1. [WORLD] User prefers Python\n2. [OPINION] User dislikes Java..." # Reflect 模式 - 综合上下文 hindsight_litellm.set_defaults(bank_id="my-agent", use_reflect=True) # 注入内容:"Based on previous conversations, the user is a Python developer who..." # Reflect + context - 影响 LLM 推理,不影响检索 hindsight_litellm.set_defaults( bank_id="my-agent", use_reflect=True, reflect_context="I am a delivery agent looking for package recipients.", )源码层面的实现差异非常清晰(init.py):
- reflect 路径:调用
client.reflect(bank_id, query, budget),将单条综合文本包装为# Relevant Context from Memory\n{text}注入; - recall 路径:调用
client.recall(bank_id, query, budget, max_tokens, types),将每条结果格式化为N. [TYPE] text,再包进# Relevant Memories头部; - 若
reflect_include_facts=True,则通过hindsight_client_api底层请求带上include.facts,把based_on中的来源事实提取进调试信息。
五、记忆注入的完整生命周期:一次 completion 调用发生了什么
集成的工作流可以用下面的链路概括:
- 记忆检索(LLM 调用前):以
hindsight_query(或最后一条用户消息)为查询,调用 recall/reflect 从记忆库取回相关内容; - Prompt 注入:按
injection_mode将记忆上下文写入 system message(默认,不存在则新建一条 system 消息),或前置到最后一条 user 消息(prepend_user),实现见init.py; - LLM 调用:把增强后的消息列表交给
litellm.completion,LLM 因此能给出个性化回复; - 对话存储(LLM 调用后):将用户消息与助手回复格式化为文本,通过
retain写入记忆库(默认异步后台线程执行),Hindsight 随后从中抽取事实; - 响应返回:调用方像使用普通
completion一样拿到ModelResponse。
enable()的实现方式是猴子补丁:保存原始litellm.completion/litellm.acompletion,替换为_wrapped_completion/_wrapped_acompletion(init.py)。disable()则恢复原始函数并关闭缓存的 HTTP 连接。
严格错误处理是本集成与 LiteLLM 原生回调的关键区别:LiteLLM 的 callback 体系会静默吞掉异常,而hindsight-litellm在inject_memories=True或store_conversations=True时若操作失败,会抛出HindsightError并传播到调用方代码。enable()还会检测litellm.callbacks中是否已注册HindsightCallback——两者是互斥的注入路径,同时启用会导致记忆被注入两次。
对话存储的细节值得一提:
- 同步 vs 异步:
sync_storage=False(默认)时,存储放入 daemon 后台线程,用get_pending_storage_errors()定期检查失败;True时同步执行并立即抛错(init.py); - 会话聚合:设置
session_id后,存储前会先读取已有 document 内容再追加,实现同一会话的连续对话聚合到同一文档(init.py); - 存储清洗:格式化时会跳过 system 消息、跳过已注入的
# Relevant Memories块,并把 tool 调用规范化为ASSISTANT_TOOL_CALLS: func(args)与TOOL_RESULT: ...文本(init.py)。
六、跨供应商接入:一套代码通吃所有 LiteLLM 模型
hindsight-litellm的通用性来自 LiteLLM 的模型前缀约定。只需更换model字符串即可切换供应商,记忆逻辑完全不变:
import hindsight_litellm hindsight_litellm.configure(hindsight_api_url="http://localhost:8888") hindsight_litellm.set_defaults(bank_id="my-agent") hindsight_litellm.enable() messages = [{"role": "user", "content": "Hello!"}] # OpenAI hindsight_litellm.completion(model="gpt-4o", messages=messages, hindsight_query="greeting") # Anthropic hindsight_litellm.completion(model="claude-sonnet-4-20250514", messages=messages, hindsight_query="greeting") # Groq hindsight_litellm.completion(model="groq/llama-3.1-70b-versatile", messages=messages, hindsight_query="greeting") # Azure OpenAI hindsight_litellm.completion(model="azure/gpt-4", messages=messages, hindsight_query="greeting") # AWS Bedrock hindsight_litellm.completion(model="bedrock/anthropic.claude-3", messages=messages, hindsight_query="greeting") # Google Vertex AI hindsight_litellm.completion(model="vertex_ai/gemini-pro", messages=messages, hindsight_query="greeting")若想对特定模型跳过记忆拦截,可在configure(excluded_models=[...])中配置 glob 模式,源码中_is_model_excluded用fnmatch做大小写不敏感匹配,命中则直接透传原始调用(init.py)。
七、直接记忆 API:recall / reflect / retain 及其异步版本
即使不做 LLM 调用,也可以手动查询、综合与写入记忆——这对调试、构建自定义 UI 或预过滤记忆非常有用。
recall:查询原始记忆
from hindsight_litellm import configure, set_defaults, recall configure(hindsight_api_url="http://localhost:8888") set_defaults(bank_id="my-agent") memories = recall("what projects am I working on?", budget="mid") for m in memories: print(f"- [{m.fact_type}] {m.text}") # 输出示例: # - [world] User is building a FastAPI project # - [observation] User prefers Python over JavaScriptrecall返回RecallResponse,可像列表一样迭代;开启verbose时附带.debug调试信息(wrappers.py)。
reflect:获取综合上下文
from hindsight_litellm import configure, set_defaults, reflect configure(hindsight_api_url="http://localhost:8888") set_defaults(bank_id="my-agent") result = reflect("what do you know about the user's preferences?") print(result.text) # "Based on our conversations, the user prefers Python for backend development..." # context 仅塑造回复形态,不影响检索 result = reflect( query="what do I know about Alice?", context="I am a delivery agent looking for package recipients.", )retain:写入记忆
from hindsight_litellm import configure, set_defaults, retain, get_pending_retain_errors configure(hindsight_api_url="http://localhost:8888") set_defaults(bank_id="my-agent") # 异步 retain(默认)- 立即返回,实际存储后台进行 result = retain( content="User mentioned they're working on a machine learning project", context="Discussion about current projects", ) # result.success 立即为 True(真实错误由 get_pending_retain_errors 收集) # 同步 retain - 阻塞直至完成,出错立即抛出 result = retain( content="Critical information that must be stored", context="Important data", sync=True, ) # 周期性检查后台 retain 错误 errors = get_pending_retain_errors() if errors: for e in errors: print(f"Background retain failed: {e}")异步 API
from hindsight_litellm import arecall, areflect, aretain memories = await arecall("what do you know about me?") context = await areflect("summarize user preferences") result = await aretain(content="New information to remember")八、原生客户端封装:不经过 LiteLLM 也能接入记忆
对于直接使用官方 SDK 的场景,集成提供了 OpenAI 与 Anthropic 客户端封装,作为 LiteLLM 回调的替代路径(wrappers.py):
from openai import OpenAI from hindsight_litellm import wrap_openai client = OpenAI() wrapped = wrap_openai( client, bank_id="my-agent", hindsight_api_url="http://localhost:8888", ) response = wrapped.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": "What do you know about me?"}] )from anthropic import Anthropic from hindsight_litellm import wrap_anthropic client = Anthropic() wrapped = wrap_anthropic( client, bank_id="my-agent", hindsight_api_url="http://localhost:8888", ) response = wrapped.messages.create( model="claude-sonnet-4-20250514", max_tokens=1024, messages=[{"role": "user", "content": "Hello!"}] )封装对象同样支持hindsight_*单次调用覆盖,并实现流式收集(OpenAI 的choices[0].delta.content与 Anthropic 的content_block_delta文本在流结束时统一落库),还支持with wrap_openai(...) as client:上下文管理自动关闭连接。
九、调试与生命周期管理
调试模式:看清到底注入了什么
开启verbose=True后,可用get_last_injection_debug()检查最近一次注入的完整信息(init.py):
from hindsight_litellm import configure, set_defaults, enable, completion, get_last_injection_debug configure(hindsight_api_url="http://localhost:8888", verbose=True) set_defaults(bank_id="my-agent", use_reflect=True) enable() response = completion( model="gpt-4o-mini", messages=[{"role": "user", "content": "What's my favorite color?"}], hindsight_query="What is the user's favorite color?", ) debug = get_last_injection_debug() if debug: print(f"Mode: {debug.mode}") # "reflect" 或 "recall" print(f"Injected: {debug.injected}") # True/False print(f"Results: {debug.results_count}") print(f"Memory context:\n{debug.memory_context}") if debug.error: print(f"Error: {debug.error}")上下文管理器:临时启用记忆
from hindsight_litellm import hindsight_memory import litellm with hindsight_memory(bank_id="user-123"): response = litellm.completion( model="gpt-4", messages=[{"role": "user", "content": "Hello!"}], hindsight_query="greeting context", ) # 退出上下文后记忆集成自动关闭,且全局状态被原子还原关闭与清理
from hindsight_litellm import disable, cleanup disable() # 临时禁用记忆集成(恢复原始 litellm.completion) cleanup() # 应用退出时调用:禁用 + 关闭连接 + 重置配置函数速查表
| 分类 | 函数 | 说明 |
|---|---|---|
| 主流程 | configure/set_defaults/enable/disable/is_enabled/cleanup | 配置与启停 |
| 配置查询 | get_config/get_defaults/is_configured/reset_config/set_document_id/set_bank_mission | 配置读写 |
| 记忆操作 | recall/arecall/reflect/areflect/retain/aretain | 查询、综合、存储(含异步) |
| 错误追踪 | get_pending_retain_errors/get_pending_storage_errors | 获取并清除后台操作错误 |
| 调试 | get_last_injection_debug/clear_injection_debug | 注入信息检查 |
| 客户端封装 | wrap_openai/wrap_anthropic | 原生 SDK 记忆化 |
十、运行前提与源码验证
- Python >= 3.10,
litellm>=1.93.0(macOS 平台为>=1.91.3,<1.92,因 LiteLLM 未发布 macOS wheel),以及一个运行中的 Hindsight API 服务器; hindsight-litellm自身不内嵌 Hindsight 服务端。本地部署可参考 docker/docker-compose 下的编排文件(如local-llm、external-pg等)搭建 API 服务;- 集成行为的正确性有测试覆盖:配置合并、enable/disable 状态机、记忆注入、流式存储与异步错误收集见 tests/test_integration.py 与 tests/test_async.py,需要真实外部服务的端到端用例标记为
requires_real_llm,可从确定性 CI 桶中隔离运行(见 pyproject.toml)。
结语
从 0.5.0 的功能首发到 0.5.4 的可靠性修复,hindsight-litellm在短短四个版本内补齐了流式支持、异步 API、类型标注、依赖安全与严格错误处理。它的价值在于:用configure → set_defaults → enable → completion四步,将"自动记忆注入 + 对话自动存储"这一横切能力无侵入地注入到任何 LiteLLM 应用,同时通过hindsight_query、session_id、tags 与set_bank_mission提供了从查询意图到多租户隔离、从会话聚合到心智模型塑造的精细化控制。无论你的应用跑在 OpenAI、Anthropic 还是 Bedrock 上,记忆层都可以完全复用——这正是"通用 LLM 记忆集成"的题中之义。
【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考