Build lightweight AI agent admin
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
知识库数据模型
|
||||
"""
|
||||
from .knowledge_base_model import KnowledgeBase
|
||||
from .document_model import KnowledgeDocument
|
||||
from .segment_model import KnowledgeSegment
|
||||
from .annotation_model import KnowledgeAnnotation
|
||||
from .retrieval_log_model import KnowledgeRetrievalLog
|
||||
|
||||
__all__ = [
|
||||
'KnowledgeBase',
|
||||
'KnowledgeDocument',
|
||||
'KnowledgeSegment',
|
||||
'KnowledgeAnnotation',
|
||||
'KnowledgeRetrievalLog',
|
||||
]
|
||||
@@ -0,0 +1,34 @@
|
||||
"""
|
||||
知识库标注模型(Q&A 对)
|
||||
|
||||
手动添加的高优先级问答对,检索时优先匹配。
|
||||
"""
|
||||
from sqlalchemy import Column, String, Text, Integer, Boolean, Index
|
||||
|
||||
from app.base_model import BaseModel
|
||||
|
||||
|
||||
class KnowledgeAnnotation(BaseModel):
|
||||
"""
|
||||
知识库标注(Q&A 对)
|
||||
|
||||
用户手动添加的问答对,检索时优先匹配 question,返回 answer。
|
||||
"""
|
||||
__tablename__ = "ai_knowledge_annotation"
|
||||
|
||||
knowledge_base_id = Column(String(21), nullable=False, index=True, comment="所属知识库ID(逻辑外键关联ai_knowledge_base)")
|
||||
|
||||
# Q&A 内容
|
||||
question = Column(Text, nullable=False, comment="问题")
|
||||
answer = Column(Text, nullable=False, comment="答案")
|
||||
|
||||
# 向量化状态
|
||||
embedding_status = Column(String(20), default="pending", comment="向量化状态: pending/completed/failed")
|
||||
|
||||
# 状态
|
||||
enabled = Column(Boolean, default=True, comment="是否启用")
|
||||
hit_count = Column(Integer, default=0, comment="命中次数")
|
||||
|
||||
__table_args__ = (
|
||||
Index('idx_annotation_kb_enabled', 'knowledge_base_id', 'enabled'),
|
||||
)
|
||||
@@ -0,0 +1,39 @@
|
||||
"""
|
||||
知识库文档模型
|
||||
"""
|
||||
from sqlalchemy import Column, String, Text, Integer, Boolean, DateTime, BigInteger
|
||||
|
||||
from app.base_model import BaseModel
|
||||
|
||||
|
||||
class KnowledgeDocument(BaseModel):
|
||||
"""
|
||||
知识库文档
|
||||
|
||||
记录上传到知识库的文档信息及处理状态
|
||||
"""
|
||||
__tablename__ = "ai_knowledge_document"
|
||||
|
||||
knowledge_base_id = Column(String(21), nullable=False, index=True, comment="所属知识库ID(逻辑外键关联ai_knowledge_base)")
|
||||
file_id = Column(String(21), nullable=True, comment="关联文件ID(逻辑外键关联core_file_manager)")
|
||||
name = Column(String(255), nullable=False, comment="文档名称")
|
||||
file_type = Column(String(20), nullable=True, comment="文件类型: pdf/docx/txt/md/xlsx/csv/html/pptx")
|
||||
file_size = Column(BigInteger, default=0, comment="文件大小(字节)")
|
||||
content_hash = Column(String(64), nullable=True, index=True, comment="内容MD5(用于去重)")
|
||||
|
||||
# 处理结果
|
||||
segment_count = Column(Integer, default=0, comment="分段数量")
|
||||
token_count = Column(Integer, default=0, comment="Token 总数")
|
||||
char_count = Column(Integer, default=0, comment="字符总数")
|
||||
|
||||
# 处理状态
|
||||
status = Column(String(20), default="pending", index=True, comment="状态: pending/indexing/completed/failed/disabled")
|
||||
error_message = Column(Text, nullable=True, comment="错误信息")
|
||||
indexing_started_at = Column(DateTime, nullable=True, comment="索引开始时间")
|
||||
indexing_completed_at = Column(DateTime, nullable=True, comment="索引完成时间")
|
||||
|
||||
# 去重
|
||||
duplicate_warning = Column(Text, nullable=True, comment="内容重复警告(跨知识库检测)")
|
||||
|
||||
# 是否启用
|
||||
enabled = Column(Boolean, default=True, comment="是否启用(禁用后不参与检索)")
|
||||
@@ -0,0 +1,55 @@
|
||||
"""
|
||||
知识库模型
|
||||
"""
|
||||
from sqlalchemy import Column, String, Text, Integer, Float, Boolean, JSON
|
||||
|
||||
from app.base_model import BaseModel
|
||||
|
||||
|
||||
class KnowledgeBase(BaseModel):
|
||||
"""
|
||||
知识库
|
||||
|
||||
管理文档集合,配置分块策略和检索参数
|
||||
"""
|
||||
__tablename__ = "ai_knowledge_base"
|
||||
|
||||
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), nullable=False, unique=True, comment="知识库编码")
|
||||
description = Column(Text, nullable=True, comment="描述")
|
||||
icon = Column(String(50), default="", comment="图标")
|
||||
|
||||
# Embedding 配置
|
||||
embedding_model_id = Column(String(21), nullable=True, comment="Embedding 模型ID(逻辑外键关联ai_llm_model)")
|
||||
embedding_dimensions = Column(Integer, default=1536, comment="向量维度")
|
||||
|
||||
# 分块策略
|
||||
chunk_strategy = Column(String(20), default="recursive", comment="分块策略: recursive/semantic/markdown/fixed")
|
||||
chunk_size = Column(Integer, default=500, comment="分块大小(字符数)")
|
||||
chunk_overlap = Column(Integer, default=50, comment="分块重叠大小(字符数)")
|
||||
separator = Column(String(50), nullable=True, comment="自定义分隔符")
|
||||
|
||||
# 检索配置
|
||||
retrieval_mode = Column(String(20), default="hybrid", comment="检索模式: vector/fulltext/hybrid")
|
||||
top_k = Column(Integer, default=5, comment="检索返回数量")
|
||||
score_threshold = Column(Float, default=0.5, comment="相似度阈值(0-1)")
|
||||
rerank_enabled = Column(Boolean, default=False, comment="是否启用重排序")
|
||||
rerank_model_id = Column(String(21), nullable=True, comment="重排序模型ID")
|
||||
retrieval_weight = Column(Float, default=1.0, comment="检索权重(多知识库检索时的加权系数,0.1-10.0)")
|
||||
|
||||
# 预处理规则
|
||||
process_rules = Column(JSON, nullable=True, comment="预处理规则(清洗配置)")
|
||||
|
||||
# 索引模式
|
||||
indexing_technique = Column(String(20), default="high_quality", comment="索引模式: high_quality/economy")
|
||||
|
||||
# 统计
|
||||
document_count = Column(Integer, default=0, comment="文档数量")
|
||||
segment_count = Column(Integer, default=0, comment="分段数量")
|
||||
total_token_count = Column(Integer, default=0, comment="总 Token 数")
|
||||
total_char_count = Column(Integer, default=0, comment="总字符数")
|
||||
|
||||
# 状态
|
||||
status = Column(String(20), default="active", comment="状态: active/disabled")
|
||||
@@ -0,0 +1,41 @@
|
||||
"""
|
||||
知识库检索日志模型
|
||||
|
||||
记录每次检索的查询、结果、耗时等信息,用于分析检索质量。
|
||||
"""
|
||||
from sqlalchemy import Column, String, Text, Integer, Float, JSON, Index
|
||||
|
||||
from app.base_model import BaseModel
|
||||
|
||||
|
||||
class KnowledgeRetrievalLog(BaseModel):
|
||||
"""
|
||||
知识库检索日志
|
||||
|
||||
记录每次检索请求的完整信息,用于检索质量分析和优化。
|
||||
"""
|
||||
__tablename__ = "ai_knowledge_retrieval_log"
|
||||
|
||||
# 检索请求
|
||||
query = Column(Text, nullable=False, comment="查询文本")
|
||||
knowledge_base_ids = Column(JSON, nullable=False, comment="检索的知识库ID列表")
|
||||
retrieval_mode = Column(String(20), default="hybrid", comment="检索模式: vector/fulltext/hybrid")
|
||||
top_k = Column(Integer, default=5, comment="请求的返回数量")
|
||||
score_threshold = Column(Float, default=0.5, comment="相似度阈值")
|
||||
|
||||
# 检索结果
|
||||
result_count = Column(Integer, default=0, comment="实际返回结果数")
|
||||
results = Column(JSON, nullable=True, comment="检索结果摘要(segment_id/score/kb_id)")
|
||||
rerank_applied = Column(String(5), default="false", comment="是否应用了重排序")
|
||||
|
||||
# 性能
|
||||
elapsed_time = Column(Integer, default=0, comment="耗时(毫秒)")
|
||||
|
||||
# 来源
|
||||
source = Column(String(50), nullable=True, comment="调用来源: api/workflow/chat")
|
||||
user_id = Column(String(21), nullable=True, comment="操作用户ID")
|
||||
|
||||
__table_args__ = (
|
||||
Index('idx_retrieval_log_query_time', 'sys_create_datetime'),
|
||||
Index('idx_retrieval_log_user', 'user_id'),
|
||||
)
|
||||
@@ -0,0 +1,47 @@
|
||||
"""
|
||||
知识库分段模型
|
||||
"""
|
||||
from sqlalchemy import Column, String, Text, Integer, Boolean, JSON, Index
|
||||
|
||||
from app.base_model import BaseModel
|
||||
|
||||
|
||||
class KnowledgeSegment(BaseModel):
|
||||
"""
|
||||
知识库分段(Chunk)
|
||||
|
||||
文档经过分块后的最小检索单元
|
||||
向量数据存储在 Qdrant 向量数据库中,此表只存业务数据
|
||||
"""
|
||||
__tablename__ = "ai_knowledge_segment"
|
||||
|
||||
knowledge_base_id = Column(String(21), nullable=False, index=True, comment="所属知识库ID(逻辑外键关联ai_knowledge_base)")
|
||||
document_id = Column(String(21), nullable=False, index=True, comment="所属文档ID(逻辑外键关联ai_knowledge_document)")
|
||||
|
||||
# 内容
|
||||
position = Column(Integer, default=0, comment="在文档中的位置序号")
|
||||
content = Column(Text, nullable=False, comment="分段文本内容")
|
||||
answer = Column(Text, nullable=True, comment="Q&A 模式的答案内容")
|
||||
token_count = Column(Integer, default=0, comment="Token 数")
|
||||
char_count = Column(Integer, default=0, comment="字符数")
|
||||
word_count = Column(Integer, default=0, comment="词数")
|
||||
|
||||
# 元数据
|
||||
page_number = Column(Integer, nullable=True, comment="来源页码(PDF/PPT)")
|
||||
keywords = Column(JSON, nullable=True, comment="关键词列表(用于全文检索增强)")
|
||||
extra_metadata = Column(JSON, nullable=True, comment="元数据(标题/来源等)")
|
||||
|
||||
# 向量化状态(向量数据存在 Qdrant 中,这里只记录状态)
|
||||
embedding_status = Column(String(20), default="pending", comment="向量化状态: pending/completed/failed")
|
||||
|
||||
# 父子分段(Small-to-Big)
|
||||
parent_segment_id = Column(String(21), nullable=True, index=True, comment="父分段ID(逻辑外键,用于 Small-to-Big 检索)")
|
||||
|
||||
# 状态
|
||||
enabled = Column(Boolean, default=True, comment="是否启用(禁用后不参与检索)")
|
||||
hit_count = Column(Integer, default=0, comment="命中次数")
|
||||
|
||||
__table_args__ = (
|
||||
Index('idx_segment_kb_doc', 'knowledge_base_id', 'document_id'),
|
||||
Index('idx_segment_kb_enabled', 'knowledge_base_id', 'enabled'),
|
||||
)
|
||||
Reference in New Issue
Block a user