edit(content): review batch-1 editorial pass across 24 posts (EN + ZH)
- voice: first-person throughout (we/our -> I/my), matching the post guideline - privacy: internal LAN IPs replaced with placeholder hostnames (n8n.internal, gpu-node.internal); one compose volume path generalised - ZH twins: Traditional -> Simplified characters (site serves zh-Hans), whole-file renormalisation where the twin was still Traditional - dynamicCta: true on 12 posts so the contextual dual-track CTA renders - long configs wrapped in <details class="tech-deep-dive"> with a summary naming the artefact and line count - self-hosted-tts: token refresh now writes .tmp + atomic mv, with a note on the 401 race the old truncating redirect created
This commit is contained in:
1 parent
86edd40c74
commit
68771101ea
50 files changed
+478
-375
No files matched your search
@@ -1,8 +1,10 @@
|
||||
---
|
||||
title: "我如何在自家 NAS 上自托管 Mem0 记忆栈(让 AI 助手有记忆)"
|
||||
title: "我如何在私有存储节点上自托管 Mem0 记忆栈(让 AI 助手拥有持久记忆)"
|
||||
description: "一套私有、自托管的 AI 助手记忆层——mem0 API + LiteLLM + PostgreSQL/pgvector,跑在 Synology NAS 上。语义记忆由你掌控,而不是第三方手里。"
|
||||
pubDate: 2026-09-16
|
||||
category: case-studies
|
||||
blueprint: ai-agent-automation
|
||||
blueprintLayer: L2-llm-gateway-agents
|
||||
tags: [mem0, docker, postgres, pgvector, litellm, ai, sharing]
|
||||
ogImage: /og/zh-self-hosting-mem0-memory-stack.jpg
|
||||
banner: /banners/self-hosting-mem0-memory-stack.jpg
|
||||
@@ -10,7 +12,7 @@ banner: /banners/self-hosting-mem0-memory-stack.jpg
|
||||
|
||||
一个每次对话后都忘光一切的 AI 助手,就是一个每轮都要你重新自我介绍的工具。我的 AI 助手(就是驱动这个博客工作流的那个)曾经每场会话都从零开始——直到我给它加了一层**记忆**:一套自托管的 [mem0](https://mem0.ai) 栈,负责存储它学到的事实、按语义检索、并跨会话存活。
|
||||
|
||||
这就是我在自家 Synology NAS 上自托管它的故事——私有、完全由我掌控、数据绝不离开我的局域网。
|
||||
这就是我在自托管生产存储节点(Synology DS1821+)上部署这套系统的工程实践——私有、完全由我掌控、数据绝不离开我的局域网。
|
||||
|
||||
## 为什么这件事重要
|
||||
|
||||
@@ -27,7 +29,7 @@ banner: /banners/self-hosting-mem0-memory-stack.jpg
|
||||
Mem0 是给 LLM 应用用的「开箱即用的记忆」。你不用手搓嵌入表和相似度检索,它给一个小 API,把记忆需要的三件事都做了:
|
||||
|
||||
1. **加一条记忆** —— `POST /memories` 传一条事实或一段对话;它抽取、去重并存储(可选由 LLM 分类)。
|
||||
2. **检索** —— `GET /search` 带一个 query,返回按语义相似度排序的相关事实。
|
||||
2. **检索** —— `POST /search` 带一个 JSON 请求体,返回按语义相似度排序的相关事实。
|
||||
3. **按用户隔离** —— 记忆归属 `user_id`,所以可以按客户、按项目、按会话分开,互不串扰。
|
||||
|
||||
「记忆」就是抽取出来的事实;「检索」就是向量相似度。哪怕你从没亲手碰过向量数据库,也能让助手有记忆。
|
||||
@@ -54,6 +56,9 @@ Synology DS1821+ 上用 Portainer compose 栈跑三个容器:
|
||||
|
||||
一份有代表性的 compose 长这样:
|
||||
|
||||
<details>
|
||||
<summary>📄 docker-compose.yml(30 行)— Mem0 + LiteLLM + pgvector 生产编排配置</summary>
|
||||
|
||||
```yaml
|
||||
services:
|
||||
mem0-postgres:
|
||||
@@ -77,24 +82,26 @@ services:
|
||||
build: ./mem0-api
|
||||
environment:
|
||||
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||
OPENAI_API_BASE: http://mem0-litellm:4000/v1 # go through the gateway
|
||||
MEM0_API_KEY: ${MEM0_API_KEY} # X-Api-Key for /search & /memories
|
||||
POSTGRES_URL: postgresql://mem0:${MEM0_DB_PASSWORD}@mem0-postgres/mem0
|
||||
OPENAI_API_BASE: http://mem0-litellm:4000/v1 # 穿过网关
|
||||
MEM0_API_KEY: ${MEM0_API_KEY} # /search 与 /memories 的 X-Api-Key
|
||||
POSTGRES_URL: postgresql://mem0:***@mem0-postgres/mem0
|
||||
ports:
|
||||
- "20015:8000"
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
(我是从 mem0 仓库本地构建、把模型/事实抽取指向 LiteLLM;确切的镜像版本是我自己维护本地镜像的结果。真实 API key 我放在 compose 文件外面,走环境变量密文注入。)
|
||||
</details>
|
||||
|
||||
(我的镜像是从 mem0 仓库构建的,模型/事实抽取指向 LiteLLM;具体 tag 是我维护的本地构建版本,真正的 API key 我不放在 compose 里——由环境密文注入。)
|
||||
|
||||
## 使用
|
||||
|
||||
起起来之后,这个 API 小到意外。加一条事实(快速、逐字保存):
|
||||
服务起来之后,API 简单得让人神清气爽。写入一条事实(快速、原样存储):
|
||||
|
||||
```bash
|
||||
curl -X POST http://192.168.1.1:20015/memories \
|
||||
curl -X POST http://nas-node.internal:20015/memories \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Api-Key: $MEM0_API_KEY" \
|
||||
-H "X-Api-Key: ***" \
|
||||
-d '{
|
||||
"user_id": "customer-2211",
|
||||
"text": "Customer 2211 prefers email over WhatsApp for order updates."
|
||||
@@ -104,9 +111,9 @@ curl -X POST http://192.168.1.1:20015/memories \
|
||||
之后再取最相关的记忆:
|
||||
|
||||
```bash
|
||||
curl -X POST http://192.168.1.1:20015/memories/search \
|
||||
curl -X POST http://nas-node.internal:20015/search \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Api-Key: $MEM0_API_KEY" \
|
||||
-H "X-Api-Key: ***" \
|
||||
-d '{
|
||||
"user_id": "customer-2211",
|
||||
"query": "how should I reach this customer?",
|
||||
|
||||
Reference in new issue
Block a user