给 Hermes 装上本地记忆:Hindsight 自部署完整记录

前言

上一篇聊了怎么用云端 Hindsight 给 Hermes 加上记忆能力,三步搞定,确实方便。

但用了一段时间后,两个问题越来越明显。

一是数据全在别人那里。
每次对话产生的记忆、提取的实体、构建的知识图谱,全部上传到 Vectorize 的云端服务器。
对于日常闲聊可能无所谓,但涉及项目细节、技术方案、个人偏好这些信息,心里总归不太踏实。

二是成本。
免费版够日常轻度使用,但对话量一大,要么升级付费,要么忍受限额。
记忆系统这种东西,一旦用上了就很难回头,越用越依赖,成本只会越来越高。

好在 Hindsight 本身是开源项目,GitHub 上代码全开放,支持本地部署。
数据存在自己的服务器上,用多少都不用额外花钱(除了 LLM API 调用费用)。

这篇文章就记录一下完整的本地部署过程。

整体架构

先说清楚最终的架构长什么样,后面每一步都是在搭这个架子。

底层是 PostgreSQL 18,负责存储所有记忆数据和向量索引,需要安装 pgvector 扩展。

中间层是 Hindsight 服务,通过 Docker Compose 部署,对外暴露两个端口:8888 提供 API,9999 提供 Web 管理界面。

上层是 Hermes Agent,通过配置指向本地 Hindsight 实例,完成记忆的读写。

模型方面,LLM 用智谱的 glm-5.1,Embedding 和 Reranker 用硅基流动的 bge-m3 和 bge-reranker-v2-m3。

安装 PostgreSQL 18

Ubuntu 24.04 默认仓库里的 PostgreSQL 版本比较老,要装 18 需要先添加官方的 PGDG 仓库。

添加 PostgreSQL 官方 APT 源:

1
2
sudo apt install -y postgresql-common
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh

脚本会自动导入 GPG key 并添加源,过程中可能要输入 sudo 密码。

安装 PostgreSQL 18:

1
2
sudo apt update
sudo apt install -y postgresql-18

安装完成后服务会自动启动,确认一下状态:

1
sudo systemctl status postgresql@18-main.service

看到 active (running) 就没问题。

安装 pgvector 扩展

Hindsight 的向量搜索依赖 pgvector,PGDG 仓库直接提供了编译好的包,不需要从源码编译。

1
sudo apt install -y postgresql-18-pgvector

装完之后在数据库里启用扩展就行,下一步创建数据库的时候一起做。

创建数据库和用户

切换到 postgres 用户,创建 Hindsight 专用的数据库和用户:

1
sudo -u postgres psql

在 psql 里执行:

1
2
3
4
5
CREATE USER hindsight WITH PASSWORD '你的密码';
CREATE DATABASE hindsight OWNER hindsight;
\c hindsight
CREATE EXTENSION IF NOT EXISTS vector;
\q

四条命令分别做了四件事:创建用户、创建数据库、切换到目标数据库、启用 pgvector 扩展。

验证扩展是否装好:

1
sudo -u postgres psql -d hindsight -c "SELECT * FROM pg_extension WHERE extname = 'vector';"

能查到一行记录就对了。

配置 PostgreSQL 允许远程连接

默认情况下 PostgreSQL 只监听 localhost,如果 Hindsight 容器和数据库不在同一台机器上,需要调整监听地址。

编辑 /etc/postgresql/18/main/postgresql.conf,找到 listen_addresses 这行:

1
listen_addresses = '*'

然后编辑 /etc/postgresql/18/main/pg_hba.conf,在文件末尾加一行允许指定网段访问:

1
host    hindsight    hindsight    192.168.10.0/24    scram-sha-256

这里的 192.168.10.0/24 根据你的实际网段调整,也可以写成 0.0.0.0/0不过为了安全起见最好还是写内网网段。

改完重启 PostgreSQL:

1
sudo systemctl restart postgresql

Docker Compose 部署 Hindsight

这一步是核心。
新建一个目录放配置文件:

1
mkdir -p ~/hindsight && cd ~/hindsight

创建 docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
version: '3.8'

services:
hindsight:
image: ghcr.io/vectorize-io/hindsight:0.7.0
container_name: hindsight
restart: unless-stopped
ports:
- "8888:8888"
- "9999:9999"
environment:
HINDSIGHT_API_LLM_PROVIDER: openai
HINDSIGHT_API_LLM_API_KEY: '你的智谱API Key'
HINDSIGHT_API_LLM_BASE_URL: 'https://open.bigmodel.cn/api/coding/paas/v4'
HINDSIGHT_API_LLM_MODEL: 'glm-5.1'
HINDSIGHT_API_EMBEDDINGS_PROVIDER: openai
HINDSIGHT_API_EMBEDDINGS_OPENAI_MODEL: 'BAAI/bge-m3'
HINDSIGHT_API_EMBEDDINGS_OPENAI_API_KEY: '你的硅基流动API Key'
HINDSIGHT_API_EMBEDDINGS_OPENAI_BASE_URL: 'https://api.siliconflow.cn/v1'
HINDSIGHT_API_RERANKER_PROVIDER: siliconflow
HINDSIGHT_API_RERANKER_SILICONFLOW_MODEL: 'BAAI/bge-reranker-v2-m3'
HINDSIGHT_API_RERANKER_SILICONFLOW_BASE_URL: 'https://api.siliconflow.cn/v1'
HINDSIGHT_API_RERANKER_SILICONFLOW_API_KEY: '你的硅基流动API Key'
HINDSIGHT_POSTGRES_URL: 'postgresql://hindsight:你的密码@192.168.10.9:5432/hindsight'

几个关键配置解释一下。

  • HINDSIGHT_API_LLM_PROVIDER 设为 openai,因为智谱的 API 兼容 OpenAI 接口格式,通过 BASE_URL 指向智谱的端点即可。

  • HINDSIGHT_API_LLM_BASE_URL 用的是智谱的 Coding PaaS 接口地址,不是标准的 open.bigmodel.cn/api/paas/v4
    如果调用时遇到问题,可以试试换回标准地址。

为什么不用 Hindsight 内置的默认模型?
默认的 Embedding 模型是 bge-small-en-v1.5,384 维,英文为主,对中文的语义理解比较弱。
而且它需要从 HuggingFace 下载,国内网络基本拉不下来。

换成硅基流动的 bge-m3,1024 维,中英双语都强,语义检索精度高很多。
Reranker 同理,bge-reranker-v2-m3 对中文的重排序效果比内置模型好。
两个都走硅基流动的 API,而且是免费的,省得自己跑本地模型占资源。

HINDSIGHT_POSTGRES_URL 指向刚才创建的外部 PostgreSQL 数据库,替换成你自己的 IP、用户名和密码。

启动:

1
docker compose up -d

查看日志确认启动成功:

1
docker logs -f hindsight

看到类似 Application startup complete 的日志就说明服务跑起来了。

镜像拉取的替代方案

ghcr.io 在国内拉取可能比较慢,可以用镜像站。

比如南京大学的镜像:

1
image: ghcr.nju.edu.cn/vectorize-io/hindsight:0.7.0

拉完之后改回原 tag 也行:

1
2
docker pull ghcr.nju.edu.cn/vectorize-io/hindsight:0.7.0
docker tag ghcr.nju.edu.cn/vectorize-io/hindsight:0.7.0 ghcr.io/vectorize-io/hindsight:0.7.0

或者像我一样推到自己的 Harbor 仓库,后续部署就不用再等了。

验证服务

Hindsight 启动后,可以用 curl 快速验证 API 是否正常工作。

创建一个记忆库:

1
2
3
curl -X POST http://localhost:8888/v1/banks \
-H "Content-Type: application/json" \
-d '{"name": "test", "bankType": "HYBRID"}'

存入一条记忆:

1
2
3
curl -X POST http://localhost:8888/v1/banks/test/retain \
-H "Content-Type: application/json" \
-d '{"content": "用户偏好使用 Python 技术栈", "context": "技术偏好"}'

搜索记忆:

1
2
3
curl -X POST http://localhost:8888/v1/banks/test/recall \
-H "Content-Type: application/json" \
-d '{"query": "用户的技术偏好", "limit": 5}'

能返回刚才存入的内容,说明整个链路通了:Hindsight API 到 PostgreSQL 到 pgvector,全部正常。

Web 管理界面在 http://你的服务器IP:9999,可以图形化地查看和管理记忆库。

创建 Hermes 记忆库

Hermes 集成需要用到一个名为 hermes 的记忆库。
打开 Hindsight Web 管理界面(http://你的服务器IP:9999),在 Banks 页面点击创建。

名称填 hermes
hindsight-local

Hermes Agent 集成

Hindsight 跑起来之后,让 Hermes 接上就很简单了。

对 Hermes 说:

1
帮我设置记忆系统

或者直接在终端执行:

1
hermes memory setup

向导里选择 Hindsight 作为 provider,选择 Local External ,输入接口地址:http://你的服务器IP:8888

然后对 Hermes 说:

1
检查记忆状态

或者执行:

1
hermes memory status

看到 auto-recallauto-retain 都是绿色的 on 状态,就大功告成了。

向导配置完成后,Hermes 会在 ~/.hermes/hindsight/config.json 生成最终配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"mode": "local_external",
"apiKey": "",
"timeout": 120,
"idle_timeout": 300,
"retain_tags": "",
"retain_source": "",
"retain_user_prefix": "User",
"retain_assistant_prefix": "Assistant",
"banks": {
"hermes": {
"bankId": "hermes",
"budget": "mid",
"enabled": true
}
},
"bank_id": "hermes",
"recall_budget": "mid",
"api_url": "http://192.168.10.9:8888",
"auto_recall": true,
"auto_retain": true,
"memory_mode": "hybrid"
}

api_url 指向本地 Hindsight 实例,bank_id 对应刚才在 Web 界面创建的记忆库名称。
apiKey 不用填,因为本地部署的也没有这个key,云端才需要。

之后的使用体验和云端版完全一样,Hermes 会自动从对话中提取记忆、在新会话中注入相关上下文。
区别在于,数据现在安安静静地躺在你自己的 PostgreSQL 里,而且成本极低。

踩坑记录

部署过程中遇到了几个问题,记录一下免得后来人踩同样的坑。

LLM 端点必须用 HTTPS。
Hindsight 连接 LLM 服务时要求 HTTPS,如果配了 HTTP 的地址会直接连不上。
智谱的 API 本身就是 HTTPS,所以正常配置不会有问题。
但如果你用的是自建的 LLM 中转服务,记得配好证书。

Embedding 批量大小要注意。
bge-m3 默认单次最多处理 64 条,而 Hindsight 的默认批量大小是 100。
超出会返回 413 错误。
可以通过环境变量调整:

1
HINDSIGHT_API_EMBEDDINGS_OPENAI_BATCH_SIZE: 64

切换 Embedding 模型要清库。
不同 Embedding 模型的向量维度不同,比如 bge-m3 是 1024 维,bge-small-en-v1.5 是 384 维。
维度不兼容意味着换了模型之后,之前存的记忆全部失效,需要清空数据库重新来。
所以上线前想好用哪个模型,别来回换。

完整配置参考

以下是我实际使用的完整 docker-compose.yml,可供参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
version: '3.8'

services:
hindsight:
image: ghcr.nju.edu.cn/vectorize-io/hindsight:0.7.0
container_name: hindsight
restart: unless-stopped
ports:
- "8888:8888"
- "9999:9999"
environment:
HINDSIGHT_API_LLM_PROVIDER: openai
HINDSIGHT_API_LLM_API_KEY: 'your-zhipu-api-key'
HINDSIGHT_API_LLM_BASE_URL: 'https://open.bigmodel.cn/api/coding/paas/v4'
HINDSIGHT_API_LLM_MODEL: 'glm-5.1'
HINDSIGHT_API_EMBEDDINGS_PROVIDER: openai
HINDSIGHT_API_EMBEDDINGS_OPENAI_MODEL: 'BAAI/bge-m3'
HINDSIGHT_API_EMBEDDINGS_OPENAI_API_KEY: 'your-siliconflow-api-key'
HINDSIGHT_API_EMBEDDINGS_OPENAI_BASE_URL: 'https://api.siliconflow.cn/v1'
HINDSIGHT_API_RERANKER_PROVIDER: siliconflow
HINDSIGHT_API_RERANKER_SILICONFLOW_MODEL: 'BAAI/bge-reranker-v2-m3'
HINDSIGHT_API_RERANKER_SILICONFLOW_BASE_URL: 'https://api.siliconflow.cn/v1'
HINDSIGHT_API_RERANKER_SILICONFLOW_API_KEY: 'your-siliconflow-api-key'
HINDSIGHT_POSTGRES_URL: 'postgresql://hindsight:your-password@192.168.10.9:5432/hindsight'

LLM 用智谱 glm-5.1,Embedding 和 Reranker 都走硅基流动的免费使用,数据库是本机的 PostgreSQL 18。

整套下来,数据完全在自己手里,不用担心隐私,也不用操心云端的用量额度。
Hermes 的记忆能力和之前用云端时一模一样,只是背后的数据流从”上传到别人服务器”变成了”写入自己的数据库”。