feat(powermem): 升级配置结构并支持多数据库用户画像

- 重构配置结构为模块化设计(llm/embedder/vector_store)
- 用户画像功能支持oceanbase/seekdb/sqlite三种存储后端
- 更新文档说明和示例配置
This commit is contained in:
渠磊
2026-01-09 12:25:17 +08:00
parent 2bf1123647
commit 564adbd851
4 changed files with 186 additions and 176 deletions
+127 -121
View File
@@ -46,49 +46,58 @@ selected_module:
Memory: Memory:
powermem: powermem:
type: powermem type: powermem
# 是否启用用户画像功能(需要OceanBase # 是否启用用户画像功能
enable_user_profile: false # 用户画像支持: oceanbase、seekdb、sqlite (powermem 0.3.0+)
# 数据库提供者: oceanbase(推荐,最佳性能), seekdb, postgres, sqlite(轻量备选) enable_user_profile: true
database_provider: sqlite # 资源充足时建议使用 oceanbase 或 seekdb
# LLM提供者: qwen(默认), openai, 等 # ========== LLM 配置 ==========
llm_provider: qwen llm:
# 嵌入模型提供者: qwen(默认), openai, 等 provider: openai # 可选: qwen, openai, zhipu
embedding_provider: qwen config:
# LLM配置 api_key: 你的LLM API密钥
llm_api_key: 你的LLM API密钥 model: qwen-plus
llm_model: qwen-plus # openai_base_url: https://api.openai.com/v1 # 可选,自定义服务地址
# 嵌入模型配置
embedding_api_key: 你的嵌入模型API密钥 # ========== Embedding 配置 ==========
embedding_model: text-embedding-v4 embedder:
# 可选:自定义嵌入服务地址(OpenAI兼容模式) provider: openai # 可选: qwen, openai 等
# embedding_openai_base_url: https://dashscope.aliyuncs.com/compatible-mode/v1 config:
api_key: 你的嵌入模型API密钥
model: text-embedding-v4
openai_base_url: https://dashscope.aliyuncs.com/compatible-mode/v1
# ========== Database 配置 ==========
vector_store:
provider: sqlite # 可选: oceanbase(推荐), seekdb(推荐), postgres, sqlite(轻量)
config: {} # SQLite 无需额外配置
``` ```
### 配置参数详解 ### 配置参数详解
| 参数 | 说明 | 默认值 | 可选值 | #### LLM 配置
|------|------|--------|--------|
| `enable_user_profile` | 启用用户画像模式 | `false` | `true`(需OceanBase), `false` |
| `database_provider` | 存储后端类型 | `sqlite` | `oceanbase`(推荐), `seekdb`, `postgres`, `sqlite`(轻量) |
| `llm_provider` | LLM 提供商 | `qwen` | `qwen`, `zhipu`(免费), `openai`, 等 |
| `embedding_provider` | 嵌入模型提供商 | `qwen` | `qwen`, `zhipu`, `openai`, 等 |
| `llm_api_key` | LLM API 密钥 | - | - |
| `llm_model` | LLM 模型名称 | - | 根据提供商选择 |
| `llm_base_url` | LLM API 地址(可选) | - | 根据provider自动选择参数名 |
| `embedding_api_key` | 嵌入模型 API 密钥 | - | - |
| `embedding_model` | 嵌入模型名称 | - | 根据提供商选择 |
| `embedding_base_url` | 嵌入模型 API 地址(可选) | - | 通用配置,根据provider自动选择 |
| `embedding_openai_base_url` | OpenAI兼容的嵌入服务地址(可选) | - | 优先级高于 embedding_base_url |
| `embedding_dashscope_base_url` | 阿里云灵积嵌入服务地址(可选) | - | 优先级高于 embedding_base_url |
#### Base URL 配置优先级 | 参数 | 说明 | 可选值 |
|------|------|--------|
| `llm.provider` | LLM 提供商 | `qwen`, `openai`, `zhipu` 等 |
| `llm.config.api_key` | API 密钥 | - |
| `llm.config.model` | 模型名称 | 根据提供商选择 |
| `llm.config.openai_base_url` | 自定义服务地址(可选) | - |
| 配置项 | 优先级 | 适用 Provider | #### Embedding 配置
|--------|--------|---------------|
| `embedding_openai_base_url` | 最高 | openai | | 参数 | 说明 | 可选值 |
| `embedding_dashscope_base_url` | 最高 | qwen | |------|------|--------|
| `embedding_base_url` | 中 | 通用,根据 provider 自动选择 | | `embedder.provider` | 嵌入模型提供商 | `qwen`, `openai` |
| 默认值 | 最低 | 使用 provider 的默认服务地址 | | `embedder.config.api_key` | API 密钥 | - |
| `embedder.config.model` | 模型名称 | 根据提供商选择 |
| `embedder.config.openai_base_url` | 自定义服务地址(可选) | - |
#### Database 配置
| 参数 | 说明 | 可选值 |
|------|------|--------|
| `vector_store.provider` | 存储后端类型 | `oceanbase`(推荐), `seekdb`(推荐), `postgres`, `sqlite`(轻量) |
| `vector_store.config` | 数据库连接配置 | 根据 provider 设置 |
### 记忆模式说明 ### 记忆模式说明
@@ -97,7 +106,9 @@ PowerMem 支持两种记忆模式:
| 模式 | 配置 | 功能 | 存储要求 | | 模式 | 配置 | 功能 | 存储要求 |
|------|------|------|----------| |------|------|------|----------|
| **普通记忆** | `enable_user_profile: false` | 对话记忆存储与检索 | 支持所有数据库 | | **普通记忆** | `enable_user_profile: false` | 对话记忆存储与检索 | 支持所有数据库 |
| **用户画像** | `enable_user_profile: true` | 记忆 + 自动提取用户画像 | 仅支持 OceanBase | | **用户画像** | `enable_user_profile: true` | 记忆 + 自动提取用户画像 | oceanbase、seekdb、sqlite |
> 📌 **版本说明**PowerMem 0.3.0+ 版本,用户画像功能支持 OceanBase、SeekDB、SQLite 三种存储后端。
### 使用通义千问(推荐) ### 使用通义千问(推荐)
@@ -109,15 +120,21 @@ PowerMem 支持两种记忆模式:
Memory: Memory:
powermem: powermem:
type: powermem type: powermem
database_provider: sqlite enable_user_profile: true
llm_provider: qwen llm:
embedding_provider: qwen provider: qwen
llm_api_key: sk-xxxxxxxxxxxxxxxx config:
llm_model: qwen-plus api_key: sk-xxxxxxxxxxxxxxxx
embedding_api_key: sk-xxxxxxxxxxxxxxxx model: qwen-plus
embedding_model: text-embedding-v4 embedder:
# 可选:使用 OpenAI 兼容模式的服务地址 provider: openai
embedding_openai_base_url: https://dashscope.aliyuncs.com/compatible-mode/v1 config:
api_key: sk-xxxxxxxxxxxxxxxx
model: text-embedding-v4
openai_base_url: https://dashscope.aliyuncs.com/compatible-mode/v1
vector_store:
provider: sqlite
config: {}
``` ```
### 使用智谱免费 LLM(完全免费方案) ### 使用智谱免费 LLM(完全免费方案)
@@ -132,15 +149,22 @@ Memory:
Memory: Memory:
powermem: powermem:
type: powermem type: powermem
database_provider: sqlite enable_user_profile: true
llm_provider: openai # 使用 openai 兼容模式 llm:
embedding_provider: openai # 使用 openai 兼容模式 provider: openai # 使用 openai 兼容模式
llm_api_key: xxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxx config:
llm_model: glm-4-flash api_key: xxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxx
llm_base_url: https://open.bigmodel.cn/api/paas/v4/ model: glm-4-flash
embedding_api_key: xxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxx openai_base_url: https://open.bigmodel.cn/api/paas/v4/
embedding_model: embedding-3 embedder:
embedding_openai_base_url: https://open.bigmodel.cn/api/paas/v4/ provider: openai
config:
api_key: xxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxx
model: embedding-3
openai_base_url: https://open.bigmodel.cn/api/paas/v4/
vector_store:
provider: sqlite
config: {}
``` ```
### 使用 OpenAI ### 使用 OpenAI
@@ -149,15 +173,22 @@ Memory:
Memory: Memory:
powermem: powermem:
type: powermem type: powermem
database_provider: sqlite enable_user_profile: true
llm_provider: openai llm:
embedding_provider: openai provider: openai
llm_api_key: sk-xxxxxxxxxxxxxxxx config:
llm_model: gpt-4o-mini api_key: sk-xxxxxxxxxxxxxxxx
llm_base_url: https://api.openai.com/v1 model: gpt-4o-mini
embedding_api_key: sk-xxxxxxxxxxxxxxxx openai_base_url: https://api.openai.com/v1
embedding_model: text-embedding-3-small embedder:
embedding_openai_base_url: https://api.openai.com/v1 provider: openai
config:
api_key: sk-xxxxxxxxxxxxxxxx
model: text-embedding-3-small
openai_base_url: https://api.openai.com/v1
vector_store:
provider: sqlite
config: {}
``` ```
### 使用 OceanBase(最佳性能方案) ### 使用 OceanBase(最佳性能方案)
@@ -173,15 +204,18 @@ OceanBase 是 PowerMem 的最佳搭档,可实现最大性能释放:
Memory: Memory:
powermem: powermem:
type: powermem type: powermem
database_provider: oceanbase enable_user_profile: true
llm_provider: qwen llm:
embedding_provider: qwen provider: qwen
llm_api_key: sk-xxxxxxxxxxxxxxxx config:
llm_model: qwen-plus api_key: sk-xxxxxxxxxxxxxxxx
embedding_api_key: sk-xxxxxxxxxxxxxxxx model: qwen-plus
embedding_model: text-embedding-v4 embedder:
embedding_openai_base_url: https://dashscope.aliyuncs.com/compatible-mode/v1 provider: openai
# OceanBase 数据库连接配置 config:
api_key: sk-xxxxxxxxxxxxxxxx
model: text-embedding-v4
openai_base_url: https://dashscope.aliyuncs.com/compatible-mode/v1
vector_store: vector_store:
provider: oceanbase provider: oceanbase
config: config:
@@ -189,36 +223,9 @@ Memory:
port: 2881 port: 2881
user: root@test user: root@test
password: your_password password: your_password
database: powermem db_name: powermem
``` collection_name: memories # 默认值
embedding_model_dims: 1536 # 嵌入向量维度,必需参数
### 高级配置
如果需要更精细的控制,可以使用完整的配置结构:
```yaml
Memory:
powermem:
type: powermem
# 向量存储配置
vector_store:
provider: sqlite
config:
path: ./data/powermem.db
# LLM 配置
llm:
provider: qwen
config:
api_key: sk-xxxxxxxxxxxxxxxx
model: qwen-plus
# 嵌入模型配置
embedder:
provider: openai # 使用 OpenAI 兼容模式
config:
api_key: sk-xxxxxxxxxxxxxxxx
model: text-embedding-v4
openai_base_url: https://dashscope.aliyuncs.com/compatible-mode/v1
``` ```
## 设备记忆隔离 ## 设备记忆隔离
@@ -233,6 +240,8 @@ PowerMem 会自动使用设备 ID`device_id`)作为 `user_id` 进行记忆
PowerMem 提供 `UserMemory` 类,可自动从对话中提取用户画像信息。 PowerMem 提供 `UserMemory` 类,可自动从对话中提取用户画像信息。
> 📌 **版本说明**PowerMem 0.3.0+ 版本,用户画像功能支持 OceanBase、SeekDB、SQLite 三种存储后端。
### 启用用户画像 ### 启用用户画像
在配置中设置 `enable_user_profile: true` 即可启用: 在配置中设置 `enable_user_profile: true` 即可启用:
@@ -242,23 +251,20 @@ Memory:
powermem: powermem:
type: powermem type: powermem
enable_user_profile: true # 启用用户画像 enable_user_profile: true # 启用用户画像
database_provider: oceanbase # 必须使用 OceanBase llm:
llm_provider: qwen provider: qwen
embedding_provider: qwen
llm_api_key: sk-xxxxxxxxxxxxxxxx
llm_model: qwen-plus
embedding_api_key: sk-xxxxxxxxxxxxxxxx
embedding_model: text-embedding-v4
embedding_openai_base_url: https://dashscope.aliyuncs.com/compatible-mode/v1
# OceanBase 数据库连接配置
vector_store:
provider: oceanbase
config: config:
host: 127.0.0.1 api_key: sk-xxxxxxxxxxxxxxxx
port: 2881 model: qwen-plus
user: root@test embedder:
password: your_password provider: openai
database: powermem config:
api_key: sk-xxxxxxxxxxxxxxxx
model: text-embedding-v4
openai_base_url: https://dashscope.aliyuncs.com/compatible-mode/v1
vector_store:
provider: sqlite # 用户画像支持: oceanbase、seekdb、sqlite
config: {}
``` ```
### 用户画像能力 ### 用户画像能力
@@ -276,7 +282,7 @@ Memory:
1. **用户画像**:用户的基本信息、兴趣爱好等 1. **用户画像**:用户的基本信息、兴趣爱好等
2. **相关记忆**:与当前对话相关的历史记忆 2. **相关记忆**:与当前对话相关的历史记忆
> ⚠️ **注意**`UserMemory` 功能需要 OceanBase 作为存储后端,其他数据库暂不支持 > **版本说明**PowerMem 0.3.0+ 版本,用户画像功能支持 OceanBase、SeekDB、SQLite 三种存储后端
## 与其他记忆组件的对比 ## 与其他记忆组件的对比
+38 -24
View File
@@ -284,32 +284,46 @@ Memory:
# 官网: https://www.powermem.ai/ # 官网: https://www.powermem.ai/
# 使用示例: https://github.com/oceanbase/powermem/tree/main/examples # 使用示例: https://github.com/oceanbase/powermem/tree/main/examples
type: powermem type: powermem
# 是否启用用户画像功能(需要OceanBase作为存储后端) # 是否启用用户画像功能
# - false: 使用普通记忆模式(AsyncMemory),支持所有数据库 # - false: 使用普通记忆模式(AsyncMemory)
# - true: 使用用户画像模式(UserMemory),自动提取用户信息,仅支持OceanBase # - true: 使用用户画像模式(UserMemory),自动提取用户信息
enable_user_profile: false # 用户画像功能支持: oceanbase、seekdb、sqlite (powermem 0.3.0+)
# 数据库提供者: oceanbase(推荐,最佳性能), seekdb(推荐,AI应用存储一体), postgres, sqlite(轻量备选) enable_user_profile: true
# 资源充足时建议使用 oceanbase 或 seekdb
# 注意:用户画像功能(enable_user_profile: true)仅支持oceanbase # ========== LLM 配置 ==========
database_provider: sqlite
# LLM提供者: qwen(默认), zhipu(免费glm-4-flash), openai, 等
llm_provider: qwen
# 嵌入模型提供者: qwen(默认), zhipu, openai, 等
embedding_provider: qwen
# LLM配置 (使用通义千问为例)
# 通义千问: https://bailian.console.aliyun.com/?apiKey=1#/api-key # 通义千问: https://bailian.console.aliyun.com/?apiKey=1#/api-key
# 智谱AI(免费): https://bigmodel.cn/usercenter/proj-mgmt/apikeys # 智谱AI(免费): https://bigmodel.cn/usercenter/proj-mgmt/apikeys
llm_api_key: 你的LLM API密钥 llm:
llm_model: qwen-plus provider: openai # 可选: qwen, openai, zhipu 等
# llm_base_url: https://dashscope.aliyuncs.com/api/v1 # 可选,自定义LLM服务地址 config:
# 嵌入模型配置 (使用通义千问为例) api_key: 你的LLM API密钥
embedding_api_key: 你的嵌入模型API密钥 model: qwen-plus
embedding_model: text-embedding-v4 # openai_base_url: https://api.openai.com/v1 # 可选,自定义服务地址
embedding_openai_base_url: https://dashscope.aliyuncs.com/compatible-mode/v1 # OpenAI兼容的嵌入服务地址
# embedding_base_url: https://dashscope.aliyuncs.com/api/v1 # 可选,自定义嵌入模型服务地址 # ========== Embedding 配置 ==========
# 或使用独立的base_url配置(优先级更高): embedder:
# embedding_openai_base_url: https://api.openai.com/v1 # OpenAI兼容的嵌入服务地址 provider: openai # 可选: qwen, openai 等
# embedding_dashscope_base_url: https://dashscope.aliyuncs.com/api/v1 # 阿里云灵积嵌入服务地址 config:
api_key: 你的嵌入模型API密钥
model: text-embedding-v4
openai_base_url: https://dashscope.aliyuncs.com/compatible-mode/v1
# ========== Database 配置 ==========
# oceanbase(推荐,最佳性能), seekdb(推荐,AI应用存储一体), postgres, sqlite(轻量备选)
# 用户画像功能支持: oceanbase、seekdb、sqlite
vector_store:
provider: sqlite
config: {} # SQLite 无需额外配置
# OceanBase 配置示例:
# provider: oceanbase
# config:
# host: 127.0.0.1
# port: 2881
# user: root@test
# password: your_password
# db_name: powermem
# collection_name: memories # 默认值
# embedding_model_dims: 1536 # 嵌入向量维度,必需参数
nomem: nomem:
# 不想使用记忆功能,可以使用nomem # 不想使用记忆功能,可以使用nomem
type: nomem type: nomem
@@ -10,6 +10,7 @@
@Author: wayyoungboy @Author: wayyoungboy
""" """
import asyncio
import traceback import traceback
from typing import Optional, Dict, Any from typing import Optional, Dict, Any
@@ -40,6 +41,7 @@ class MemoryProvider(MemoryProviderBase):
self.use_powermem = False self.use_powermem = False
self.memory_client = None self.memory_client = None
self.enable_user_profile = False self.enable_user_profile = False
self.last_profile_content = "" # Cache for user profile from UserMemory
try: try:
# Check if user profile mode is enabled # Check if user profile mode is enabled
@@ -50,14 +52,6 @@ class MemoryProvider(MemoryProviderBase):
llm_provider = config.get("llm_provider", "qwen") llm_provider = config.get("llm_provider", "qwen")
embedding_provider = config.get("embedding_provider", "qwen") embedding_provider = config.get("embedding_provider", "qwen")
# UserMemory requires OceanBase
if self.enable_user_profile and database_provider not in ["oceanbase"]:
logger.bind(tag=TAG).warning(
f"UserMemory requires OceanBase as storage backend, but got {database_provider}. "
"Falling back to AsyncMemory mode."
)
self.enable_user_profile = False
# Build powermem configuration dict # Build powermem configuration dict
# PowerMem supports two config styles: # PowerMem supports two config styles:
# 1. powermem style: database, llm, embedding # 1. powermem style: database, llm, embedding
@@ -183,12 +177,22 @@ class MemoryProvider(MemoryProviderBase):
] ]
# Add memory using PowerMem SDK # Add memory using PowerMem SDK
result = await self.memory_client.add( result = self.memory_client.add(
messages=messages, messages=messages,
user_id=self.role_id user_id=self.role_id
) )
# Handle both sync and async returns
if asyncio.iscoroutine(result):
result = await result
logger.bind(tag=TAG).debug(f"Save memory result: {result}") logger.bind(tag=TAG).debug(f"Save memory result: {result}")
# Cache user profile if UserMemory mode and profile was extracted
if self.enable_user_profile and result:
if result.get('profile_extracted'):
self.last_profile_content = result.get('profile_content', '')
logger.bind(tag=TAG).debug(f"User profile extracted: {self.last_profile_content}")
return result return result
except Exception as e: except Exception as e:
@@ -283,6 +287,9 @@ class MemoryProvider(MemoryProviderBase):
""" """
Get user profile from PowerMem (only available in UserMemory mode). Get user profile from PowerMem (only available in UserMemory mode).
In PowerMem 0.3.0+, user profile is automatically extracted during add()
and cached in last_profile_content.
Returns: Returns:
Formatted user profile string or empty string if not available Formatted user profile string or empty string if not available
""" """
@@ -293,26 +300,9 @@ class MemoryProvider(MemoryProviderBase):
logger.bind(tag=TAG).debug("User profile mode is not enabled") logger.bind(tag=TAG).debug("User profile mode is not enabled")
return "" return ""
try: # Return cached profile content from last add() operation
if not getattr(self, "role_id", None): if self.last_profile_content:
return "" return self.last_profile_content
# Get user profile using UserMemory SDK return ""
profile = await self.memory_client.get_profile(user_id=self.role_id)
if not profile:
return ""
# Format profile as readable string
profile_parts = []
for key, value in profile.items():
if value:
profile_parts.append(f"- {key}: {value}")
return "\n".join(profile_parts)
except Exception as e:
logger.bind(tag=TAG).error(f"Error getting user profile: {str(e)}")
logger.bind(tag=TAG).debug(f"Detailed error: {traceback.format_exc()}")
return ""
+1 -1
View File
@@ -23,7 +23,7 @@ loguru==0.7.3
requests==2.32.5 requests==2.32.5
cozepy==0.20.0 cozepy==0.20.0
mem0ai==1.0.0 mem0ai==1.0.0
powermem>=0.2.1 powermem>=0.3.0
bs4==0.0.2 bs4==0.0.2
modelscope==1.32.0 modelscope==1.32.0
sherpa_onnx==1.12.17 sherpa_onnx==1.12.17