|
|
6 mesi fa | |
|---|---|---|
| .. | ||
| README.md | 6 mesi fa | |
| api.md | 6 mesi fa | |
| frontend.md | 6 mesi fa | |
| frontend.s.md | 6 mesi fa | |
本项目旨在实现一个类似 Claude 的聊天系统,支持以下核心功能:
系统支持标准的 Function Call 流程:
user → assistant(tool_calls) → tool(result) → assistant(final_response)
所有相关消息归属同一个 session,前端显示为一个完整的 AI 回复。
系统采用软删除策略,保护用户数据安全:
deleted_at 字段存储每个独立的聊天会话。
CREATE TABLE chats (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
uid CHAR(36) NOT NULL UNIQUE COMMENT 'UUID唯一标识',
title VARCHAR(255) NOT NULL COMMENT '聊天标题',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL COMMENT '软删除时间戳',
user_id CHAR(36) COMMENT '用户ID',
INDEX idx_chats_uid (uid),
INDEX idx_chats_user_id (user_id),
INDEX idx_chats_created_at (created_at),
INDEX idx_chats_deleted_at (deleted_at)
) COMMENT '聊天会话表';
存储所有消息,支持树形结构和版本控制。role=system 为消息树的唯一根节点。不可修改,不可删除。
CREATE TABLE chat_messages (
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '自增主键,提供天然时间排序',
uid CHAR(36) NOT NULL UNIQUE COMMENT 'UUID唯一标识',
chat_id CHAR(36) NOT NULL COMMENT '关联chats.uid',
parent_id CHAR(36) COMMENT '关联chat_messages.uid,NULL表示根节点',
session_id CHAR(36) NOT NULL COMMENT '会话段ID,同一消息组共享',
role ENUM('system','user', 'assistant', 'tool') NOT NULL COMMENT '消息角色',
content TEXT COMMENT '消息内容',
model_id CHAR(36) COMMENT '使用的模型id(assistant消息)',
tool_calls JSON COMMENT '函数调用信息(assistant消息)',
tool_call_id VARCHAR(100) COMMENT '工具调用ID(tool消息)',
metadata JSON COMMENT '消息元数据:生成参数、token统计等',
is_active BOOLEAN DEFAULT TRUE COMMENT '是否为当前激活版本',
editor_id CHAR(36) COMMENT '最后编辑用户ID',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL COMMENT '软删除时间戳',
INDEX idx_messages_uid (uid),
INDEX idx_messages_chat_id (chat_id),
INDEX idx_messages_parent_id (parent_id),
INDEX idx_messages_session_id (session_id),
INDEX idx_messages_active (chat_id, is_active),
INDEX idx_messages_deleted_at (deleted_at)
) COMMENT '聊天消息表';
id: 自增主键,数据库内部使用uid: UUID 标识,用于外部引用和 APItitle: 聊天标题,可从首条消息自动生成user_id: 用户标识(可选,如果需要多用户支持)deleted_at: 软删除时间戳,NULL 表示未删除id: 自增主键,提供天然的消息时间顺序uid: UUID 标识,用于 parent_id 引用,保证跨系统稳定性parent_id: 指向父消息的 uid,构建技术依赖关系session_id: 消息组标识,相同 session_id 的消息在前端显示为一组role: 消息类型(user 用户/assistant 助手/tool 工具结果)tool_calls: JSON 格式存储函数调用信息tool_call_id: 关联 tool 消息到具体的函数调用metadata: 消息生成相关参数和统计信息is_active: 标记用户当前查看的版本deleted_at: 软删除时间戳,NULL 表示未删除metadata 字段存储与消息生成相关的参数和统计信息:
{
// AI生成参数(assistant消息)
"generation_params": {
"temperature": 0.7,
"max_tokens": 2048,
"top_p": 0.9,
"frequency_penalty": 0.0,
"presence_penalty": 0.0
},
// Token使用统计
"token_usage": {
"prompt_tokens": 150,
"completion_tokens": 320,
"total_tokens": 470
},
// 性能指标
"performance": {
"response_time_ms": 1250,
"first_token_time_ms": 450
},
// 工具调用统计(如适用)
"tool_stats": {
"total_calls": 2,
"successful_calls": 2,
"execution_time_ms": 340
},
// 其他扩展信息
"custom_data": {}
}
维护 Function Call 的执行链:
user(id=1)
↓ parent_id=uuid1
assistant(id=2, tool_calls=[...])
↓ parent_id=uuid2
tool(id=3, tool_call_id=xxx)
↓ parent_id=uuid3
assistant(id=4, final_response)
将相关消息组织成前端显示单元:
Session 1: [user消息]
Session 2: [assistant + tool + assistant] -> 显示为一个AI回复
Session 3: [user消息]
-- 软删除聊天(级联删除所有消息)
UPDATE chats SET deleted_at = CURRENT_TIMESTAMP WHERE uid = ?;
UPDATE chat_messages SET deleted_at = CURRENT_TIMESTAMP WHERE chat_id = ?;
-- 软删除单个消息
UPDATE chat_messages SET deleted_at = CURRENT_TIMESTAMP WHERE uid = ?;
所有业务查询都需要过滤已删除数据:
-- 查询示例
SELECT * FROM chats WHERE deleted_at IS NULL;
SELECT * FROM chat_messages WHERE deleted_at IS NULL;
-- 恢复聊天
UPDATE chats SET deleted_at = NULL WHERE uid = ?;
-- 恢复消息
UPDATE chat_messages SET deleted_at = NULL WHERE uid = ?;
-- Chat记录
INSERT INTO chats (id, uid, title) VALUES
(1, 'chat-uuid-1', '天气查询对话');
-- 消息记录
INSERT INTO chat_messages (id, uid, chat_id, parent_id, session_id, role, content, metadata) VALUES
-- Session 1: 用户提问
(1, 'msg-uuid-1', 'chat-uuid-1', NULL, 'session-uuid-1', 'user', '查询今天天气', NULL),
-- Session 2: AI处理流程
(2, 'msg-uuid-2', 'chat-uuid-1', 'msg-uuid-1', 'session-uuid-2', 'assistant', NULL,
'{"generation_params":{"temperature":0.7,"max_tokens":2048},"token_usage":{"prompt_tokens":20,"completion_tokens":50,"total_tokens":70}}'),
(3, 'msg-uuid-3', 'chat-uuid-1', 'msg-uuid-2', 'session-uuid-2', 'tool', '今天晴天,25°C',
'{"tool_stats":{"execution_time_ms":340}}'),
(4, 'msg-uuid-4', 'chat-uuid-1', 'msg-uuid-3', 'session-uuid-2', 'assistant', '今天天气晴朗,气温25度...',
'{"generation_params":{"temperature":0.7},"token_usage":{"prompt_tokens":100,"completion_tokens":80,"total_tokens":180},"performance":{"response_time_ms":1250}}'),
-- Session 3: 用户继续提问
(5, 'msg-uuid-5', 'chat-uuid-1', 'msg-uuid-4', 'session-uuid-3', 'user', '那明天呢?', NULL);
[
{
"id": "call_123",
"function": "get_weather",
"arguments": {
"city": "北京",
"date": "today"
}
}
]
SELECT DISTINCT session_id, MIN(id) as first_message_id
FROM chat_messages
WHERE chat_id = ? AND is_active = true AND deleted_at IS NULL
ORDER BY first_message_id;
SELECT * FROM chat_messages
WHERE session_id = ? AND is_active = true AND deleted_at IS NULL
ORDER BY id;
-- 获取当前激活路径的所有消息
WITH RECURSIVE active_path AS (
SELECT * FROM chat_messages
WHERE chat_id = ? AND parent_id IS NULL AND is_active = true AND deleted_at IS NULL
UNION ALL
SELECT m.* FROM chat_messages m
JOIN active_path p ON m.parent_id = p.uid
WHERE m.is_active = true AND m.deleted_at IS NULL
)
SELECT * FROM active_path ORDER BY id;
SELECT *,
CASE WHEN deleted_at IS NULL THEN 'active' ELSE 'deleted' END as status
FROM chat_messages
WHERE parent_id = ? AND role = ?
ORDER BY created_at;
-- 查询聊天的总token使用量
SELECT
chat_id,
SUM(JSON_EXTRACT(metadata, '$.token_usage.total_tokens')) as total_tokens,
AVG(JSON_EXTRACT(metadata, '$.performance.response_time_ms')) as avg_response_time
FROM chat_messages
WHERE chat_id = ? AND role = 'assistant' AND deleted_at IS NULL
GROUP BY chat_id;
chat_id: 快速查询某个聊天的所有消息session_id: 快速获取消息组parent_id: 支持树形查询和兄弟节点查询(chat_id, is_active): 快速获取激活消息deleted_at: 快速过滤软删除数据deleted_at IS NULL 条件文档版本: 1.1
创建时间: 2025-09-07
更新时间: 2025-09-09
修订说明: 增加 metadata 字段和软删除机制