Compare commits
19 Commits
4806225f65
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ef1ceb384 | ||
|
|
567fc2c180 | ||
|
|
042a377143 | ||
|
|
ed054da5d8 | ||
|
|
893839c7a8 | ||
|
|
fb80480a22 | ||
|
|
21e3e33da9 | ||
|
|
9159cdf83c | ||
|
|
df5c412c7b | ||
|
|
2ea8964b7c | ||
|
|
7f2a609914 | ||
|
|
a72b1faf11 | ||
|
|
3180fb0ee8 | ||
|
|
24905d501f | ||
|
|
961cc218f1 | ||
|
|
5cd3ecd5e5 | ||
|
|
c09b23df6e | ||
|
|
9fd51e7556 | ||
|
|
a6755089ab |
44
AI/mem0/01-basics.md
Normal file
44
AI/mem0/01-basics.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Mem0 基础概念
|
||||
|
||||
## 什么是 Mem0
|
||||
|
||||
Mem0 是一个 **AI 记忆层**(Memory Layer),为大语言模型提供持久化记忆能力。
|
||||
|
||||
核心功能:
|
||||
- 存储 AI 与用户的对话记忆
|
||||
- 语义搜索相关记忆
|
||||
- 记忆关联推理
|
||||
|
||||
## Self-Host 是什么
|
||||
|
||||
Self-host(自托管)= 把 Mem0 部署在自己服务器上,而不是使用官方云服务。
|
||||
|
||||
| 方式 | 说明 | 数据位置 |
|
||||
|------|------|----------|
|
||||
| **官方云服务** | 调用 mem0.ai 的 API | 数据在第三方服务器 |
|
||||
| **Self-host** | 自己部署 mem0 代码 | 数据完全在自己控制 |
|
||||
|
||||
### Self-host 的优势
|
||||
|
||||
1. **数据隐私** - 所有数据不经过第三方
|
||||
2. **网络可控** - 可运行在私有网络/内网
|
||||
3. **成本可控** - 无 API 调用费用,适合大规模使用
|
||||
4. **定制灵活** - 可修改源码,切换向量数据库
|
||||
|
||||
## Mem0 官方仓库
|
||||
|
||||
- GitHub: `mem0ai/mem0`
|
||||
- 主要分支/目录:
|
||||
- `server/` - FastAPI 服务,完整功能(需 PostgreSQL + pgvector + Neo4j)
|
||||
- `openmemory/` - 轻量版本(已 sunset,建议用 server/)
|
||||
|
||||
## OpenMemory 和 Mem0 的关系
|
||||
|
||||
`openmemory/` 是 `mem0ai/mem0` 仓库下的一个**子目录/组件**,不是独立项目。
|
||||
|
||||
| 目录 | 存储后端 | 架构复杂度 | 状态 |
|
||||
|------|---------|-----------|------|
|
||||
| `server/` | PostgreSQL + pgvector + Neo4j | 高 | ✅ 维护中 |
|
||||
| `openmemory/` | Qdrant only | 低 | ⚠️ 已 sunset |
|
||||
|
||||
> ⚠️ 官方建议新部署使用 `server/` 目录
|
||||
100
AI/mem0/02-architecture.md
Normal file
100
AI/mem0/02-architecture.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Mem0 架构详解
|
||||
|
||||
## 整体架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Mem0 Server │
|
||||
│ (总控,协调所有组件) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│ │ │ │
|
||||
▼ ▼ ▼ ▼
|
||||
┌────────┐ ┌─────────┐ ┌──────────┐ ┌────────┐
|
||||
│ TEI │ │ Qdrant │ │PostgreSQL│ │ LLM │
|
||||
│(向量) │ │(向量库) │ │ (关系数据)│ │(回答) │
|
||||
└────────┘ └─────────┘ └──────────┘ └────────┘
|
||||
生成向量 存/搜向量 存元数据/关系 生成自然语言
|
||||
```
|
||||
|
||||
## 各组件职责
|
||||
|
||||
| 组件 | 类型 | 职责 | 你的环境 |
|
||||
|------|------|------|----------|
|
||||
| **TEI** | Text Embeddings Inference | 把文本转换成向量(embeddings) | BGE-M3 模型 |
|
||||
| **Qdrant** | 向量数据库 | 存储向量 + 原始文本,搜索相似向量 | tei namespace |
|
||||
| **PostgreSQL** | 关系数据库 | 存储用户数据、记忆元数据、关系链 | tei namespace |
|
||||
| **LLM** | 大语言模型 | 把向量检索结果组织成自然语言回答 | 待确认 |
|
||||
| **Neo4j** | 图数据库 | 存储记忆之间的关联关系(可选) | 可选,暂不需要 |
|
||||
|
||||
## 读写流程
|
||||
|
||||
### 写入记忆(2次请求)
|
||||
|
||||
```
|
||||
用户 → Mem0: "今天吃了火锅"
|
||||
│
|
||||
├→ TEI: 生成向量 [0.123, -0.456, ...]
|
||||
│ │
|
||||
├→ Qdrant: 存储向量 + 原始文本
|
||||
│ │
|
||||
└→ PostgreSQL: 存储元数据/关系
|
||||
```
|
||||
|
||||
### 搜索记忆(3次请求)
|
||||
|
||||
```
|
||||
用户 → Mem0: "最近吃了什么"
|
||||
│
|
||||
├→ TEI: 生成查询向量 [0.456, ...]
|
||||
│ │
|
||||
├→ Qdrant: 搜索相似向量 → 返回 "今天吃了火锅"
|
||||
│ │
|
||||
├→ PostgreSQL: 查询关联元数据
|
||||
│ │
|
||||
└→ LLM: 组织自然语言回答
|
||||
│
|
||||
▼
|
||||
用户得到回答
|
||||
```
|
||||
|
||||
## TEI 和 Qdrant 的关系
|
||||
|
||||
**TEI 和 Qdrant 完全独立,不知道对方存在**,全靠 Mem0 Server 在中间协调。
|
||||
|
||||
| 比喻 | 说明 |
|
||||
|------|------|
|
||||
| **TEI** | 翻译软件,把中文翻译成密码(向量) |
|
||||
| **Qdrant** | 图书馆,把密码对应的书存起来、搜出来 |
|
||||
|
||||
### 数据流
|
||||
|
||||
```
|
||||
Mem0 Server
|
||||
│
|
||||
├── 调用 TEI ────────→ TEI(只吐向量)
|
||||
│
|
||||
└── 调用 Qdrant ──── → Qdrant(只存/搜向量)
|
||||
```
|
||||
|
||||
## 为什么需要两者
|
||||
|
||||
- **TEI**:把文字变成数字,才能做语义计算
|
||||
- **Qdrant**:高效存储和搜索海量向量
|
||||
|
||||
两者缺一不可,分工不同。
|
||||
|
||||
## Neo4j(可选)
|
||||
|
||||
Neo4j 是图数据库,存储**记忆之间的关系**,用于复杂推理。
|
||||
|
||||
### 何时需要
|
||||
- 多跳问答("我老婆的表哥的同事")
|
||||
- 知识图谱构建
|
||||
- 社交网络分析
|
||||
|
||||
### 何时不需要
|
||||
- 普通语义搜索
|
||||
- 个人记忆库
|
||||
- RAG 增强
|
||||
|
||||
**建议:先不加 Neo4j,只用 Qdrant + PostgreSQL,跑起来后再按需扩展。**
|
||||
120
AI/mem0/03-deployment.md
Normal file
120
AI/mem0/03-deployment.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# Mem0 部署方案
|
||||
|
||||
## 部署选项
|
||||
|
||||
### 选项 A:server/(完整功能)
|
||||
|
||||
| 组件 | 说明 |
|
||||
|------|------|
|
||||
| **Mem0 Server** | FastAPI 服务 |
|
||||
| **PostgreSQL + pgvector** | 关系数据 + 向量存储 |
|
||||
| **Neo4j** | 图数据库(可选) |
|
||||
|
||||
### 选项 B:openmemory/(轻量,已 sunset)
|
||||
|
||||
仅需 Qdrant,但官方已停止维护,不建议使用。
|
||||
|
||||
---
|
||||
|
||||
## K8s 部署(server/ 方案)
|
||||
|
||||
### 你已有的基础设施
|
||||
|
||||
```
|
||||
tei namespace 下已有:
|
||||
├── Qdrant ← 向量数据库
|
||||
├── PostgreSQL ← 关系数据库
|
||||
├── Dify ← 编排平台(LLM 能力?)
|
||||
├── TEI ← Text Embeddings Inference
|
||||
└── BGM ← BGE-M3 嵌入模型服务
|
||||
```
|
||||
|
||||
### 部署架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Mem0 Pod │
|
||||
│ ├── mem0-server (main container) │
|
||||
│ │ - Port: 8000 │
|
||||
│ │ - 连接 TEI、Qdrant、PostgreSQL、LLM │
|
||||
│ └── git-sync (sidecar, 可选) │
|
||||
│ - 从 Gitea 拉取配置/知识库 │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
├─ TEI: http://tei-server:8080
|
||||
├─ Qdrant: http://qdrant:6333
|
||||
├─ PostgreSQL: postgres:5432
|
||||
└─ LLM: 待确认(Dify / OpenAI 代理 / Ollama)
|
||||
```
|
||||
|
||||
### 核心环境变量
|
||||
|
||||
```bash
|
||||
# PostgreSQL(已有)
|
||||
POSTGRES_HOST=postgres
|
||||
POSTGRES_PORT=5432
|
||||
POSTGRES_DB=mem0
|
||||
POSTGRES_USER=postgres
|
||||
POSTGRES_PASSWORD=xxx
|
||||
APP_DB_NAME=mem0_app
|
||||
|
||||
# Qdrant(已有)
|
||||
QDRANT_HOST=qdrant
|
||||
QDRANT_PORT=6333
|
||||
|
||||
# TEI Embedder(已有)
|
||||
EMBEDDER_PROVIDER=tei
|
||||
TEI_ENDPOINT=http://tei-server:8080
|
||||
|
||||
# LLM(待确认)
|
||||
LLM_PROVIDER=openai # 或 dify / ollama / anthropic
|
||||
OPENAI_API_KEY=xxx # 或通过 Dify
|
||||
|
||||
# Auth
|
||||
JWT_SECRET=xxx
|
||||
ADMIN_API_KEY=xxx
|
||||
AUTH_DISABLED=false
|
||||
|
||||
# Telemetry(国内建议关闭)
|
||||
MEM0_TELEMETRY=false
|
||||
```
|
||||
|
||||
### 你需要准备的内容
|
||||
|
||||
1. [ ] 确认 LLM 来源(Dify / OpenAI 代理 / Ollama)
|
||||
2. [ ] 确认 PostgreSQL 数据库已创建(`mem0` 数据库)
|
||||
3. [ ] 确认 Qdrant collection 已创建(或让 mem0 自动创建)
|
||||
4. [ ] 配置环境变量
|
||||
5. [ ] 编译/获取 mem0 镜像
|
||||
|
||||
---
|
||||
|
||||
## 国内网络问题
|
||||
|
||||
### 问题
|
||||
|
||||
- 无法访问 Docker Hub
|
||||
- 无法访问 GitHub raw content
|
||||
|
||||
### 解决方式
|
||||
|
||||
1. **镜像提前导入**:在有网环境 `docker pull` 后 `docker save`,导入到 K8s 节点
|
||||
2. **内网镜像仓库**:配置私有的 Harbor 或 registry
|
||||
3. **代码构建**:下载代码后 `docker build` 本地镜像
|
||||
|
||||
### 建议的镜像来源
|
||||
|
||||
| 镜像 | 国内可用的 registry |
|
||||
|------|-------------------|
|
||||
| pgvector | `registry.cn-hangzhou.aliyuncs.com` 搜索 |
|
||||
| neo4j | `docker.m.daocloud.io/neo4j` (DaoCloud) |
|
||||
| mem0 | 需自行 build 或找社区镜像 |
|
||||
|
||||
---
|
||||
|
||||
## 待完成
|
||||
|
||||
- [ ] 确认 mem0 代码可下载
|
||||
- [ ] 确认 LLM 来源
|
||||
- [ ] 生成 K8s YAML 文件
|
||||
- [ ] 测试部署
|
||||
62
AI/mem0/04-your-infra.md
Normal file
62
AI/mem0/04-your-infra.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# 你的基础设施
|
||||
|
||||
## K8s 集群
|
||||
|
||||
- **Namespace**: `tei`
|
||||
- **已有组件**: Qdrant, PostgreSQL, Dify, TEI, BGE-M3
|
||||
|
||||
## 服务列表
|
||||
|
||||
### TEI (Text Embeddings Inference)
|
||||
- **服务名**: `tei` (在 tei namespace)
|
||||
- **模型**: BGE-M3 (BGM-M3)
|
||||
- **用途**: 生成文本向量(embeddings)
|
||||
- **特点**: 中文支持好,比 OpenAI embedder 更适合中文
|
||||
|
||||
### Qdrant
|
||||
- **服务名**: `qdrant`
|
||||
- **端口**: 6333 (HTTP), 6334 (gRPC)
|
||||
- **用途**: 向量数据库,存储和搜索向量
|
||||
- **注意**: Mem0 Server 通过 Qdrant 的 HTTP API 连接
|
||||
|
||||
### PostgreSQL
|
||||
- **服务名**: `postgres`
|
||||
- **端口**: 5432
|
||||
- **扩展**: pgvector(用于向量支持)
|
||||
- **用途**: 存储用户数据、记忆元数据、关系数据
|
||||
|
||||
### Dify
|
||||
- **服务名**: `dify`
|
||||
- **用途**: 编排平台,可能提供 LLM 能力
|
||||
- **注意**: 需确认 Dify 是否作为 LLM Provider 接入 Mem0
|
||||
|
||||
### BGE-M3 / BGM-M3
|
||||
- **模型**: BAAI General Embedding Model - M3
|
||||
- **部署方式**: 通过 TEI 推理服务
|
||||
- **特点**: 支持 100+ 语言,中文效果优秀
|
||||
|
||||
## 网络架构
|
||||
|
||||
```
|
||||
Mem0 Pod(在 tei namespace)
|
||||
│
|
||||
├── TEI: http://tei-server:8080
|
||||
│ └── 模型: BGE-M3
|
||||
│
|
||||
├── Qdrant: http://qdrant:6333
|
||||
│
|
||||
├── PostgreSQL: postgres:5432
|
||||
│
|
||||
└── LLM: 待确认
|
||||
├── 选项 1: Dify
|
||||
├── 选项 2: OpenAI 代理
|
||||
└── 选项 3: Ollama (本地模型)
|
||||
```
|
||||
|
||||
## 待确认事项
|
||||
|
||||
1. [ ] TEI 服务的具体地址和端口
|
||||
2. [ ] Qdrant 是否需要手动创建 collection
|
||||
3. [ ] PostgreSQL 是否已创建 `mem0` 数据库
|
||||
4. [ ] Dify 的 LLM API 是否可用
|
||||
5. [ ] LLM 最终选择(Dify / OpenAI 代理 / Ollama)
|
||||
81
AI/mem0/05-faq.md
Normal file
81
AI/mem0/05-faq.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# Mem0 常见问题
|
||||
|
||||
## Q: Mem0 和 OpenMemory 是什么关系?
|
||||
|
||||
A: OpenMemory 是 `mem0ai/mem0` 仓库下的一个子目录,不是独立项目。OpenMemory 使用 Qdrant 作为唯一存储后端,已被官方废弃(sunset),建议使用 `server/` 目录。
|
||||
|
||||
## Q: 为什么需要 TEI 和 Qdrant 两个东西?
|
||||
|
||||
A: 它们是完全不同的组件,分工合作:
|
||||
- **TEI**:把文本转换成向量(理解语义)
|
||||
- **Qdrant**:存储向量 + 搜索相似向量
|
||||
|
||||
类比:TEI 是翻译软件,Qdrant 是图书馆。两者缺一不可,但互相不知道对方存在,全靠 Mem0 Server 协调。
|
||||
|
||||
## Q: Neo4j 是必须的吗?
|
||||
|
||||
A: 不是。大部分场景不需要 Neo4j:
|
||||
- 普通语义搜索:Qdrant 足够
|
||||
- 关系推理(如"我老婆的表哥的同事"):需要 Neo4j
|
||||
|
||||
建议先不加,只部署 Qdrant + PostgreSQL,跑起来后再按需扩展。
|
||||
|
||||
## Q: 写入和读取记忆需要多少次请求?
|
||||
|
||||
A:
|
||||
- **写入**:2次(TEI生成向量 → Qdrant存储)
|
||||
- **读取/搜索**:3次(TEI生成查询向量 → Qdrant搜索 → LLM生成回答)
|
||||
|
||||
## Q: 中国网络环境下如何部署?
|
||||
|
||||
A: 主要问题:
|
||||
1. 无法从 Docker Hub 拉镜像 → 提前下载导入或使用国内镜像
|
||||
2. 无法访问 GitHub → 使用 gitea 托管代码
|
||||
|
||||
## Q: Self-host 需要哪些环境变量?
|
||||
|
||||
A: 核心变量:
|
||||
```bash
|
||||
# 数据库
|
||||
POSTGRES_HOST=
|
||||
POSTGRES_PORT=5432
|
||||
POSTGRES_DB=
|
||||
POSTGRES_USER=
|
||||
POSTGRES_PASSWORD=
|
||||
|
||||
# 向量库
|
||||
QDRANT_HOST=
|
||||
QDRANT_PORT=6333
|
||||
|
||||
# Embedder
|
||||
EMBEDDER_PROVIDER=tei
|
||||
TEI_ENDPOINT=
|
||||
|
||||
# LLM
|
||||
LLM_PROVIDER=
|
||||
OPENAI_API_KEY=
|
||||
|
||||
# Auth
|
||||
JWT_SECRET=
|
||||
ADMIN_API_KEY=
|
||||
AUTH_DISABLED=false
|
||||
```
|
||||
|
||||
## Q: Mem0 有官方 K8s 部署吗?
|
||||
|
||||
A: 没有官方 Helm Chart 或 K8s YAML。需要自行转换 docker-compose.yaml 为 K8s 资源,或使用社区方案。
|
||||
|
||||
## Q: TEI 是否需要知道 Qdrant?
|
||||
|
||||
A: 不需要。TEI 只做向量生成(文本→向量),不存储任何数据,不与 Qdrant 通信。
|
||||
|
||||
## Q: 为什么你的 mem0 代码 clone 这么慢?
|
||||
|
||||
A: 可能网络问题。可以尝试:
|
||||
- 使用断点续传:`curl -C - -L -o file.tar.gz URL`
|
||||
- 使用国内镜像或代理
|
||||
- 通过 Gitea 等国内 Git 服务托管
|
||||
|
||||
## Q: Swagger UI 可以随意注册用户,生产环境安全吗?
|
||||
|
||||
A: Mem0 系统级别的单用户模式——注册第一个 admin 用户后,系统禁止再注册新用户。
|
||||
405
AI/mem0/deploy.md
Normal file
405
AI/mem0/deploy.md
Normal file
@@ -0,0 +1,405 @@
|
||||
# mem0 自托管部署
|
||||
|
||||
## 镜像
|
||||
|
||||
```
|
||||
ccr.ccs.tencentyun.com/tei_agent/mem0:latest
|
||||
```
|
||||
|
||||
## 依赖服务(tei namespace)
|
||||
|
||||
| 服务 | 地址 | 用途 |
|
||||
|---|---|---|
|
||||
| PostgreSQL | 192.168.3.49:5432 | 关系数据存储 |
|
||||
| Qdrant | qdrant:6333 | 向量存储 |
|
||||
| TEI (BGE-M3) | tei:8080 | Embedder(文本→向量) |
|
||||
|
||||
## 环境变量
|
||||
|
||||
### ConfigMap (mem0-env)
|
||||
|
||||
| 变量 | 值 | 说明 |
|
||||
|---|---|---|
|
||||
| APP_DB_NAME | mem0 | 数据库名 |
|
||||
| QDRANT_HOST | qdrant | Qdrant 服务地址 |
|
||||
| QDRANT_PORT | 6333 | Qdrant 端口 |
|
||||
| QDRANT_COLLECTION_NAME | mem0 | 集合名 |
|
||||
| EMBEDDER_PROVIDER | tei | Embedder 使用 TEI |
|
||||
| TEI_ENDPOINT | http://tei:8080 | TEI endpoint |
|
||||
| LLM_PROVIDER | openai | LLM provider(MiniMax 兼容 OpenAI 格式) |
|
||||
| OPENAI_API_KEY | YOUR_MINIMAX_KEY | MiniMax API key |
|
||||
| OPENAI_BASE_URL | https://api.minimax.chat/v1 | MiniMax API 地址 |
|
||||
| AUTH_DISABLED | false | 启用认证 |
|
||||
| MEM0_TELEMETRY | false | 关闭遥测 |
|
||||
| REQUEST_LOG_RETENTION_DAYS | 30 | 日志保留天数 |
|
||||
| HISTORY_DB_PATH | /app/data/mem0_history.db | SQLite 历史数据库路径 |
|
||||
|
||||
### Secret (mem0-secrets)
|
||||
|
||||
| 变量 | 说明 |
|
||||
|---|---|
|
||||
| JWT_SECRET | JWT 签名密钥 |
|
||||
| ADMIN_API_KEY | 管理后台 API key |
|
||||
| POSTGRES_PASSWORD | PostgreSQL 密码 |
|
||||
|
||||
## 数据库迁移 (Alembic)
|
||||
|
||||
mem0 server 使用 Alembic 管理 PostgreSQL schema。**首次部署前必须先执行迁移**,创建 `request_logs` 等表。
|
||||
|
||||
### 迁移 Job
|
||||
|
||||
```yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: mem0-migrate
|
||||
namespace: tei
|
||||
spec:
|
||||
ttlSecondsAfterFinished: 300 # 完成后5分钟自动清理
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: OnFailure
|
||||
containers:
|
||||
- name: alembic
|
||||
image: ccr.ccs.tencentyun.com/tei_agent/mem0:latest
|
||||
command: ["alembic", "upgrade", "head"]
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: mem0-env
|
||||
- secretRef:
|
||||
name: mem0-secrets
|
||||
env:
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: dify-prod-db-secret
|
||||
key: password
|
||||
resources:
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "500m"
|
||||
```
|
||||
|
||||
### 迁移部署步骤
|
||||
|
||||
```bash
|
||||
# 1. 先跑迁移(只执行一次)
|
||||
kubectl apply -f mem0-migrate-job.yaml
|
||||
|
||||
# 2. 确认迁移完成
|
||||
kubectl get job mem0-migrate -n tei -w
|
||||
|
||||
# 3. 确认成功后再部署 mem0
|
||||
kubectl apply -f mem0-deployment.yaml
|
||||
|
||||
# 4. 如果迁移失败,查看原因
|
||||
kubectl logs job/mem0-migrate -n tei
|
||||
```
|
||||
|
||||
**重要**:迁移 Job 只跑一次。Pod 重启时不需要重新迁移,PostgreSQL schema 不会天天变。
|
||||
|
||||
## 前置要求
|
||||
|
||||
1. **pgvector 扩展** — PostgreSQL 需要安装 pgvector
|
||||
2. **mem0 数据库** — 需要提前创建
|
||||
3. **mem0-migrate Job** — 首次部署前必须先执行迁移
|
||||
4. **mem0-history PVC** — 必须提前创建
|
||||
5. **Qdrant collection** — mem0 启动时自动创建(首次调用时)
|
||||
|
||||
## 部署清单
|
||||
|
||||
### PVC + ConfigMap + Secret + Deployment + Service
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: mem0-history
|
||||
namespace: tei
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
storageClassName: standard # 根据你的 StorageClass 调整
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: mem0-env
|
||||
namespace: tei
|
||||
data:
|
||||
APP_DB_NAME: "mem0"
|
||||
QDRANT_HOST: "qdrant"
|
||||
QDRANT_PORT: "6333"
|
||||
QDRANT_COLLECTION_NAME: "mem0"
|
||||
EMBEDDER_PROVIDER: "tei"
|
||||
TEI_ENDPOINT: "http://tei:8080"
|
||||
LLM_PROVIDER: "openai"
|
||||
OPENAI_API_KEY: "YOUR_MINIMAX_KEY"
|
||||
OPENAI_BASE_URL: "https://api.minimax.chat/v1"
|
||||
AUTH_DISABLED: "false"
|
||||
MEM0_TELEMETRY: "false"
|
||||
REQUEST_LOG_RETENTION_DAYS: "30"
|
||||
HISTORY_DB_PATH: "/app/data/mem0_history.db"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: mem0-secrets
|
||||
namespace: tei
|
||||
type: Opaque
|
||||
stringData:
|
||||
JWT_SECRET: "your-jwt-secret-change-me"
|
||||
ADMIN_API_KEY: "your-admin-key-change-me"
|
||||
POSTGRES_PASSWORD: "gitlab"
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mem0
|
||||
namespace: tei
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mem0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mem0
|
||||
spec:
|
||||
containers:
|
||||
- name: mem0
|
||||
image: ccr.ccs.tencentyun.com/tei_agent/mem0:latest
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
name: http
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: mem0-env
|
||||
- secretRef:
|
||||
name: mem0-secrets
|
||||
volumeMounts:
|
||||
- name: mem0-history
|
||||
mountPath: /app/data
|
||||
resources:
|
||||
limits:
|
||||
cpu: "2"
|
||||
memory: "4Gi"
|
||||
requests:
|
||||
cpu: "500m"
|
||||
memory: "1Gi"
|
||||
volumes:
|
||||
- name: mem0-history
|
||||
persistentVolumeClaim:
|
||||
claimName: mem0-history
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mem0
|
||||
namespace: tei
|
||||
spec:
|
||||
ports:
|
||||
- port: 8000
|
||||
name: http
|
||||
selector:
|
||||
app: mem0
|
||||
```
|
||||
|
||||
## 验证
|
||||
|
||||
```bash
|
||||
# 检查 PVC
|
||||
kubectl get pvc -n tei mem0-history
|
||||
|
||||
# 检查 Pod
|
||||
kubectl get pods -n tei -l app=mem0
|
||||
|
||||
# 查看日志
|
||||
kubectl logs -n tei -l app=mem0 --tail=50
|
||||
|
||||
# 健康检查
|
||||
curl http://mem0:8000/health
|
||||
```
|
||||
|
||||
## History SQLite 说明
|
||||
|
||||
mem0 的对话历史存储在 SQLite,位于 `/app/data/mem0_history.db`。**必须用 PVC 持久化**,emptyDir 挂载重启后数据丢失。
|
||||
|
||||
如果 PVC 空间不足或不需要历史功能,可以改用空目录(数据丢失但不影响核心记忆功能):
|
||||
|
||||
```yaml
|
||||
# 测试/轻量级环境用 emptyDir
|
||||
volumes:
|
||||
- name: mem0-history
|
||||
emptyDir: {}
|
||||
```
|
||||
|
||||
## Dashboard 部署
|
||||
|
||||
mem0 dashboard 是 Next.js 应用,需要单独部署。
|
||||
|
||||
### 环境变量
|
||||
|
||||
```yaml
|
||||
NEXT_PUBLIC_API_URL=http://mem0.tei.svc.cluster.local:8000 # 浏览器调用(通过 Ingress)
|
||||
API_INTERNAL_URL=http://mem0.tei.svc.cluster.local:8000 # 服务端内部调用(K8s 内部直连)
|
||||
NEXT_PUBLIC_INSTANCE_NAME=Mem0
|
||||
```
|
||||
|
||||
**`API_INTERNAL_URL`**:K8s 内部服务间通信,直接使用 Service DNS,不需要暴露到外部。浏览器无法解析 `mem0.tei.svc.cluster.local`,所以前端用 `NEXT_PUBLIC_API_URL` 通过 Ingress 访问。
|
||||
|
||||
两者可以相同,但分离部署时:
|
||||
- `NEXT_PUBLIC_API_URL` = 对外域名(Ingress)
|
||||
- `API_INTERNAL_URL` = 集群内部 `mem0.tei.svc.cluster.local:8000`
|
||||
|
||||
### CORS 配置
|
||||
|
||||
mem0 server 使用 CORSMiddleware,需要通过环境变量配置允许的来源:
|
||||
|
||||
```yaml
|
||||
DASHBOARD_URL=https://mem0.your-domain.com # dashboard 的外部访问地址
|
||||
```
|
||||
|
||||
mem0 server 启动时读取 `DASHBOARD_URL`,设置 `allow_origins=[DASHBOARD_URL]`。
|
||||
|
||||
**常见问题**:
|
||||
- 浏览器访问 dashboard 登录页时,返回 `400 Bad Request`
|
||||
- OPTIONS 预检请求失败,因为 `allow_origins` 为空
|
||||
- Swagger 能正常登录(同域请求,无 CORS 问题)
|
||||
|
||||
确保 `DASHBOARD_URL` 设为 dashboard 的外部访问地址(与 `NEXT_PUBLIC_API_URL` 的域名部分一致)。
|
||||
|
||||
## sentence_transformers 导入错误(永久修复)
|
||||
|
||||
mem0 的 `huggingface.py` 在文件顶部执行 `from sentence_transformers import SentenceTransformer`,即使走 `huggingface_base_url` 路径(用 OpenAI 客户端调用 TEI,不需要本地模型)也会尝试加载,造成 `ModuleNotFoundError`。
|
||||
|
||||
通过 init container + emptyDir 挂载实现持久修复,pod recreate 不丢失:
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mem0
|
||||
namespace: tei
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mem0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mem0
|
||||
spec:
|
||||
initContainers:
|
||||
- name: patch-mem0
|
||||
image: ccr.ccs.tencentyun.com/tei_agent/mem0:latest
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
cp -r /usr/local/lib/python3.12/site-packages/mem0 /tmp/mem0-patch/
|
||||
sed -i 's/from sentence_transformers import SentenceTransformer/# from sentence_transformers import SentenceTransformer/' /tmp/mem0-patch/embeddings/huggingface.py
|
||||
echo "patch done"
|
||||
volumeMounts:
|
||||
- name: mem0-code
|
||||
mountPath: /tmp/mem0-patch
|
||||
containers:
|
||||
- name: mem0-ui
|
||||
image: ccr.ccs.tencentyun.com/tei_agent/mem0-ui:latest
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
name: http
|
||||
env:
|
||||
- name: NEXT_PUBLIC_API_URL
|
||||
value: "https://api.mem0.violin-work.online"
|
||||
- name: API_INTERNAL_URL
|
||||
value: "http://mem0.tei.svc.cluster.local:8000"
|
||||
- name: NEXT_PUBLIC_INSTANCE_NAME
|
||||
value: Mem0
|
||||
resources:
|
||||
limits:
|
||||
cpu: 200m
|
||||
memory: 500Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 250Mi
|
||||
- name: mem0
|
||||
image: ccr.ccs.tencentyun.com/tei_agent/mem0:latest
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
name: http
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: mem0-env
|
||||
- secretRef:
|
||||
name: mem0-secrets
|
||||
env:
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: dify-prod-db-secret
|
||||
key: password
|
||||
volumeMounts:
|
||||
- name: mem0-history
|
||||
mountPath: /app/data
|
||||
- name: mem0-code
|
||||
mountPath: /usr/local/lib/python3.12/site-packages/mem0
|
||||
resources:
|
||||
limits:
|
||||
cpu: "2"
|
||||
memory: 4Gi
|
||||
requests:
|
||||
cpu: "500m"
|
||||
memory: 1Gi
|
||||
volumes:
|
||||
- name: mem0-history
|
||||
persistentVolumeClaim:
|
||||
claimName: mem0-history
|
||||
- name: mem0-code
|
||||
emptyDir: {}
|
||||
```
|
||||
|
||||
**原理**:init container 先于主容器启动,把镜像里的 mem0 代码复制到 emptyDir,sed 补丁打在 emptyDir 里。主容器挂载 emptyDir 到 site-packages,覆盖镜像原有文件,实现补丁持久化(recreate 不丢)。
|
||||
|
||||
## 功能测试
|
||||
|
||||
mem0 未为 K8s 做适配,无健康检查端点。手动测试核心 API:
|
||||
|
||||
```bash
|
||||
cat > /tmp/test_mem0.py << 'TESTEOF'
|
||||
import urllib.request, json, uuid
|
||||
|
||||
BASE = "http://mem0:8000"
|
||||
|
||||
def req(method, path, data=None):
|
||||
url = BASE + path
|
||||
body = json.dumps(data).encode() if data else None
|
||||
headers = {"Content-Type": "application/json"}
|
||||
try:
|
||||
r = urllib.request.urlopen(urllib.request.Request(url, data=body, headers=headers, method=method), timeout=10)
|
||||
return json.loads(r.read()), r.status
|
||||
except urllib.error.HTTPError as e:
|
||||
return json.loads(e.read()), e.code
|
||||
except Exception as e:
|
||||
return str(e), 0
|
||||
|
||||
uid = str(uuid.uuid4())
|
||||
print("=== 1. 创建用户 ===")
|
||||
print(req("POST", "/api/v1/users", {"user_id": uid, "email": f"{uid}@test.com"}))
|
||||
|
||||
print("=== 2. 添加记忆 ===")
|
||||
print(req("POST", "/api/v1/memories", {"text": "我叫张三,我喜欢Python", "user_id": uid}))
|
||||
|
||||
print("=== 3. 搜索记忆 ===")
|
||||
print(req("GET", f"/api/v1/memories?query=python&user_id={uid}"))
|
||||
|
||||
print("=== 4. 获取历史 ===")
|
||||
print(req("GET", f"/api/v1/history?user_id={uid}"))
|
||||
TESTEOF
|
||||
kubectl exec -n tei deploy/mem0 -- python3 /tmp/test_mem0.py
|
||||
```
|
||||
11
AI/openviking/Dockerfile
Normal file
11
AI/openviking/Dockerfile
Normal file
@@ -0,0 +1,11 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN pip install openviking --upgrade --force-reinstall
|
||||
|
||||
RUN openviking-server init
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
CMD ["openviking-server", "run", "--host", "0.0.0.0", "--port", "8000"]
|
||||
152
AI/tokyo-proxy/01-proxy.md
Normal file
152
AI/tokyo-proxy/01-proxy.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# 东京云服务器代理方案
|
||||
|
||||
## 场景
|
||||
国内访问 GitHub / Docker Hub 速度慢,用东京低配云服务器做流量转发。
|
||||
|
||||
## 服务端(东京服务器)
|
||||
|
||||
### 1. 安装 squid
|
||||
```bash
|
||||
apt update && apt install -y squid apache2-utils
|
||||
```
|
||||
|
||||
### 2. 配置 squid(密码认证)
|
||||
```bash
|
||||
cat > /etc/squid/squid.conf << 'EOF'
|
||||
http_port 3128
|
||||
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwd
|
||||
auth_param basic realm "Tokyo Proxy"
|
||||
acl auth proxy_auth REQUIRED
|
||||
http_access allow auth
|
||||
http_access deny all
|
||||
EOF
|
||||
```
|
||||
|
||||
### 3. 创建用户
|
||||
```bash
|
||||
htpasswd -cb /etc/squid/passwd 用户名 密码
|
||||
```
|
||||
|
||||
### 4. 重启
|
||||
```bash
|
||||
systemctl restart squid
|
||||
systemctl enable squid
|
||||
```
|
||||
|
||||
### 验证
|
||||
```bash
|
||||
ss -tlnp | grep 3128
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 国内客户端
|
||||
|
||||
### Docker 配置
|
||||
```bash
|
||||
mkdir -p /etc/systemd/system/docker.service.d
|
||||
cat > /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF
|
||||
[Service]
|
||||
Environment="HTTP_PROXY=http://用户名:密码@东京服务器IP:3128"
|
||||
Environment="HTTPS_PROXY=http://用户名:密码@东京服务器IP:3128"
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload && systemctl restart docker
|
||||
```
|
||||
|
||||
### Git 配置
|
||||
```bash
|
||||
git config --global http.proxy http://用户名:密码@东京服务器IP:3128
|
||||
git config --global https.proxy http://用户名:密码@东京服务器IP:3128
|
||||
```
|
||||
|
||||
### K3s (containerd) 配置
|
||||
K3s 默认使用 containerd,不走 systemd代理,需要在 k3s service 环境变量中配置。
|
||||
|
||||
```bash
|
||||
# 添加代理环境变量到 k3s service
|
||||
mkdir -p /etc/systemd/system/k3s.service.d
|
||||
cat > /etc/systemd/system/k3s.service.d/http-proxy.conf <<EOF
|
||||
[Service]
|
||||
Environment="HTTP_PROXY=http://用户名:密码@东京服务器IP:3128"
|
||||
Environment="HTTPS_PROXY=http://用户名:密码@东京服务器IP:3128"
|
||||
Environment="NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,.svc,.cluster.local"
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload && systemctl restart k3s
|
||||
```
|
||||
|
||||
验证:
|
||||
```bash
|
||||
crictl pull nginx
|
||||
kubectl run nginx --image=nginx
|
||||
```
|
||||
|
||||
### 取消代理(如需直连)
|
||||
```bash
|
||||
git config --global --unset http.proxy
|
||||
git config --global --unset https.proxy
|
||||
# Docker 删除 /etc/systemd/system/docker.service.d/http-proxy.conf 后重启
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 验证
|
||||
```bash
|
||||
docker pull nginx
|
||||
git clone https://github.com/torvalds/linux
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 外部镜像同步到本地 Registry
|
||||
|
||||
### 场景
|
||||
东京服务器能访问 `ghcr.io`/`docker.io`,需要同步到本地 `localhost:5000` registry,供国内 K8s 节点拉取。
|
||||
|
||||
### 拉取外部镜像
|
||||
```bash
|
||||
docker pull ghcr.io/volcengine/openviking:latest
|
||||
```
|
||||
|
||||
### 同步到本地 Registry(推荐保留原始路径)
|
||||
```bash
|
||||
# 打 tag,路径保留原始仓库路径
|
||||
docker tag ghcr.io/volcengine/openviking:latest localhost:5000/ghcr.io/volcengine/openviking:latest
|
||||
|
||||
# 推送
|
||||
docker push localhost:5000/ghcr.io/volcengine/openviking:latest
|
||||
```
|
||||
|
||||
### 国内 K8s 节点拉取
|
||||
```bash
|
||||
docker pull 43.130.228.226:5000/ghcr.io/volcengine/openviking:latest
|
||||
```
|
||||
|
||||
### 用 skopeo 跳过本地存储直接同步(多架构镜像推荐)
|
||||
```bash
|
||||
apt update && apt install -y skopeo
|
||||
|
||||
skopeo copy --dest-tls-verify=false \
|
||||
docker://ghcr.io/volcengine/openviking:latest \
|
||||
docker://localhost:5000/ghcr.io/volcengine/openviking:latest
|
||||
```
|
||||
|
||||
### 查看本地 Registry 内容
|
||||
```bash
|
||||
curl -s http://localhost:5000/v2/_catalog
|
||||
curl -s http://localhost:5000/v2/ghcr.io/volcengine/openviking/tags/list
|
||||
```
|
||||
|
||||
### 路径说明
|
||||
- `localhost:5000/library/alpine` = Docker 官方镜像路径
|
||||
- `localhost:5000/ghcr.io/volcengine/openviking` = 保留原始来源路径(推荐)
|
||||
|
||||
保留原始路径好处:一目了然知道镜像来源。
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
- 东京服务器带宽低(1-2Mbps),Docker 拉大镜像较慢
|
||||
- Git 流量小,代理无压力
|
||||
- HTTP 代理同时支持 Git 和 Docker,无需 nginx 反代
|
||||
36
Linux/linux-users.md
Normal file
36
Linux/linux-users.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Linux 用户基础操作
|
||||
|
||||
## 查看用户
|
||||
|
||||
```bash
|
||||
# 查看所有用户
|
||||
cat /etc/passwd
|
||||
|
||||
# 查看当前在线用户
|
||||
who
|
||||
|
||||
# 显示谁在登录
|
||||
w
|
||||
```
|
||||
|
||||
## 切换用户
|
||||
|
||||
```bash
|
||||
su - postgres # 切换到 postgres 用户(带登录 shell)
|
||||
sudo su - postgres # 用 sudo 切换(需要 root 权限)
|
||||
```
|
||||
|
||||
## PostgreSQL 进数据库
|
||||
|
||||
```bash
|
||||
su - postgres # 先切到 postgres 用户
|
||||
psql # 直接进数据库
|
||||
```
|
||||
|
||||
或者不切换用户直接进:
|
||||
|
||||
```bash
|
||||
psql -U postgres -h 192.168.3.49 -p 5432
|
||||
```
|
||||
|
||||
输入密码后进入 SQL 操作界面,quit 用 `\q`。
|
||||
21
README.md
21
README.md
@@ -1,2 +1,21 @@
|
||||
# knowledge-base
|
||||
# 知识库
|
||||
|
||||
个人知识仓库,存储 AI 相关技术知识。
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
AI/
|
||||
├── mem0/ # Mem0 自托管部署、架构、运维知识
|
||||
│ ├── 01-basics.md
|
||||
│ ├── 02-architecture.md
|
||||
│ ├── 03-deployment.md
|
||||
│ ├── 04-your-infra.md
|
||||
│ └── 05-faq.md
|
||||
└── tokyo-proxy/ # 东京云服务器代理:GitHub + Docker 流量转发
|
||||
└── 01-proxy.md
|
||||
```
|
||||
|
||||
## 来源
|
||||
|
||||
本知识库由 AI Agent (Hermes) 根据对话整理。
|
||||
Reference in New Issue
Block a user