1. 添加 mem0_search 和 mem0_delete TODO实现函数. 2. 在收到新消息时,调用 mem0_search 获得相关记忆,封装到上下文 3. 在删除聊天框时候,调用 mem0_delete 以删除相关聊天框所抽取的记忆

This commit is contained in:
Gaofeng 2025-11-28 02:48:58 +08:00
parent 242bcf7c29
commit d61bb99ffa
4 changed files with 78 additions and 29 deletions

View file

@ -1588,6 +1588,7 @@ async def chat_completion(
"""处理完整的聊天流程Payload 处理 → LLM 调用 → 响应处理"""
try:
# 8.1 Payload 预处理:执行 Pipeline Filters、工具注入、RAG 检索等
# remark并不涉及消息的持久化只涉及发送给 LLM 前,上下文的封装
form_data, metadata, events = await process_chat_payload(
request, form_data, user, metadata, model
)

View file

@ -0,0 +1,33 @@
async def mem0_search(user_id: str, chat_id: str, last_message: str) -> list[str]:
"""
预留的 Mem0 检索接口当前为占位实现
未来可替换为实际检索逻辑返回若干相关记忆条目字符串
增加 chat_id 便于按会话窗口区分/隔离记忆
"""
try:
# TODO: 接入真实 Mem0 检索
print("mem0_search")
print("user_id:", user_id)
print("chat_id:", chat_id)
print("last_message:", last_message)
return []
except Exception as e:
log.debug(f"Mem0 search failed: {e}")
return []
async def mem0_delete(user_id: str, chat_id: str) -> bool:
"""
删除指定用户在指定 chat 窗口下的所有 Mem0 相关记忆占位实现
未来可替换为实际删除逻辑
"""
try:
# TODO: 接入真实删除逻辑(如按 chat_id 过滤)
print("mem0_delete")
print("user_id:", user_id)
print("chat_id:", chat_id)
return True
except Exception as e:
log.debug(f"Mem0 delete failed: {e}")
return False

View file

@ -19,6 +19,7 @@ from open_webui.constants import ERROR_MESSAGES
from open_webui.env import SRC_LOG_LEVELS
from fastapi import APIRouter, Depends, HTTPException, Request, status
from pydantic import BaseModel
from open_webui.memory.mem0 import mem0_delete
from open_webui.utils.auth import get_admin_user, get_verified_user
@ -654,6 +655,9 @@ async def delete_chat_by_id(request: Request, id: str, user=Depends(get_verified
# === 管理员分支 ===
if user.role == "admin":
chat = Chats.get_chat_by_id(id)
# 清理该聊天的 Mem0 记忆条目
await mem0_delete(chat.user_id, id)
# 清理孤立标签(仅被该聊天使用的标签)
for tag in chat.meta.get("tags", []):
@ -676,6 +680,9 @@ async def delete_chat_by_id(request: Request, id: str, user=Depends(get_verified
chat = Chats.get_chat_by_id(id)
# 清理该聊天的 Mem0 记忆条目
await mem0_delete(user.id, id)
# 清理孤立标签
for tag in chat.meta.get("tags", []):
if Chats.count_chats_by_tag_name_and_user_id(tag, user.id) == 1:

View file

@ -54,7 +54,8 @@ from open_webui.routers.pipelines import (
process_pipeline_inlet_filter,
process_pipeline_outlet_filter,
)
from open_webui.routers.memories import query_memory, QueryMemoryForm
from open_webui.models.memories import Memories
from open_webui.memory.mem0 import mem0_search
from open_webui.utils.webhook import post_webhook
from open_webui.utils.files import (
@ -517,37 +518,44 @@ async def chat_completion_tools_handler(
async def chat_memory_handler(
request: Request, form_data: dict, extra_params: dict, user
request: Request, form_data: dict, extra_params: dict, user, metadata
):
try:
results = await query_memory(
request,
QueryMemoryForm(
**{
"content": get_last_user_message(form_data["messages"]) or "",
"k": 3,
}
),
user,
)
except Exception as e:
log.debug(e)
results = None
"""
聊天记忆处理器 - 注入用户手动保存的记忆 + Mem0 检索结果到当前对话上下文
新增行为
1. memory 特性开启时直接注入用户所有记忆条目不再做 RAG Top-K
2. 预留 Mem0 检索使用最后一条用户消息查询 Mem0返回的条目也一并注入
3. 上下文注入方式保持不变统一写入 System Message
"""
user_message = get_last_user_message(form_data.get("messages", [])) or ""
# === 1. 获取用户全部记忆(不再截断 Top-K ===
memories = Memories.get_memories_by_user_id(user.id) or []
# === 2. 预留的 Mem0 检索结果 ===
mem0_results = await mem0_search(user.id, metadata.get("chat_id"), user_message)
# === 3. 格式化记忆条目 ===
entries = []
# 3.1 用户记忆库全量
for mem in memories:
created_at_date = time.strftime("%Y-%m-%d", time.localtime(mem.created_at)) if mem.created_at else "Unknown Date"
entries.append(f"[{created_at_date}] {mem.content}")
# 3.2 Mem0 检索结果
for item in mem0_results:
entries.append(f"[Mem0] {item}")
if not entries:
return form_data
user_context = ""
if results and hasattr(results, "documents"):
if results.documents and len(results.documents) > 0:
for doc_idx, doc in enumerate(results.documents[0]):
created_at_date = "Unknown Date"
if results.metadatas[0][doc_idx].get("created_at"):
created_at_timestamp = results.metadatas[0][doc_idx]["created_at"]
created_at_date = time.strftime(
"%Y-%m-%d", time.localtime(created_at_timestamp)
)
user_context += f"{doc_idx + 1}. [{created_at_date}] {doc}\n"
for idx, entry in enumerate(entries):
user_context += f"{idx + 1}. {entry}\n"
# === 4. 将记忆注入到系统消息中 ===
form_data["messages"] = add_or_update_system_message(
f"User Context:\n{user_context}\n", form_data["messages"], append=True
)
@ -1189,7 +1197,7 @@ async def process_chat_payload(request, form_data, user, metadata, model):
# 12.1 记忆功能 - 注入历史对话记忆
if "memory" in features and features["memory"]:
form_data = await chat_memory_handler(
request, form_data, extra_params, user
request, form_data, extra_params, user, metadata
)
# 12.2 网页搜索功能 - 执行网络搜索