feat: v2.0.0 架构重构 - 大模型池、Agent管理、渠道独立绑定、思考功能
This commit is contained in:
+342
@@ -0,0 +1,342 @@
|
||||
"""
|
||||
AI对话系统 v2.0.0 - 数据库模型重构
|
||||
支持:大模型池、Agent管理、渠道独立绑定、思考功能开关
|
||||
"""
|
||||
from sqlalchemy import create_engine, Column, Integer, String, Text, Boolean, DateTime, ForeignKey, JSON, Float
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import sessionmaker, relationship
|
||||
from datetime import datetime
|
||||
import os
|
||||
|
||||
DATABASE_URL = os.environ.get('DATABASE_URL', 'sqlite:///./ai_chat_v2.db')
|
||||
|
||||
engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
|
||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
# ==================== 大模型池 ====================
|
||||
|
||||
class LLMProvider(Base):
|
||||
"""大模型提供商/池配置"""
|
||||
__tablename__ = 'llm_providers'
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
name = Column(String(100), unique=True, index=True) # 名称标识,如 "DeepSeek", "本地LLM"
|
||||
api_base = Column(String(500)) # API地址
|
||||
api_key = Column(String(500)) # API密钥
|
||||
models = Column(JSON, default=list) # 可用模型列表 [{"id": "xxx", "name": "xxx"}]
|
||||
default_model = Column(String(100)) # 默认模型
|
||||
|
||||
# 思考功能支持
|
||||
supports_thinking = Column(Boolean, default=False) # 是否原生支持思考
|
||||
thinking_model = Column(String(100), nullable=True) # 思考模式模型名(如有单独模型)
|
||||
|
||||
# 配额和限制
|
||||
max_tokens = Column(Integer, default=4096)
|
||||
temperature = Column(Float, default=0.7)
|
||||
|
||||
# 状态
|
||||
is_active = Column(Boolean, default=True)
|
||||
priority = Column(Integer, default=0) # 优先级,用于自动选择
|
||||
description = Column(Text, nullable=True)
|
||||
|
||||
created_at = Column(DateTime, default=datetime.utcnow)
|
||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
# 关联
|
||||
agents = relationship("Agent", back_populates="llm_provider")
|
||||
|
||||
|
||||
# ==================== Agent ====================
|
||||
|
||||
class Agent(Base):
|
||||
"""智能体配置"""
|
||||
__tablename__ = 'agents'
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
name = Column(String(100), unique=True, index=True) # Agent名称
|
||||
display_name = Column(String(100)) # 显示名称
|
||||
|
||||
# 大模型配置
|
||||
llm_provider_id = Column(Integer, ForeignKey('llm_providers.id'))
|
||||
model_override = Column(String(100), nullable=True) # 覆盖Provider默认模型
|
||||
|
||||
# 系统设定
|
||||
system_prompt = Column(Text, default="你是一个有用的AI助手。") # 系统提示词
|
||||
|
||||
# 思考功能
|
||||
enable_thinking = Column(Boolean, default=True) # 是否启用思考
|
||||
thinking_prompt = Column(Text, nullable=True) # 思考提示词模板
|
||||
thinking_prefix = Column(String(50), default="<think>") # 思考内容前缀标识
|
||||
thinking_suffix = Column(String(50), default="</think>") # 思考内容后缀标识
|
||||
|
||||
# 其他配置
|
||||
max_history = Column(Integer, default=20) # 最大历史消息数
|
||||
temperature_override = Column(Float, nullable=True) # 覆盖温度
|
||||
|
||||
# 状态
|
||||
is_active = Column(Boolean, default=True)
|
||||
is_default = Column(Boolean, default=False) # 是否为默认Agent
|
||||
description = Column(Text, nullable=True)
|
||||
|
||||
created_at = Column(DateTime, default=datetime.utcnow)
|
||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
# 关联
|
||||
llm_provider = relationship("LLMProvider", back_populates="agents")
|
||||
channel_mappings = relationship("ChannelAgentMapping", back_populates="agent")
|
||||
|
||||
|
||||
# ==================== 渠道 ====================
|
||||
|
||||
class Channel(Base):
|
||||
"""渠道配置 - 网页端、Matrix端等"""
|
||||
__tablename__ = 'channels'
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
channel_type = Column(String(20), index=True) # web, matrix, telegram, etc.
|
||||
name = Column(String(100)) # 渠道名称,如 "网页端主入口", "Matrix AI Bot"
|
||||
|
||||
# 渠道配置(JSON)
|
||||
config = Column(JSON, default=dict)
|
||||
# Matrix示例: {"homeserver": "xxx", "username": "xxx", "password": "xxx"}
|
||||
# Web示例: {"require_login": false, "session_timeout": 3600}
|
||||
|
||||
# 状态
|
||||
is_active = Column(Boolean, default=True)
|
||||
is_primary = Column(Boolean, default=False) # 是否为主要渠道
|
||||
|
||||
created_at = Column(DateTime, default=datetime.utcnow)
|
||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
# 关联
|
||||
agent_mappings = relationship("ChannelAgentMapping", back_populates="channel", order_by="ChannelAgentMapping.priority")
|
||||
conversations = relationship("Conversation", back_populates="channel")
|
||||
|
||||
|
||||
# ==================== 渠道-Agent映射 ====================
|
||||
|
||||
class ChannelAgentMapping(Base):
|
||||
"""渠道与Agent的映射关系"""
|
||||
__tablename__ = 'channel_agent_mappings'
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
channel_id = Column(Integer, ForeignKey('channels.id'))
|
||||
agent_id = Column(Integer, ForeignKey('agents.id'))
|
||||
|
||||
# 映射配置
|
||||
priority = Column(Integer, default=0) # 优先级(数字越小优先级越高)
|
||||
mode = Column(String(20), default='single') # single(单Agent), round_robin(轮询), fallback(备用)
|
||||
weight = Column(Integer, default=1) # 轮询权重
|
||||
|
||||
# 条件配置(可选)
|
||||
conditions = Column(JSON, nullable=True) # 条件触发,如 {"user_type": "vip"}
|
||||
|
||||
is_active = Column(Boolean, default=True)
|
||||
created_at = Column(DateTime, default=datetime.utcnow)
|
||||
|
||||
# 关联
|
||||
channel = relationship("Channel", back_populates="agent_mappings")
|
||||
agent = relationship("Agent", back_populates="channel_mappings")
|
||||
|
||||
|
||||
# ==================== 用户和会话(保留原有结构,增加渠道关联) ====================
|
||||
|
||||
class User(Base):
|
||||
"""用户表"""
|
||||
__tablename__ = 'users'
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
user_id = Column(String(100), unique=True, index=True)
|
||||
display_name = Column(String(100))
|
||||
user_type = Column(String(20), default='web') # web, matrix, telegram
|
||||
matrix_user_id = Column(String(200), nullable=True)
|
||||
|
||||
# 用户级别(用于Agent选择条件)
|
||||
user_level = Column(String(20), default='normal') # normal, vip, admin
|
||||
|
||||
created_at = Column(DateTime, default=datetime.utcnow)
|
||||
last_active_at = Column(DateTime, default=datetime.utcnow)
|
||||
is_active = Column(Boolean, default=True)
|
||||
|
||||
conversations = relationship("Conversation", back_populates="user")
|
||||
|
||||
|
||||
class Conversation(Base):
|
||||
"""对话会话"""
|
||||
__tablename__ = 'conversations'
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
conversation_id = Column(String(100), unique=True, index=True)
|
||||
user_id = Column(Integer, ForeignKey('users.id'))
|
||||
channel_id = Column(Integer, ForeignKey('channels.id'), nullable=True) # 新增渠道关联
|
||||
|
||||
title = Column(String(200), nullable=True)
|
||||
|
||||
# 当前使用的Agent(会话可切换Agent)
|
||||
current_agent_id = Column(Integer, ForeignKey('agents.id'), nullable=True)
|
||||
|
||||
created_at = Column(DateTime, default=datetime.utcnow)
|
||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
is_active = Column(Boolean, default=True)
|
||||
extra_data = Column(JSON, nullable=True)
|
||||
|
||||
user = relationship("User", back_populates="conversations")
|
||||
channel = relationship("Channel", back_populates="conversations")
|
||||
messages = relationship("Message", back_populates="conversation")
|
||||
|
||||
|
||||
class Message(Base):
|
||||
"""消息表"""
|
||||
__tablename__ = 'messages'
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
conversation_id = Column(Integer, ForeignKey('conversations.id'))
|
||||
role = Column(String(20)) # user, assistant, system, thinking(思考过程)
|
||||
content = Column(Text)
|
||||
source = Column(String(20)) # web, matrix
|
||||
|
||||
# 思考内容(如果启用了思考功能)
|
||||
thinking_content = Column(Text, nullable=True) # 思考过程
|
||||
|
||||
# Agent信息
|
||||
agent_id = Column(Integer, ForeignKey('agents.id'), nullable=True) # 生成此消息的Agent
|
||||
model_used = Column(String(100), nullable=True) # 使用的模型
|
||||
|
||||
created_at = Column(DateTime, default=datetime.utcnow)
|
||||
extra_data = Column(JSON, nullable=True)
|
||||
|
||||
conversation = relationship("Conversation", back_populates="messages")
|
||||
|
||||
|
||||
# ==================== Matrix房间映射(保留) ====================
|
||||
|
||||
class MatrixRoomMapping(Base):
|
||||
"""Matrix房间映射"""
|
||||
__tablename__ = 'matrix_room_mapping'
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
room_id = Column(String(200), unique=True, index=True)
|
||||
user_id = Column(Integer, ForeignKey('users.id'))
|
||||
conversation_id = Column(Integer, ForeignKey('conversations.id'))
|
||||
channel_id = Column(Integer, ForeignKey('channels.id'), nullable=True)
|
||||
created_at = Column(DateTime, default=datetime.utcnow)
|
||||
|
||||
|
||||
# ==================== 系统配置(保留) ====================
|
||||
|
||||
class SystemConfig(Base):
|
||||
"""系统配置表"""
|
||||
__tablename__ = 'system_config'
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
key = Column(String(100), unique=True, index=True)
|
||||
value = Column(Text)
|
||||
description = Column(String(500))
|
||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
|
||||
def init_db():
|
||||
"""初始化数据库"""
|
||||
Base.metadata.create_all(bind=engine)
|
||||
|
||||
|
||||
def get_db():
|
||||
"""获取数据库会话"""
|
||||
db = SessionLocal()
|
||||
try:
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
# ==================== 初始化默认数据 ====================
|
||||
|
||||
def init_default_data():
|
||||
"""初始化默认数据:大模型池、Agent、渠道"""
|
||||
db = SessionLocal()
|
||||
try:
|
||||
# 检查是否已有数据
|
||||
if db.query(LLMProvider).count() > 0:
|
||||
return
|
||||
|
||||
# 1. 创建默认大模型池
|
||||
default_llm = LLMProvider(
|
||||
name="本地LLM Proxy",
|
||||
api_base="http://192.168.2.17:19007/v1",
|
||||
api_key="xxxx",
|
||||
models=[
|
||||
{"id": "auto", "name": "auto (自动选择)"},
|
||||
{"id": "qwen3.5-4b", "name": "qwen3.5-4b"},
|
||||
{"id": "dsv32", "name": "dsv32"},
|
||||
{"id": "glm-4", "name": "glm-4"}
|
||||
],
|
||||
default_model="auto",
|
||||
supports_thinking=False,
|
||||
is_active=True,
|
||||
priority=0,
|
||||
description="本地LLM代理服务"
|
||||
)
|
||||
db.add(default_llm)
|
||||
|
||||
# 2. 创建默认Agent
|
||||
default_agent = Agent(
|
||||
name="default",
|
||||
display_name="默认助手",
|
||||
llm_provider_id=1,
|
||||
system_prompt="你是一个有用的AI助手。",
|
||||
enable_thinking=True,
|
||||
thinking_prompt="请先仔细思考这个问题,然后给出回答。",
|
||||
is_active=True,
|
||||
is_default=True,
|
||||
description="默认AI助手"
|
||||
)
|
||||
db.add(default_agent)
|
||||
|
||||
# 3. 创建渠道
|
||||
web_channel = Channel(
|
||||
channel_type="web",
|
||||
name="网页端",
|
||||
config={"require_login": False},
|
||||
is_active=True,
|
||||
is_primary=True
|
||||
)
|
||||
db.add(web_channel)
|
||||
|
||||
matrix_channel = Channel(
|
||||
channel_type="matrix",
|
||||
name="Matrix AI Bot",
|
||||
config={
|
||||
"homeserver": "http://matrix.tphai.com",
|
||||
"username": "@tester:matrix.tphai.com",
|
||||
"password": "tester12345@!"
|
||||
},
|
||||
is_active=True
|
||||
)
|
||||
db.add(matrix_channel)
|
||||
|
||||
db.commit()
|
||||
|
||||
# 4. 创建渠道-Agent映射
|
||||
web_mapping = ChannelAgentMapping(
|
||||
channel_id=1,
|
||||
agent_id=1,
|
||||
priority=0,
|
||||
mode='single'
|
||||
)
|
||||
db.add(web_mapping)
|
||||
|
||||
matrix_mapping = ChannelAgentMapping(
|
||||
channel_id=2,
|
||||
agent_id=1,
|
||||
priority=0,
|
||||
mode='single'
|
||||
)
|
||||
db.add(matrix_mapping)
|
||||
|
||||
db.commit()
|
||||
print("默认数据初始化完成")
|
||||
|
||||
finally:
|
||||
db.close()
|
||||
Reference in New Issue
Block a user