Hindsight 服务架构解析:API、Worker 与 Control Plane 的部署与分工

发布时间:2026/9/15 12:51:47
Hindsight 服务架构解析:API、Worker 与 Control Plane 的部署与分工 Hindsight 服务架构解析API、Worker 与 Control Plane 的部署与分工【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsightHindsight 是一个会学习的 Agent 记忆系统Agent Memory That Learns其运行体系由三个职责清晰、既可合体运行也可独立拆分的服务组成核心记忆引擎 API 服务、后台任务处理器 Worker 服务以及面向开发调试的 Web 控制面 Control Plane。本篇指南基于官方开发文档 services.md 展开结合仓库源码、配置项与 Helm 图表完整讲解三个服务的功能边界、内部 Worker 与专用 Worker 的取舍、健康探针的正确配置方式以及 Control Plane 的独立部署方法读完即可根据吞吐量、任务类型和基础设施条件选择并落地合适的部署拓扑。三个服务一体两面按需拆合从 services.md 的定位看Hindsight 的三个服务共享同一个核心包与同一份 Docker 镜像区别仅在于入口点entry point与暴露的端口。这意味着单进程全家桶与多服务横向扩展两种形态之间切换成本极低——前者适合开发与小型生产后者面向高吞吐场景。服务默认端口角色API Service8888核心记忆引擎处理全部记忆操作Worker Service8889metrics/health后台任务处理器独立承担异步任务Control Plane9999Web 管理界面连接 API 提供可视化操作三个服务可以一起跑、也可以分开跑具体取决于你的部署需求deployment needs。其中 API 与 Worker 使用同一个包和同一个 Docker 镜像只是入口点不同Control Plane 则是独立的 Next.js 应用hindsight-control-plane/package.json 中name: vectorize-io/hindsight-control-plane由hindsight-control-planebin 命令启动。API Service核心记忆引擎API 服务是 Hindsight 的记忆引擎本体承担全部三类记忆操作Retain摄取内容抽取事实构建知识图谱Recall跨记忆的语义检索Reflect基于记忆处置disposition的答案生成。在源码层面这三类能力对应 engine/memory_engine.py 中的retain/recall/reflect系列方法并通过 engine/interface.py 中定义的抽象接口如retain_batch_async、recall_async、reflect_async暴露给上层调用。其中retain是同步便捷包装底层委托给retain_asyncmemory_engine.py#L5179-L5207生产场景建议直接使用异步版本。启动方式极其简单hindsight-api # 默认端口 8888核心特性与约束无状态可水平扩展API 服务本身不持有任何会话或本地状态所有状态全部落在 PostgreSQL 中。因此可以在负载均衡器后面起任意多个 API 实例横向扩容只受数据库容量约束。默认内嵌后台任务处理默认情况下API 进程内部会同时处理后台任务主要是 mental model consolidation心智模型整合。这意味着单进程模式下API 即一切无需额外组件。高吞吐时可拆分当吞吐量上来了可以关闭 API 的内嵌 Worker改用独立 Worker 进程承接后台任务见下文。从 api/http.py 可以看到API 应用是一个标准的 FastAPI 应用titleHindsight HTTP API版本信息、license 等元数据齐全同时支持root_pathconfig.base_path可平滑部署在反向代理子路径之下。API 命令行常用选项结合 installation.md 与仓库 CLI 实现hindsight-api支持常用启动参数hindsight-api --port 9000 # 自定义端口默认 8888 hindsight-api --host 127.0.0.1 # 仅绑定 localhost hindsight-api --workers 4 # 多 uvicorn worker 进程 hindsight-api --log-level debug # 详细日志其中--workers对应配置项HINDSIGHT_API_WORKERS默认1用于提升单机上的请求并发处理能力。Worker Service专用后台任务处理器Worker 是独立的后台任务执行进程与 API 使用同一份包与镜像只是入口点不同hindsight-worker # 默认 metrics 端口 8889Worker 的独特之处在于用 PostgreSQL 充当任务代理task broker后台操作如 consolidation、batch retain、mental model refresh以行的形式写入async_operations表见 alembic 初始 schema包含operation_id、bank_id、operation_type、statuspending/processing/completed/failed等字段Worker 通过**轮询polling**数据库来领取待处理任务因此多个 Worker 可以同时运行而互不冲突。并发安全的核心FOR UPDATE SKIP LOCKED从源码看多个 Worker 无冲突并行的关键是 worker/poller.py 中的WorkerPoller类。其claim_batch()poller.py#L524-L564使用 PostgreSQL 的FOR UPDATE SKIP LOCKED进行安全分布式领取多个 Worker 同时扫描任务队列时每行任务只会被一个 Worker 锁定领取其余 Worker 自动跳过从数据库层面根除了双跑同一任务被两个 Worker 同时执行问题。同时轮询循环对多租户 schema 采用**轮转round-robin**遍历防止某个繁忙租户饿死其他租户并优先用轻量EXISTS扫描找出有任务的活跃 schema再只对活跃 schema 执行昂贵的FOR UPDATE SKIP LOCKED领取查询。Worker 进程启动时会校验后端是否支持异步轮询memory._backend.supports_worker_poller若底层数据库后端不支持例如 Oracle独立 Worker 会直接报错退出并提示Operations run synchronously within the API processworker/main.py。此外 Worker 使用WorkerTaskBackend其submit_task为 no-op——因为任务行已由 API 侧写入Worker 的子任务如 retain 触发的 consolidation会在下一轮轮询被拾取而不是内联执行从而避免阻塞父任务。何时使用专用 Worker部署决策表原文档给出了一张非常实用的决策表它决定了内嵌 Worker与独立 Worker两种形态的取舍部署场景内嵌 WorkerAPI 内部专用 Worker独立进程开发环境✅ 简单一体化❌ 过度设计小型生产✅ 基础设施更少❌ 过度设计高吞吐❌ API 成为瓶颈✅ 可独立横向扩展长耗时任务❌ 占用 API 资源✅ 处理相互隔离简言之开发与小型生产直接使用内嵌 Worker 即可一旦任务吞吐升高或存在长耗时任务如大型文档的 retain、大批量 consolidation就应把后台执行从 API 进程中剥离出去。切换为专用 Worker 的完整操作切换的核心是关闭 API 内嵌 Worker再启动多个独立 Worker 进程# 1. 关闭 API 内嵌 Worker HINDSIGHT_API_WORKER_ENABLEDfalse hindsight-api # 2. 启动专用 Worker可并行运行多个实例 hindsight-worker --worker-id worker-1 hindsight-worker --worker-id worker-2HINDSIGHT_API_WORKER_ENABLED的语义在 config.py 中定义为环境变量默认值为trueconfig.py#L1696。配置文档明确指出把它设为false才是真正让进程停止领取后台操作的手段——这比调节维护间隔旋钮更彻底它直接静默quiesce了整个执行面。--worker-id若不指定默认取主机名hostname显式指定便于后续通过hindsight-admin decommission-worker worker-id精确管理。每个 Worker 默认最多同时运行 10 个任务HINDSIGHT_API_WORKER_MAX_SLOTS并以 500ms 间隔轮询数据库HINDSIGHT_API_WORKER_POLL_INTERVAL_MS。Worker 槽位Slots机制预留是下限不是上限Worker 的并发模型采用槽位slots设计。默认HINDSIGHT_API_WORKER_MAX_SLOTS10同时支持按操作类型**预留reserve**最少槽位保证饱和池中某类操作不被饿死。配置文档给出关键语义说明见 configuration.md#L2304-L2309..._RESERVED_SLOTS是下限floor而非上限cap。预留槽位之和不得超过WORKER_MAX_SLOTS否则启动时报ValueError。剩余容量MAX_SLOTS - 预留之和构成共享池任何类型先到先得某类型的预留槽位打满后可以溢出overflow进共享池——所以某类型的真实上限永远是WORKER_MAX_SLOTS。示例MAX_SLOTS10、CONSOLIDATION_RESERVED_SLOTS2、RETAIN_RESERVED_SLOTS3、REFRESH_MENTAL_MODEL_RESERVED_SLOTS2→ 共享池 10 - (232) 3。默认配置MAX_SLOTS10、consolidation 预留 2、其余为 0下2 个槽位始终预留给 consolidation其余 8 个构成共享池consolidation 仍可溢出到共享池最多占满 10 个。值得注意的是无论槽位由哪个池提供consolidation 的银行串行化约束同一 bank 不允许两个 consolidation 任务并发始终被保留。从源码看槽位预留的解析逻辑在 config.py 的_parse_worker_slot_reservations各操作类型的预留通过HINDSIGHT_API_WORKER_TYPE_RESERVED_SLOTS环境变量配置TYPE为CONSOLIDATION、RETAIN、FILE_CONVERT_RETAIN、REFRESH_MENTAL_MODEL、GRAPH_MAINTENANCE、IMPORT_DOCUMENTS等旧名..._MAX_SLOTS已弃用但兼容会打日志告警两者同时设置会直接报错。Worker 启动时会打印槽位预留与共享池明细worker/main.py#L243-L248。Worker 完整环境变量速查以下配置项取自 configuration.md 的 Distributed Workers 小节覆盖 Worker 的主要调优维度环境变量说明默认值HINDSIGHT_API_WORKER_ENABLED是否在 API 进程内启用内嵌 Workerfalse停止本进程领取后台任务trueHINDSIGHT_API_WORKER_ID唯一 Worker 标识hostnameHINDSIGHT_API_WORKER_POLL_INTERVAL_MS数据库轮询间隔毫秒500HINDSIGHT_API_WORKER_MAX_RETRIES任务失败前的最大重试次数3HINDSIGHT_API_WORKER_TASK_RETRY_BACKOFF_SECONDS瞬时失败重试间隔秒60HINDSIGHT_API_BACKPRESSURED_DEFER_SECONDS因存储背压被搁置任务的延迟重试时间秒不计入最大重试次数120HINDSIGHT_API_WORKER_HTTP_PORTWorker metrics/health 端口仅 Worker CLI8889HINDSIGHT_API_WORKER_MAX_SLOTS每 Worker 最大并发任务数跨所有操作类型10HINDSIGHT_API_OPERATION_RETENTION_DAYS已完成/失败/取消操作行的保留窗口0为永久保留0HINDSIGHT_API_OPERATION_CLEANUP_BATCH_SIZE每个清理周期每 schema 最多删除的过期操作行数1000HINDSIGHT_API_WORKER_CONSOLIDATION_RESERVED_SLOTSconsolidation 预留最少槽位数——下限非上限2HINDSIGHT_API_WORKER_CONSOLIDATION_BANK_PRIORITYconsolidation 的按银行调度优先级支持*通配符未设置HINDSIGHT_API_WORKER_RETAIN_RESERVED_SLOTS等各操作类型预留槽位retain、file_convert_retain、refresh_mental_model、graph_maintenance、import_documents0关于超时兜底配置文档强调了两类墙钟上限wall-clock ceilingHINDSIGHT_API_RETAIN_WALL_TIMEOUT默认 3600 秒是单个 retain 任务的死锁/卡死兜底任务一旦卡死会被取消并标记failed以便重试而不是占着 Worker 槽位直到进程重启HINDSIGHT_API_CONSOLIDATION_WALL_TIMEOUT默认 7200 秒则是无进展空闲超时——consolidation 每个批次提交都会重置计时因此大积压不会被打断只有真正停滞的任务才会被终止configuration.md#L2100。收缩 Worker 规模前的必备操作decommission-worker在缩容或移除 Worker 之前必须先释放其任务命令为hindsight-admin decommission-worker worker-id该命令的实现位于 admin/cli.py它会将async_operations表中该 Worker 名下所有statusprocessing的任务批量更新回pending状态同时清空worker_id、claimed_at让其他 Worker 可以重新拾取。命令执行前会弹确认提示--yes可跳过支持--schema指定数据库 schema。原文档明确指出当 Worker 崩溃或被移除而未优雅关闭时应使用该命令把所有正在处理的任务释放回队列。与之对应的批量版本是hindsight-admin decommission-workers释放所有 Worker 的全部 processing 任务。KubernetesHelm下的分布式 WorkerHelm 图表将 Worker 部署为StatefulSet每个 Pod 获得稳定名称如hindsight-worker-0并以此作为HINDSIGHT_API_WORKER_ID——这样 Pod 跨重启后仍能识别自己此前认领的任务。相关配置见 helm/hindsight/values.yamlworker: enabled: false # 设为 true 启用专用 Worker同时 API 内嵌 Worker 被禁用 replicaCount: 2 service: port: 8889 # 供 Prometheus 抓取的 headless Service livenessProbe: httpGet: { path: /health/live, port: 8889 } readinessProbe: httpGet: { path: /health, port: 8889 } env: HINDSIGHT_API_WORKER_POLL_INTERVAL_MS: 500 HINDSIGHT_API_WORKER_MAX_RETRIES: 3 HINDSIGHT_API_WORKER_HTTP_PORT: 8889图表在 API Deployment 中自动注入关闭内嵌 Worker 的环境变量api-deployment.yaml#L62-L66{{- if .Values.worker.enabled }} - name: HINDSIGHT_API_WORKER_ENABLED value: false {{- end }}启用方式来自 installation.md#L204-L216helm install hindsight oci://ghcr.io/vectorize-io/charts/hindsight \ --set worker.enabledtrue \ --set worker.replicaCount3安装文档特别提醒如果不用 StatefulSet 而改用普通 Deployment必须为每个副本显式设置HINDSIGHT_API_WORKER_ID——否则随机化的主机名会导致此前认领的任务变成孤儿任务。健康探针与监控端点每个 Worker以及 API 服务都暴露三组标准端点它们回答两个不同的问题指向错误的端点是把数据库小故障放大成事故的分水岭端点是否检查数据库用途/health/live否Liveness 探针/health/ready是Readiness 探针/health是Readiness——/health/ready的别名为兼容保留其行为在 worker/main.py#L85-L135 中有清晰的源码实现/health/live只要进程能处理请求就返回 200不访问数据库。因为 Hindsight 的请求处理与任务执行共享同一个事件循环一旦事件循环被阻塞调用卡死探针在超时时间内根本无法响应——这恰恰是重启就能修复的失败类型。Worker 的响应额外携带worker_id、is_shutdown、seconds_since_last_poll上一次完成认领周期距今的秒数首次轮询前为null。最后这个字段是供告警使用的它永不改变状态码因为轮询器被饱和数据库拖住时恰恰是重启会让情况更糟的场景。/health与/health/ready从连接池取连接执行SELECT 1数据库可达返回 200不可达返回 503。响应体区分db_acquire_ms与db_pool_waiting以定位连接池耗尽慢查询则指向数据库本身。/metricsPrometheus 格式指标端点OpenTelemetry 初始化失败时自动降级禁用。配置文档monitoring.md#L87-L98给出了一条重要警告永远不要把 liveness 探针指向依赖检查。liveness 失败意味着重启该进程若 liveness 检查数据库数据库一慢就会导致所有 Pod 同时重启在途请求被丢弃、已认领的异步任务带着递增的retry_count被重新入队滑向永久失败悬崖、每个重启的 Pod 还要在已经挣扎的数据库上重新预热连接池。正确做法是让 readiness 失败——把 Pod 从 Service 摘除数据库恢复后再挂回去。仓库自带的 Helm 图表已按此接线livenessProbe→/health/livereadinessProbe→/health。Control Plane可视化控制面Control Plane 是 Hindsight 的 Web 管理界面用于管理和探索你的记忆库memory banks核心能力包括浏览 agents 与记忆库memory banks探索实体entities及其关系查看摄取历史与操作记录交互式测试 recall 查询它通过连接 API 服务工作为开发与调试提供可视化界面。在 hindsight-control-plane 仓库中这是一个基于 Next.js 的应用hindsight-control-planebin 指向 bin/cli.js核心环境变量为HINDSIGHT_CP_DATAPLANE_API_URL默认回退http://localhost:8888见 src/app/api/health/route.ts。裸机独立运行npx对于裸机bare metal部署可以脱离仓库直接使用 npx 独立运行 Control Planenpx vectorize-io/hindsight-control-plane --api-url http://localhost:8888这会连接到运行中的 API 服务提供管理记忆库、探索实体、测试查询的可视化界面。常用选项如下来自 installation.md#L283-L289 与 CLI 源码选项环境变量默认值说明-p, --portPORT9999监听端口-H, --hostnameHOSTNAME0.0.0.0绑定主机名-a, --api-urlHINDSIGHT_CP_DATAPLANE_API_URLhttp://localhost:8888Hindsight API 地址HINDSIGHT_CP_ACCESS_KEY无设置后用户需输入该密钥登录 Control Plane UI容器化部署镜像方式下Control Plane 独立于 API 镜像存在ghcr.io/vectorize-io/hindsight-control-plane:latest而一体化 Docker 运行方式同时暴露 API8888与 Control Plane9999两个端口docker run -it --pull always --name hindsight --restart unless-stopped --shm-size1g -p 8888:8888 -p 9999:9999 ...启动后访问API Serverhttp://localhost:8888Control PlaneWeb UIhttp://localhost:9999部署形态小结与选型建议综合原文档与仓库证据Hindsight 的三种部署形态可归纳为单进程一体化开发/小型生产hindsight-api单命令启动内嵌 Worker 处理后台任务配 Control Plane 可视化调试。基础设施最少推荐用于开发环境与小规模生产。API 专用 Worker高吞吐/长任务生产设置HINDSIGHT_API_WORKER_ENABLEDfalse关闭内嵌 Worker启动多个hindsight-worker --worker-id id两者都挂在同一个 PostgreSQL 上。Worker 通过FOR UPDATE SKIP LOCKED安全并发认领任务通过槽位预留与共享池机制隔离不同类型任务的资源通过健康探针纳入编排体系缩容前务必执行hindsight-admin decommission-worker worker-id释放任务。KubernetesHelmworker.enabledtrue时图表自动以 StatefulSet 部署 Worker 并禁用 API 内嵌 Worker稳定 Pod 名直接充当 Worker ID/health/live与/health分别接入 liveness 与 readiness 探针/metrics供 Prometheus 抓取。无论选择哪种形态三个服务的共同底座都是 PostgreSQLAPI 无状态可横向扩展Worker 以数据库为任务代理实现分布式调度Control Plane 则始终作为 API 的外部观测窗口存在。理解了这三者同镜像、异入口、分职责的关系就能按吞吐量与任务类型灵活编排出适合自己的 Hindsight 记忆服务拓扑。【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询