Build lightweight AI agent admin
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
"""
|
||||
AI 平台数据模型
|
||||
"""
|
||||
from .provider import LLMProvider
|
||||
from .model import LLMModel
|
||||
from .app import AIApp
|
||||
from .conversation import Conversation, Message
|
||||
from .workflow import AIWorkflow, AIWorkflowVersion, AIWorkflowRun
|
||||
from .prompt_template import PromptTemplate
|
||||
from .agent import Agent, AgentConversation, AgentMessage
|
||||
from ai_platform.knowledge.models import KnowledgeBase, KnowledgeDocument, KnowledgeSegment
|
||||
|
||||
__all__ = [
|
||||
'LLMProvider',
|
||||
'LLMModel',
|
||||
'AIApp',
|
||||
'Conversation',
|
||||
'Message',
|
||||
'AIWorkflow',
|
||||
'AIWorkflowVersion',
|
||||
'AIWorkflowRun',
|
||||
'PromptTemplate',
|
||||
'Agent',
|
||||
'AgentConversation',
|
||||
'AgentMessage',
|
||||
'KnowledgeBase',
|
||||
'KnowledgeDocument',
|
||||
'KnowledgeSegment',
|
||||
]
|
||||
@@ -0,0 +1,95 @@
|
||||
"""
|
||||
智能体模型
|
||||
"""
|
||||
from sqlalchemy import Column, String, Text, Float, Integer, Boolean, JSON, Index
|
||||
|
||||
from app.base_model import BaseModel
|
||||
|
||||
|
||||
class Agent(BaseModel):
|
||||
"""
|
||||
智能体定义
|
||||
|
||||
智能体是一个能够自主决策、调用工具、多轮推理的 AI 实体
|
||||
支持两种模式:
|
||||
- autonomous: 自主规划模式 - Agent 自动拆解任务并执行
|
||||
- dialog_flow: 对话流模式 - 按预定义流程与用户交互
|
||||
"""
|
||||
__tablename__ = "ai_agent"
|
||||
|
||||
application_id = Column(String(21), nullable=True, index=True, comment="所属应用ID(逻辑外键关联core_application)")
|
||||
is_global = Column(Boolean, default=False, comment="是否在子应用中可见")
|
||||
name = Column(String(100), nullable=False, comment="智能体名称")
|
||||
code = Column(String(100), unique=True, nullable=False, comment="智能体编码")
|
||||
description = Column(Text, default="", comment="智能体描述")
|
||||
avatar = Column(String(500), default="", comment="头像 URL")
|
||||
mode = Column(String(20), default="autonomous", comment="运行模式: autonomous/dialog_flow")
|
||||
status = Column(String(20), default="draft", comment="状态: draft/published/disabled")
|
||||
persona = Column(JSON, default=dict, comment="人设配置")
|
||||
system_prompt = Column(Text, default="", comment="系统提示词")
|
||||
model_id = Column(String(21), nullable=True, index=True, comment="默认模型ID(逻辑外键关联ai_llm_model)")
|
||||
temperature = Column(Float, default=0.7, comment="温度参数(0-2)")
|
||||
top_p = Column(Float, default=1.0, comment="top_p 参数")
|
||||
max_tokens = Column(Integer, default=4096, comment="最大输出 Token")
|
||||
max_iterations = Column(Integer, default=10, comment="最大推理轮数")
|
||||
welcome_message = Column(Text, default="", comment="开场白")
|
||||
suggested_questions = Column(JSON, default=list, comment="推荐问题列表")
|
||||
workflow_id = Column(String(21), nullable=True, index=True, comment="关联工作流ID(逻辑外键关联ai_workflow)")
|
||||
enable_memory = Column(Boolean, default=False, comment="是否启用对话记忆")
|
||||
memory_window = Column(Integer, default=10, comment="记忆窗口大小(最近 N 轮对话)")
|
||||
enable_streaming = Column(Boolean, default=True, comment="是否启用流式输出(自主规划模式)")
|
||||
knowledge_base_ids = Column(JSON, default=list, comment="关联的知识库ID列表")
|
||||
knowledge_config = Column(JSON, default=dict, comment="知识库检索配置(top_k/score_threshold/retrieval_mode等)")
|
||||
is_public = Column(Boolean, default=False, comment="是否公开")
|
||||
conversation_count = Column(Integer, default=0, comment="对话数量")
|
||||
message_count = Column(Integer, default=0, comment="消息数量")
|
||||
total_tokens = Column(Integer, default=0, comment="总 Token 消耗")
|
||||
|
||||
|
||||
class AgentConversation(BaseModel):
|
||||
"""
|
||||
智能体对话
|
||||
"""
|
||||
__tablename__ = "ai_agent_conversation"
|
||||
|
||||
agent_id = Column(String(21), nullable=False, index=True, comment="智能体ID(逻辑外键关联ai_agent)")
|
||||
user_id = Column(String(21), nullable=True, index=True, comment="用户ID(逻辑外键关联core_user)")
|
||||
title = Column(String(200), default="", comment="对话标题")
|
||||
summary = Column(Text, default="", comment="对话摘要")
|
||||
workflow_run_id = Column(String(21), nullable=True, comment="工作流运行实例ID(逻辑外键关联ai_workflow_run)")
|
||||
waiting_node_id = Column(String(100), default="", comment="等待输入的节点 ID")
|
||||
extra_data = Column(JSON, default=dict, comment="元数据")
|
||||
message_count = Column(Integer, default=0, comment="消息数量")
|
||||
total_tokens = Column(Integer, default=0, comment="总 Token 消耗")
|
||||
|
||||
__table_args__ = (
|
||||
Index("ix_ai_agent_conversation_agent_user", "agent_id", "user_id"),
|
||||
)
|
||||
|
||||
|
||||
class AgentMessage(BaseModel):
|
||||
"""
|
||||
智能体消息
|
||||
|
||||
记录对话中的每条消息,包括用户消息、助手回复、工具调用等
|
||||
"""
|
||||
__tablename__ = "ai_agent_message"
|
||||
|
||||
conversation_id = Column(String(21), nullable=False, index=True, comment="对话ID(逻辑外键关联ai_agent_conversation)")
|
||||
role = Column(String(20), nullable=False, comment="角色: user/assistant/tool/system")
|
||||
content = Column(Text, default="", comment="消息内容")
|
||||
attachments = Column(JSON, default=list, comment="附件列表 [{id, type, name, url, mime_type, size}]")
|
||||
status = Column(String(20), default="completed", comment="状态: pending/completed/failed")
|
||||
reasoning_steps = Column(JSON, default=list, comment="推理步骤")
|
||||
tool_calls = Column(JSON, default=list, comment="工具调用记录")
|
||||
prompt_tokens = Column(Integer, default=0, comment="提示 Token")
|
||||
completion_tokens = Column(Integer, default=0, comment="生成 Token")
|
||||
total_tokens = Column(Integer, default=0, comment="总 Token")
|
||||
elapsed_time = Column(Integer, default=0, comment="耗时(毫秒)")
|
||||
error_message = Column(Text, default="", comment="错误信息")
|
||||
feedback = Column(String(20), default="", comment="用户反馈(like/dislike)")
|
||||
feedback_content = Column(Text, default="", comment="反馈内容")
|
||||
|
||||
__table_args__ = (
|
||||
Index("ix_ai_agent_message_conversation_role", "conversation_id", "role"),
|
||||
)
|
||||
@@ -0,0 +1,37 @@
|
||||
"""
|
||||
AI 应用模型
|
||||
"""
|
||||
from sqlalchemy import Column, String, Text, Float, Integer, Boolean, JSON
|
||||
|
||||
from app.base_model import BaseModel
|
||||
|
||||
|
||||
class AIApp(BaseModel):
|
||||
"""
|
||||
AI 应用
|
||||
|
||||
支持的应用类型:
|
||||
- chat: 聊天助手
|
||||
- completion: 文本生成
|
||||
- workflow: 工作流应用
|
||||
- agent: Agent 应用(预留)
|
||||
"""
|
||||
__tablename__ = "ai_app"
|
||||
|
||||
name = Column(String(100), nullable=False, comment="应用名称")
|
||||
code = Column(String(100), unique=True, nullable=False, comment="应用编码")
|
||||
description = Column(Text, default="", comment="应用描述")
|
||||
icon = Column(String(100), default="", comment="应用图标")
|
||||
app_type = Column(String(20), default="chat", comment="应用类型: chat/completion/workflow/agent")
|
||||
status = Column(String(20), default="draft", comment="状态: draft/published/disabled")
|
||||
model_id = Column(String(21), nullable=True, index=True, comment="默认模型ID(逻辑外键关联ai_llm_model)")
|
||||
system_prompt = Column(Text, default="", comment="系统提示词")
|
||||
temperature = Column(Float, default=0.7, comment="温度参数")
|
||||
top_p = Column(Float, default=1.0, comment="top_p 参数")
|
||||
max_tokens = Column(Integer, default=2048, comment="最大输出 Token")
|
||||
workflow_definition = Column(JSON, default=dict, comment="工作流定义")
|
||||
opening_statement = Column(Text, default="", comment="开场白")
|
||||
suggested_questions = Column(JSON, default=list, comment="建议问题列表")
|
||||
is_public = Column(Boolean, default=False, comment="是否公开")
|
||||
conversation_count = Column(Integer, default=0, comment="对话数量")
|
||||
message_count = Column(Integer, default=0, comment="消息数量")
|
||||
@@ -0,0 +1,50 @@
|
||||
"""
|
||||
对话模型
|
||||
"""
|
||||
from sqlalchemy import Column, String, Text, Float, Integer, Boolean, Index
|
||||
|
||||
from app.base_model import BaseModel
|
||||
|
||||
|
||||
class Conversation(BaseModel):
|
||||
"""
|
||||
对话
|
||||
"""
|
||||
__tablename__ = "ai_conversation"
|
||||
|
||||
app_id = Column(String(21), nullable=False, index=True, comment="所属应用ID(逻辑外键关联ai_app)")
|
||||
user_id = Column(String(21), nullable=False, index=True, comment="用户ID(逻辑外键关联core_user)")
|
||||
title = Column(String(200), default="", comment="对话标题")
|
||||
model_override_id = Column(String(21), nullable=True, comment="覆盖模型ID(逻辑外键关联ai_llm_model)")
|
||||
temperature_override = Column(Float, nullable=True, comment="覆盖温度参数")
|
||||
message_count = Column(Integer, default=0, comment="消息数量")
|
||||
total_tokens = Column(Integer, default=0, comment="总 Token 数")
|
||||
is_pinned = Column(Boolean, default=False, comment="是否置顶")
|
||||
|
||||
__table_args__ = (
|
||||
Index("ix_ai_conversation_user_app", "user_id", "app_id"),
|
||||
)
|
||||
|
||||
|
||||
class Message(BaseModel):
|
||||
"""
|
||||
消息
|
||||
"""
|
||||
__tablename__ = "ai_message"
|
||||
|
||||
conversation_id = Column(String(21), nullable=False, index=True, comment="所属对话ID(逻辑外键关联ai_conversation)")
|
||||
role = Column(String(20), nullable=False, comment="角色: system/user/assistant")
|
||||
content = Column(Text, nullable=False, comment="消息内容")
|
||||
status = Column(String(20), default="completed", comment="状态: pending/completed/failed/stopped")
|
||||
prompt_tokens = Column(Integer, default=0, comment="提示 Token 数")
|
||||
completion_tokens = Column(Integer, default=0, comment="补全 Token 数")
|
||||
total_tokens = Column(Integer, default=0, comment="总 Token 数")
|
||||
model_name = Column(String(100), default="", comment="使用的模型名称")
|
||||
latency = Column(Integer, default=0, comment="响应耗时(毫秒)")
|
||||
error_message = Column(Text, default="", comment="错误信息")
|
||||
parent_message_id = Column(String(21), nullable=True, comment="父消息ID(逻辑外键关联自身)")
|
||||
feedback = Column(String(20), default="", comment="用户反馈: like/dislike")
|
||||
|
||||
__table_args__ = (
|
||||
Index("ix_ai_message_conversation_created", "conversation_id", "sys_create_datetime"),
|
||||
)
|
||||
@@ -0,0 +1,30 @@
|
||||
"""
|
||||
LLM 模型配置
|
||||
"""
|
||||
from sqlalchemy import Column, String, Integer, Float, Boolean, Numeric
|
||||
|
||||
from app.base_model import BaseModel
|
||||
|
||||
|
||||
class LLMModel(BaseModel):
|
||||
"""
|
||||
LLM 模型配置
|
||||
|
||||
每个提供商可以配置多个模型
|
||||
"""
|
||||
__tablename__ = "ai_llm_model"
|
||||
|
||||
provider_id = Column(String(21), nullable=False, index=True, comment="所属提供商ID(逻辑外键关联ai_llm_provider)")
|
||||
model_name = Column(String(100), nullable=False, comment="模型名称(API 调用时使用)")
|
||||
display_name = Column(String(100), nullable=False, comment="显示名称")
|
||||
model_type = Column(String(20), default="chat", comment="模型类型: chat/completion/embedding/rerank")
|
||||
max_tokens = Column(Integer, default=4096, comment="最大 Token 数")
|
||||
context_window = Column(Integer, default=4096, comment="上下文窗口大小")
|
||||
default_temperature = Column(Float, default=0.7, comment="默认温度参数")
|
||||
default_top_p = Column(Float, default=1.0, comment="默认 top_p 参数")
|
||||
input_price = Column(Numeric(10, 6), default=0, comment="输入价格(每 1K tokens)")
|
||||
output_price = Column(Numeric(10, 6), default=0, comment="输出价格(每 1K tokens)")
|
||||
is_active = Column(Boolean, default=True, comment="是否启用")
|
||||
supports_vision = Column(Boolean, default=False, comment="是否支持视觉(图片输入)")
|
||||
supports_function_call = Column(Boolean, default=False, comment="是否支持函数调用")
|
||||
supports_streaming = Column(Boolean, default=True, comment="是否支持流式输出")
|
||||
@@ -0,0 +1,40 @@
|
||||
"""
|
||||
Prompt 模板模型
|
||||
"""
|
||||
from sqlalchemy import Column, String, Text, Integer, Boolean, JSON
|
||||
|
||||
from app.base_model import BaseModel
|
||||
|
||||
|
||||
class PromptTemplate(BaseModel):
|
||||
"""
|
||||
Prompt 模板
|
||||
|
||||
用于管理和复用 Prompt
|
||||
"""
|
||||
__tablename__ = "ai_prompt_template"
|
||||
|
||||
name = Column(String(100), nullable=False, comment="模板名称")
|
||||
code = Column(String(100), unique=True, nullable=False, comment="模板编码")
|
||||
category = Column(String(20), default="system", comment="分类: system/user/assistant/few_shot")
|
||||
description = Column(Text, default="", comment="描述")
|
||||
content = Column(Text, nullable=False, comment="模板内容")
|
||||
variables = Column(JSON, default=list, comment="变量定义列表")
|
||||
tags = Column(JSON, default=list, comment="标签列表")
|
||||
is_public = Column(Boolean, default=False, comment="是否公开")
|
||||
usage_count = Column(Integer, default=0, comment="使用次数")
|
||||
|
||||
def render(self, variables: dict) -> str:
|
||||
"""
|
||||
渲染模板
|
||||
|
||||
Args:
|
||||
variables: 变量字典
|
||||
|
||||
Returns:
|
||||
渲染后的内容
|
||||
"""
|
||||
content = self.content or ""
|
||||
for key, value in variables.items():
|
||||
content = content.replace(f'{{{{{key}}}}}', str(value))
|
||||
return content
|
||||
@@ -0,0 +1,42 @@
|
||||
"""
|
||||
LLM 提供商模型
|
||||
"""
|
||||
from sqlalchemy import Column, String, Text, Boolean, Integer
|
||||
|
||||
from app.base_model import BaseModel
|
||||
|
||||
|
||||
class LLMProvider(BaseModel):
|
||||
"""
|
||||
LLM 提供商配置
|
||||
|
||||
支持的提供商类型:
|
||||
- openai: OpenAI (GPT-3.5, GPT-4, etc.)
|
||||
- claude: Anthropic Claude
|
||||
- qwen: 阿里通义千问
|
||||
- ollama: 本地 Ollama
|
||||
- azure_openai: Azure OpenAI
|
||||
- zhipu: 智谱 AI
|
||||
- moonshot: Moonshot (Kimi)
|
||||
- deepseek: DeepSeek
|
||||
"""
|
||||
__tablename__ = "ai_llm_provider"
|
||||
|
||||
name = Column(String(100), nullable=False, comment="提供商名称")
|
||||
provider_type = Column(String(50), nullable=False, comment="提供商类型")
|
||||
api_key = Column(Text, default="", comment="API Key(加密存储)")
|
||||
api_base = Column(String(500), default="", comment="API 地址(可选,用于自定义端点)")
|
||||
api_version = Column(String(50), default="", comment="API 版本(Azure OpenAI 专用)")
|
||||
ollama_host = Column(String(200), default="http://localhost:11434", comment="Ollama 服务地址")
|
||||
is_active = Column(Boolean, default=True, comment="是否启用")
|
||||
description = Column(Text, default="", comment="描述")
|
||||
quota_limit = Column(Integer, default=0, comment="配额限制(0 表示无限制)")
|
||||
quota_used = Column(Integer, default=0, comment="已使用配额")
|
||||
|
||||
def get_api_key_masked(self) -> str:
|
||||
"""获取脱敏的 API Key"""
|
||||
if not self.api_key:
|
||||
return ''
|
||||
if len(self.api_key) <= 8:
|
||||
return '*' * len(self.api_key)
|
||||
return self.api_key[:4] + '*' * (len(self.api_key) - 8) + self.api_key[-4:]
|
||||
@@ -0,0 +1,83 @@
|
||||
"""
|
||||
AI 工作流模型
|
||||
"""
|
||||
from sqlalchemy import Column, String, Text, Integer, Boolean, DateTime, JSON, Index
|
||||
|
||||
from app.base_model import BaseModel
|
||||
|
||||
|
||||
class AIWorkflow(BaseModel):
|
||||
"""
|
||||
AI 工作流定义
|
||||
|
||||
独立于 AIApp 的工作流定义,可以被多个应用引用
|
||||
"""
|
||||
__tablename__ = "ai_workflow"
|
||||
|
||||
application_id = Column(String(21), nullable=True, index=True, comment="所属应用ID(逻辑外键关联core_application)")
|
||||
is_global = Column(Boolean, default=False, comment="是否在子应用中可见")
|
||||
name = Column(String(100), nullable=False, comment="工作流名称")
|
||||
code = Column(String(100), unique=True, nullable=False, comment="工作流编码")
|
||||
workflow_type = Column(String(30), default="general", comment="工作流类型: general/application/form/report/data_process/automation")
|
||||
description = Column(Text, default="", comment="描述")
|
||||
status = Column(String(20), default="draft", comment="状态: draft/published/disabled")
|
||||
version = Column(Integer, default=1, comment="当前草稿版本号")
|
||||
published_version = Column(Integer, nullable=True, comment="已发布的版本号")
|
||||
published_at = Column(DateTime, nullable=True, comment="最后发布时间")
|
||||
published_definition = Column(JSON, default=dict, comment="已发布版本的工作流定义")
|
||||
definition = Column(JSON, default=dict, comment="工作流定义(草稿)")
|
||||
input_variables = Column(JSON, default=list, comment="输入变量定义")
|
||||
output_variables = Column(JSON, default=list, comment="输出变量定义")
|
||||
run_count = Column(Integer, default=0, comment="运行次数")
|
||||
success_count = Column(Integer, default=0, comment="成功次数")
|
||||
|
||||
|
||||
class AIWorkflowVersion(BaseModel):
|
||||
"""
|
||||
AI 工作流版本历史
|
||||
|
||||
每次发布时创建一条版本记录
|
||||
"""
|
||||
__tablename__ = "ai_workflow_version"
|
||||
|
||||
workflow_id = Column(String(21), nullable=False, index=True, comment="工作流ID(逻辑外键关联ai_workflow)")
|
||||
version = Column(Integer, nullable=False, comment="版本号")
|
||||
definition = Column(JSON, default=dict, comment="该版本的工作流定义")
|
||||
description = Column(Text, default="", comment="版本说明")
|
||||
published_by_id = Column(String(21), nullable=True, comment="发布人ID(逻辑外键关联core_user)")
|
||||
published_at = Column(DateTime, nullable=True, comment="发布时间")
|
||||
run_count = Column(Integer, default=0, comment="运行次数")
|
||||
success_count = Column(Integer, default=0, comment="成功次数")
|
||||
|
||||
|
||||
class AIWorkflowRun(BaseModel):
|
||||
"""
|
||||
AI 工作流运行记录
|
||||
"""
|
||||
__tablename__ = "ai_workflow_run"
|
||||
|
||||
workflow_id = Column(String(21), nullable=False, index=True, comment="工作流ID(逻辑外键关联ai_workflow)")
|
||||
app_id = Column(String(21), nullable=True, index=True, comment="关联应用ID(逻辑外键关联ai_app)")
|
||||
conversation_id = Column(String(21), nullable=True, comment="关联对话ID(逻辑外键关联ai_conversation)")
|
||||
user_id = Column(String(21), nullable=True, index=True, comment="执行用户ID(逻辑外键关联core_user)")
|
||||
status = Column(String(20), default="pending", comment="状态: pending/running/waiting/completed/failed/stopped")
|
||||
trigger_type = Column(String(30), default="api", comment="触发来源: editor_draft/editor_published/agent/api/form_button")
|
||||
use_draft = Column(Boolean, default=False, comment="是否使用草稿定义执行")
|
||||
workflow_version = Column(Integer, nullable=True, comment="执行时发布版本号,草稿运行为空")
|
||||
definition_snapshot = Column(JSON, default=dict, comment="运行开始时的工作流定义快照")
|
||||
inputs = Column(JSON, default=dict, comment="输入数据")
|
||||
outputs = Column(JSON, default=dict, comment="输出数据")
|
||||
execution_log = Column(JSON, default=list, comment="执行日志")
|
||||
current_node_id = Column(String(100), default="", comment="当前节点 ID")
|
||||
waiting_config = Column(JSON, default=dict, comment="等待用户输入的配置")
|
||||
error_message = Column(Text, default="", comment="错误信息")
|
||||
total_tokens = Column(Integer, default=0, comment="总 Token 数")
|
||||
total_steps = Column(Integer, default=0, comment="总步骤数")
|
||||
elapsed_time = Column(Integer, default=0, comment="总耗时(毫秒)")
|
||||
started_at = Column(DateTime, nullable=True, comment="开始时间")
|
||||
completed_at = Column(DateTime, nullable=True, comment="完成时间")
|
||||
|
||||
__table_args__ = (
|
||||
Index("ix_ai_workflow_run_workflow_status", "workflow_id", "status"),
|
||||
Index("ix_ai_workflow_run_user_status", "user_id", "status"),
|
||||
)
|
||||
Reference in New Issue
Block a user