news 2026/9/14 12:00:24

hindsight-all Python 编程式 API 指南:在本地进程内一键启动 Hindsight 记忆服务

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
hindsight-all Python 编程式 API 指南:在本地进程内一键启动 Hindsight 记忆服务

hindsight-all Python 编程式 API 指南:在本地进程内一键启动 Hindsight 记忆服务

【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight

本指南围绕 Hindsight 仓库中的 hindsight-all 编程式 API(Python) 文档展开,系统讲解如何通过hindsight-all包在本地 Python 代码中直接拉起一个完整的 Hindsight 记忆服务——无需部署任何服务器基础设施。读完本文,你将掌握HindsightServer(显式生命周期)与HindsightEmbedded(自动托管)两种使用方式、Profile 数据隔离机制、四大 API 命名空间(banks / mental_models / directives / memories)的完整用法,以及 daemon 崩溃自动恢复等底层原理,可直接在测试、脚本和长期运行的应用中落地。

为什么需要 hindsight-all:一套安装包,零基础设施启动

Hindsight 是一个“会学习的 Agent 记忆系统”(Agent Memory That Learns)。要把它接入自己的应用,通常需要部署 API 服务、准备数据库、再引入客户端——这在实际开发中是一笔不小的开销。hindsight-all的目的就是把这套流程压缩成一个安装包和几行 Python 代码。

从仓库中的 hindsight-all/pyproject.toml 可以看到它的依赖构成(当前版本 0.9.2):

  • hindsight-api-slim[all]==0.9.2—— Hindsight API 服务端(精简版,含全部可选依赖)
  • hindsight-client>=0.0.7—— 官方 Python HTTP 客户端
  • hindsight-embed==0.9.2—— 嵌入式 daemon 管理模块

因此pip install hindsight-all一次安装,就能同时获得 API 服务、嵌入式 PostgreSQL 存储和类型化 Python 客户端三件套。

需要注意的是,这里的“嵌入式”并不意味着服务跑在你的 Python 进程内存里。相反,hindsight-all/hindsight/init.py 导出的两个核心入口HindsightServerHindsightEmbedded,其底层 daemon 都以独立的 OS 进程运行在127.0.0.1上,你的代码通过 HTTP 与该进程通信。也就是说:Python 进程崩溃不影响记忆数据,记忆服务随时可以被其他进程、CLI 工具复用。

安装与依赖

pip install hindsight-all

如果你的运行环境没有 LLM API 密钥,也可以选择本地推理方案:

pip install "hindsight-all[local-llm]"

该可选依赖通过hindsight-api-slim[local-llm]引入本地模型支持。仓库的测试套件还声明了test可选依赖(pytestpytest-asyncio),用于运行 hindsight-all/tests 下的集成测试。

环境要求为python >= 3.11。如果你已经有运行中的 Hindsight 服务器、只需要一个客户端,那么应当直接使用 Python Client(hindsight-client),无需引入整套嵌入式依赖。

两种 API 形态:HindsightServer 与 HindsightEmbedded

hindsight-all暴露两类主要 API,二者最终都通过同一个HindsightClientHTTP 接口与同一个底层 daemon 通信,区别只在于服务器进程由谁管理

API生命周期管理适用场景
HindsightServer显式:进入上下文即启动,退出即关闭测试、短生命周期脚本,要求确定性的启停
HindsightEmbedded自动:首次调用启动,跨调用复用,空闲自动退出长期运行的应用,不想关心生命周期

下面分别深入讲解。

HindsightServer:显式生命周期(上下文管理器)

HindsightServer作为上下文管理器使用,进入with块时立即启动服务,退出时干净关闭,非常适合测试和短脚本:

import os from hindsight import HindsightServer, HindsightClient with HindsightServer( llm_provider="openai", llm_model="gpt-4o-mini", llm_api_key=os.environ["OPENAI_API_KEY"], ) as server: client = HindsightClient(base_url=server.url) client.retain(bank_id="my-bank", content="Alice works at Google") results = client.recall(bank_id="my-bank", query="What does Alice do?") for r in results: print(r.text) answer = client.reflect(bank_id="my-bank", query="Tell me about Alice") print(answer.text) # Server is stopped here

从源码看,hindsight-all/hindsight/server.py 中的Server类提供了完整的生命周期实现:

  • 启动start(timeout=30.0)在一个后台守护线程(threading.Thread(daemon=True))中创建MemoryEngine、构建 FastAPI 应用(create_app)、并启动 uvicorn 服务器。启动后通过socket.create_connection轮询确认端口已就绪才返回,超时则抛出RuntimeError
  • 端口:默认通过_find_free_port()自动选择一个空闲端口,无需手动指定;也可以通过port参数固定端口。
  • 停止stop()uvicorn.Server.should_exit置为 True,等待线程退出(默认最多 10 秒),并完成MemoryEngine.close()清理。
  • URLserver.url属性返回http://{host}:{port},默认绑定127.0.0.1

Server的完整构造参数(也是start_server便捷函数接受的参数)如下:

参数默认值说明
db_url"pg0"数据库 URL;"pg0"表示使用嵌入式 PostgreSQL
llm_provider"groq"LLM 提供商:groqopenaiollamageminianthropiclmstudio
llm_api_key""LLM 提供商 API 密钥
llm_model"openai/gpt-oss-120b"使用的模型名
llm_base_urlNone可选的 LLM API 自定义 base URL
host"127.0.0.1"服务绑定地址
portNone绑定端口,默认自动选择空闲端口
mcp_enabledFalse是否启用 MCP 服务器
log_level"info"Server)/"warning"start_serveruvicorn 日志级别

除了上下文管理器,你还可以手动管理生命周期:先用start_server(...)Server(...).start()启动,用完调用server.stop()(hindsight-all/README.md 的 Quick Start 展示了这种写法)。

HindsightEmbedded:自动托管,开箱即用

HindsightEmbedded是 Hindsight 在 Python 中使用的最简方式。它自动管理后台 daemon:首次调用时启动,之后跨调用复用同一个 daemon,空闲后自动退出;你也可以调用close(stop_daemon=True)显式停止。

from hindsight import HindsightEmbedded import os # Server starts automatically on first call client = HindsightEmbedded( profile="myapp", # Profile for data isolation llm_provider="openai", llm_model="gpt-4o-mini", llm_api_key=os.environ["OPENAI_API_KEY"], ) # Use immediately - no manual server management needed client.retain(bank_id="my-bank", content="Alice works at Google") results = client.recall(bank_id="my-bank", query="What does Alice do?") # Server continues running (auto-stops after idle timeout) # Or explicitly stop it: client.close(stop_daemon=True)

HindsightEmbedded的构造参数非常灵活(见 hindsight-all/hindsight/embedded.py)。关键设计是:你显式传入的设置才会被转发给 daemon,未指定的参数全部交给 daemon 按序解析——先查 Profile 的.env文件,再查父进程环境变量,最后使用 daemon 自身默认值。这意味着你可以构造一个不带凭据的客户端,让它直接复用某个已配置好凭据的 Profile 或 shell 环境,而不会被占位符覆盖(源码注释中引用了 issue #3253 的设计约束)。

重要参数说明:

参数默认值说明
profile"default"Profile 名称,用于数据隔离
llm_providerNone(继承)LLM 提供商,省略则继承;服务器默认"openai"
llm_api_keyNone(继承)API 密钥,省略则继承;显式传""表示明确运行在无密钥环境(如本地免鉴权服务)
llm_modelNone(继承)模型名,省略则继承,服务器按已解析的提供商选默认模型
llm_base_urlNone自定义 LLM API base URL
database_urlNone数据库 URL 覆盖项,默认使用 Profile 专属 pg0
idle_timeout已弃用并被忽略daemon 不再因空闲自动退出,保留参数仅为兼容旧调用方
log_levelNone(继承)daemon 日志级别,daemon 默认"info"
uiFalse是否随 daemon 一同启动控制平面 Web UI
ui_portNoneUI 端口,默认daemon_port + 10000
ui_hostname"0.0.0.0"UI 绑定主机名

内部实现上,HindsightEmbedded通过get_embed_manager()(来自hindsight-embed包)获得DaemonEmbedManager,其配置以HINDSIGHT_API_LLM_PROVIDERHINDSIGHT_API_LLM_API_KEYHINDSIGHT_API_LLM_MODEL等环境变量键的形式传给 daemon。

什么是 Profile?

Profile 是一个隔离的 Hindsight 环境。每个 Profile 拥有:

  • 自己的嵌入式 PostgreSQL 数据库(存储在~/.pg0/instances/hindsight-embed-{profile}/);
  • 自己的 API 服务器进程。

因此可以用不同 Profile 来隔离开发/生产环境、不同应用,甚至不同用户的数据。仓库中的集成测试 hindsight-all/tests/test_embedded.py 中的test_embedded_profile_isolation验证了这一点:两个不同 Profile 使用相同的bank_id各自写入内容,互相看不到对方的数据。

HindsightEmbeddedhindsight-embedCLI 共享同一套 daemon 管理接口和 Profile 存储,因此可以放心地与 CLI 工具混用同一份 Profile 数据。

何时选择哪种?

使用场景选择
测试、短生命周期脚本、需要确定性启停HindsightServer(上下文管理器)
长期运行的应用、首次使用自动启动、不想管理生命周期HindsightEmbedded
已有运行中的 Hindsight 服务器直接使用 hindsight-client

API 命名空间:组织化的银行、心智模型、指令与记忆操作

HindsightEmbeddedHindsightClient都暴露了组织化的 API 命名空间,用于银行(Bank)管理、心智模型(Mental Models)、指令(Directives)和记忆(Memories):

from hindsight import HindsightEmbedded import os embedded = HindsightEmbedded( profile="myapp", llm_provider="openai", llm_api_key=os.environ["OPENAI_API_KEY"], ) # Core operations embedded.retain(bank_id="test", content="Hello") results = embedded.recall(bank_id="test", query="Hello") # Bank management embedded.banks.create(bank_id="test", name="Test Bank", mission="Help users") embedded.banks.set_mission(bank_id="test", mission="Updated mission") embedded.banks.delete(bank_id="test") # Mental models embedded.mental_models.create( bank_id="test", name="User Preferences", content="User prefers dark mode" ) models = embedded.mental_models.list(bank_id="test") # Directives embedded.directives.create( bank_id="test", name="Response Style", content="Be concise and friendly" ) directives = embedded.directives.list(bank_id="test") # List memories memories = embedded.memories.list(bank_id="test", type="world", limit=50)

这些命名空间由 hindsight-all/hindsight/api_namespaces.py 中的四个类实现(BanksAPIMentalModelsAPIDirectivesAPIMemoriesAPI),在 hindsight-all/hindsight/client_wrapper.py 中还有一套绑定在HindsightClient上的同名实现。每个命名空间的方法签名与底层客户端方法一一对应:

  • bankscreate(bank_id, name=None, mission=None, disposition=None)delete(bank_id)set_mission(bank_id, mission)set_disposition(bank_id, disposition)HindsightClient版本另有list())。
  • mental_modelscreate(bank_id, name, content, tags=None)list(bank_id, tags=None, detail=None)get(bank_id, mental_model_id)refresh(bank_id, mental_model_id)update(...)delete(...)。其中list()默认只返回元数据,需要正文时传detail="content"
  • directivescreate(bank_id, name, content, tags=None)list(bank_id, tags=None)get(bank_id, directive_id)update(...)delete(...)
  • memorieslist(bank_id, type=None, search_query=None, limit=100, offset=0),支持按记忆类型过滤、文本搜索与分页。

为什么推荐走命名空间而不是直接访问 client?

关键原因在于daemon 崩溃的优雅处理。命名空间的每个方法调用都会先执行_ensure_started()(见 hindsight-all/hindsight/embedded.py):它会检查 daemon 是否仍在运行,若已崩溃则自动清理过期客户端并重启 daemon,然后才发起真实 API 调用:

# ✅ GOOD - Uses API namespace (daemon restarts handled) embedded.banks.create(bank_id="test", name="Test") # ❌ BAD - Direct client access (daemon crashes NOT handled) client = embedded.client client.create_bank(bank_id="test", name="Test") # Fails if daemon crashed

这一点有测试直接背书:hindsight-all/tests/test_embedded_namespaces.py 中的test_daemon_restart_handling模拟了“daemon 崩溃→清除客户端→再次调用”的场景,验证命名空间方法能透明地重启 daemon 并继续工作;test_multiple_calls_ensure_daemon_each_time则确认每次命名空间调用都会执行_ensure_started()。此外 hindsight-all/tests/test_embedded.py 的test_embedded_daemon_crash_recovery通过client._manager.stop(profile)模拟真实崩溃,随后下一次retain调用自动重启 daemon 并成功写入数据。

需要注意的是,HindsightEmbedded的普通方法代理(__getattr__)同样会在调用前执行_ensure_started(),所以直接调用client.retain(...)也具有崩溃恢复能力;真正危险的是先通过embedded.client拿到底层Hindsight客户端引用再保存下来使用——该引用在 daemon 崩溃后不会自动刷新。

完整工作流示例:从建库到反思

结合仓库测试 hindsight-all/tests/test_embedded.py 中的test_embedded_complete_workflow,一个典型的完整工作流如下:

client = HindsightEmbedded(profile="myapp", llm_provider="openai", llm_api_key=os.environ["OPENAI_API_KEY"]) # 1. 创建记忆银行 client.create_bank(bank_id="assistant", name="Test Assistant", mission="Help with programming tasks") # 2. 存储单条记忆 client.retain(bank_id="assistant", content="User prefers Python for data analysis.", context="Programming preferences") # 3. 批量存储记忆 client.retain_batch(bank_id="assistant", items=[ {"content": "User works with pandas and numpy."}, {"content": "User likes matplotlib for visualization."}, {"content": "User is interested in machine learning with scikit-learn."}, ]) # 4. 检索记忆 results = client.recall(bank_id="assistant", query="What tools does the user prefer?", max_tokens=2000) # 5. 反思(基于记忆生成上下文回答) answer = client.reflect(bank_id="assistant", query="What programming tools should I recommend?", budget="low") # 6. 列出记忆 client.list_memories(bank_id="assistant", limit=10) client.close()

retain/recall/reflect的完整参数参考(无论客户端以何种方式获得,行为一致)见 Python Client 页面:例如retain支持contexttimestampdocument_idmetadataretain_asyncrecall支持typesmax_tokensbudgetlow/mid/high)、include_chunksreflect支持budgetcontext;所有方法都有以a前缀开头的异步版本(aretainarecallareflect等)。

进阶:上下文管理器与 UI 控制平面

HindsightEmbedded同样支持上下文管理器,退出时自动调用close()

from hindsight import HindsightEmbedded with HindsightEmbedded(profile="myapp") as client: client.retain(bank_id="alice", content="Alice loves AI") # Daemon managed automatically

如果你希望记忆服务同时附带可视化控制平面,可以设置ui=True(并可选ui_portui_hostname)。测试 hindsight-all/tests/test_embedded.py 中的test_embedded_ui_flag验证了:启用 UI 后,首次调用会同时拉起 daemon 和 UI,且 UI 的健康检查端点({ui_url}/api/health)返回status: "ok"dataplane.status: "connected",说明数据平面已成功连接。

最佳实践小结

  • 测试与短脚本用HindsightServer上下文管理器:确定性的启停让测试互不干扰,server.url可直接注入HindsightClient
  • 应用代码用HindsightEmbedded:懒启动 + 跨调用复用 + 空闲自动退出,配合命名空间获得 daemon 崩溃自愈能力。
  • 用 Profile 做环境隔离:dev/prod、不同应用或不同用户各用一个 Profile,数据库与服务器进程完全隔离(存储于~/.pg0/instances/hindsight-embed-{profile}/)。
  • 优先走 API 命名空间embedded.banksembedded.mental_models等),避免长期保存embedded.client裸引用。
  • 无密钥本地服务:将llm_api_key显式传"",可清除继承的 API 密钥,配合本地 LLM 服务(如ollamalmstudio)使用。
  • 省略参数即继承:构造HindsightEmbedded时未显式给出的配置会按“Profile.env→ 父进程环境变量 → daemon 默认值”的顺序解析,适合复用已配置好的环境。

从安装到生产级接入,hindsight-all用一套依赖覆盖了 API 服务、嵌入式 PostgreSQL 与类型化客户端,让“Agent 记忆”真正成为应用里随手可用的本地基础设施。

【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 11:58:05

安卓与嵌入式低功耗开发全栈解析:从PMIC寄存器到PowerHAL契约

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 11:56:59

UART通信实操指南:从电平波形到寄存器配置

1. 这不是“讲义”,而是一份UART通信的实操手记你打开开发板手册,第一页就写着“支持UART通信”;调试时串口助手一闪而过几行乱码;Linux下dmesg | grep tty突然冒出个ttyUSB0却连不上;用FT232R芯片焊好电路&#xff0c…

作者头像 李华
网站建设 2026/9/14 11:54:39

AI编曲5大技巧:从清唱到专业级音乐制作

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华