Build lightweight AI agent admin
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
"""
|
||||
知识库 Schema
|
||||
"""
|
||||
from .knowledge_base_schema import *
|
||||
from .document_schema import *
|
||||
from .segment_schema import *
|
||||
@@ -0,0 +1,37 @@
|
||||
"""
|
||||
知识库标注 Schema
|
||||
"""
|
||||
from typing import Optional, List
|
||||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel, Field, ConfigDict
|
||||
|
||||
from app.base_schema import CSTDatetime
|
||||
|
||||
|
||||
class AnnotationCreateInput(BaseModel):
|
||||
"""创建标注"""
|
||||
question: str = Field(..., min_length=1, description="问题")
|
||||
answer: str = Field(..., min_length=1, description="答案")
|
||||
|
||||
|
||||
class AnnotationUpdateInput(BaseModel):
|
||||
"""更新标注"""
|
||||
question: Optional[str] = Field(None, min_length=1, description="问题")
|
||||
answer: Optional[str] = Field(None, min_length=1, description="答案")
|
||||
enabled: Optional[bool] = Field(None, description="是否启用")
|
||||
|
||||
|
||||
class AnnotationResponse(BaseModel):
|
||||
"""标注输出"""
|
||||
id: str
|
||||
knowledge_base_id: str
|
||||
question: str
|
||||
answer: str
|
||||
embedding_status: str = "pending"
|
||||
enabled: bool = True
|
||||
hit_count: int = 0
|
||||
sys_create_datetime: Optional[CSTDatetime] = None
|
||||
sys_update_datetime: Optional[CSTDatetime] = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
@@ -0,0 +1,62 @@
|
||||
"""
|
||||
知识库文档 Schema
|
||||
"""
|
||||
from typing import Optional, List
|
||||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel, Field, ConfigDict
|
||||
|
||||
from app.base_schema import CSTDatetime
|
||||
|
||||
|
||||
class DocumentUploadInput(BaseModel):
|
||||
"""文档上传输入(通过文件管理系统上传后传入 file_id)"""
|
||||
file_id: str = Field(..., description="文件ID(来自文件管理系统)")
|
||||
name: Optional[str] = Field(None, description="文档名称(不传则使用文件名)")
|
||||
|
||||
|
||||
class DocumentBatchUploadInput(BaseModel):
|
||||
"""批量文档上传"""
|
||||
file_ids: List[str] = Field(..., min_length=1, description="文件ID列表")
|
||||
|
||||
|
||||
class DocumentResponse(BaseModel):
|
||||
"""文档输出"""
|
||||
id: str
|
||||
knowledge_base_id: str
|
||||
file_id: Optional[str] = None
|
||||
name: str
|
||||
file_type: str = ""
|
||||
file_size: int = 0
|
||||
content_hash: str = ""
|
||||
segment_count: int = 0
|
||||
token_count: int = 0
|
||||
char_count: int = 0
|
||||
status: str = "pending"
|
||||
error_message: str = ""
|
||||
duplicate_warning: Optional[str] = None
|
||||
enabled: bool = True
|
||||
indexing_started_at: Optional[CSTDatetime] = None
|
||||
indexing_completed_at: Optional[CSTDatetime] = None
|
||||
sys_create_datetime: Optional[CSTDatetime] = None
|
||||
sys_update_datetime: Optional[CSTDatetime] = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class DocumentListResponse(BaseModel):
|
||||
"""文档列表输出"""
|
||||
id: str
|
||||
knowledge_base_id: str
|
||||
file_id: Optional[str] = None
|
||||
name: str
|
||||
file_type: str = ""
|
||||
file_size: int = 0
|
||||
segment_count: int = 0
|
||||
token_count: int = 0
|
||||
status: str = "pending"
|
||||
duplicate_warning: Optional[str] = None
|
||||
enabled: bool = True
|
||||
sys_create_datetime: Optional[CSTDatetime] = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
@@ -0,0 +1,115 @@
|
||||
"""
|
||||
知识库 Schema
|
||||
"""
|
||||
from typing import Optional, List, Dict, Any
|
||||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel, Field, ConfigDict
|
||||
|
||||
from app.base_schema import CSTDatetime
|
||||
|
||||
|
||||
class KnowledgeBaseCreate(BaseModel):
|
||||
"""创建知识库"""
|
||||
model_config = ConfigDict(protected_namespaces=())
|
||||
|
||||
application_id: Optional[str] = Field(None, description="所属应用ID")
|
||||
is_global: bool = Field(default=False, description="是否在子应用中可见")
|
||||
name: str = Field(..., max_length=100, description="知识库名称")
|
||||
code: str = Field(..., max_length=100, description="知识库编码")
|
||||
description: Optional[str] = Field(None, description="描述")
|
||||
icon: str = Field(default="", description="图标")
|
||||
embedding_model_id: Optional[str] = Field(None, description="Embedding 模型ID")
|
||||
embedding_dimensions: int = Field(default=1536, description="向量维度")
|
||||
chunk_strategy: str = Field(default="recursive", description="分块策略")
|
||||
chunk_size: int = Field(default=500, ge=100, le=4000, description="分块大小")
|
||||
chunk_overlap: int = Field(default=50, ge=0, le=500, description="分块重叠")
|
||||
separator: Optional[str] = Field(None, description="自定义分隔符")
|
||||
retrieval_mode: str = Field(default="hybrid", description="检索模式")
|
||||
top_k: int = Field(default=5, ge=1, le=20, description="检索数量")
|
||||
score_threshold: float = Field(default=0.5, ge=0, le=1, description="相似度阈值")
|
||||
rerank_enabled: bool = Field(default=False, description="是否启用重排序")
|
||||
rerank_model_id: Optional[str] = Field(None, description="重排序模型ID")
|
||||
retrieval_weight: float = Field(default=1.0, ge=0.1, le=10.0, description="检索权重")
|
||||
process_rules: Optional[Dict[str, Any]] = Field(None, description="预处理规则")
|
||||
indexing_technique: str = Field(default="high_quality", description="索引模式: high_quality/economy")
|
||||
|
||||
|
||||
class KnowledgeBaseUpdate(BaseModel):
|
||||
"""更新知识库"""
|
||||
model_config = ConfigDict(protected_namespaces=())
|
||||
|
||||
name: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
icon: Optional[str] = None
|
||||
embedding_model_id: Optional[str] = None
|
||||
embedding_dimensions: Optional[int] = None
|
||||
chunk_strategy: Optional[str] = None
|
||||
chunk_size: Optional[int] = Field(None, ge=100, le=4000)
|
||||
chunk_overlap: Optional[int] = Field(None, ge=0, le=500)
|
||||
separator: Optional[str] = None
|
||||
retrieval_mode: Optional[str] = None
|
||||
top_k: Optional[int] = Field(None, ge=1, le=20)
|
||||
score_threshold: Optional[float] = Field(None, ge=0, le=1)
|
||||
rerank_enabled: Optional[bool] = None
|
||||
rerank_model_id: Optional[str] = None
|
||||
retrieval_weight: Optional[float] = Field(None, ge=0.1, le=10.0)
|
||||
process_rules: Optional[Dict[str, Any]] = None
|
||||
indexing_technique: Optional[str] = None
|
||||
status: Optional[str] = None
|
||||
is_global: Optional[bool] = None
|
||||
|
||||
|
||||
class KnowledgeBaseResponse(BaseModel):
|
||||
"""知识库详情输出"""
|
||||
id: str
|
||||
application_id: Optional[str] = None
|
||||
is_global: bool = False
|
||||
name: str
|
||||
code: str
|
||||
description: str = ""
|
||||
icon: str = ""
|
||||
embedding_model_id: Optional[str] = None
|
||||
embedding_model_name: str = ""
|
||||
embedding_dimensions: int = 1536
|
||||
chunk_strategy: str = "recursive"
|
||||
chunk_size: int = 500
|
||||
chunk_overlap: int = 50
|
||||
separator: Optional[str] = None
|
||||
retrieval_mode: str = "hybrid"
|
||||
top_k: int = 5
|
||||
score_threshold: float = 0.5
|
||||
rerank_enabled: bool = False
|
||||
rerank_model_id: Optional[str] = None
|
||||
retrieval_weight: float = 1.0
|
||||
process_rules: Optional[Dict[str, Any]] = None
|
||||
indexing_technique: str = "high_quality"
|
||||
document_count: int = 0
|
||||
segment_count: int = 0
|
||||
total_token_count: int = 0
|
||||
total_char_count: int = 0
|
||||
status: str = "active"
|
||||
sort: int = 0
|
||||
sys_create_datetime: Optional[CSTDatetime] = None
|
||||
sys_update_datetime: Optional[CSTDatetime] = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True, protected_namespaces=())
|
||||
|
||||
|
||||
class KnowledgeBaseListResponse(BaseModel):
|
||||
"""知识库列表输出"""
|
||||
id: str
|
||||
application_id: Optional[str] = None
|
||||
application_name: str = ""
|
||||
is_global: bool = False
|
||||
name: str
|
||||
code: str
|
||||
description: str = ""
|
||||
icon: str = ""
|
||||
embedding_model_name: str = ""
|
||||
document_count: int = 0
|
||||
segment_count: int = 0
|
||||
status: str = "active"
|
||||
sys_create_datetime: Optional[CSTDatetime] = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True, protected_namespaces=())
|
||||
@@ -0,0 +1,28 @@
|
||||
"""
|
||||
检索日志 Schema
|
||||
"""
|
||||
from typing import Optional, List, Dict, Any
|
||||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel, Field, ConfigDict
|
||||
|
||||
from app.base_schema import CSTDatetime
|
||||
|
||||
|
||||
class RetrievalLogResponse(BaseModel):
|
||||
"""检索日志输出"""
|
||||
id: str
|
||||
query: str
|
||||
knowledge_base_ids: List[str] = []
|
||||
retrieval_mode: str = "hybrid"
|
||||
top_k: int = 5
|
||||
score_threshold: float = 0.5
|
||||
result_count: int = 0
|
||||
results: Optional[List[Dict[str, Any]]] = None
|
||||
rerank_applied: str = "false"
|
||||
elapsed_time: int = 0
|
||||
source: Optional[str] = None
|
||||
user_id: Optional[str] = None
|
||||
sys_create_datetime: Optional[CSTDatetime] = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
@@ -0,0 +1,140 @@
|
||||
"""
|
||||
知识库分段 Schema
|
||||
"""
|
||||
from typing import Optional, List, Dict, Any
|
||||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel, Field, ConfigDict
|
||||
|
||||
from app.base_schema import CSTDatetime
|
||||
|
||||
|
||||
class SegmentResponse(BaseModel):
|
||||
"""分段输出"""
|
||||
id: str
|
||||
knowledge_base_id: str
|
||||
document_id: str
|
||||
document_name: str = ""
|
||||
position: int = 0
|
||||
content: str
|
||||
answer: Optional[str] = None
|
||||
token_count: int = 0
|
||||
char_count: int = 0
|
||||
word_count: int = 0
|
||||
page_number: Optional[int] = None
|
||||
keywords: Optional[List[str]] = None
|
||||
metadata: Optional[Dict[str, Any]] = None
|
||||
embedding_status: str = "pending"
|
||||
enabled: bool = True
|
||||
hit_count: int = 0
|
||||
sys_create_datetime: Optional[CSTDatetime] = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class SegmentListResponse(BaseModel):
|
||||
"""分段列表输出"""
|
||||
id: str
|
||||
document_id: str
|
||||
document_name: str = ""
|
||||
position: int = 0
|
||||
content: str
|
||||
answer: Optional[str] = None
|
||||
token_count: int = 0
|
||||
char_count: int = 0
|
||||
word_count: int = 0
|
||||
page_number: Optional[int] = None
|
||||
keywords: Optional[List[str]] = None
|
||||
extra_metadata: Optional[Dict[str, Any]] = None
|
||||
enabled: bool = True
|
||||
hit_count: int = 0
|
||||
embedding_status: str = "pending"
|
||||
sys_create_datetime: Optional[CSTDatetime] = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class SegmentUpdateInput(BaseModel):
|
||||
"""更新分段"""
|
||||
content: Optional[str] = Field(None, description="分段内容")
|
||||
keywords: Optional[List[str]] = Field(None, description="关键词")
|
||||
enabled: Optional[bool] = Field(None, description="是否启用")
|
||||
extra_metadata: Optional[Dict[str, Any]] = Field(None, description="元数据")
|
||||
|
||||
|
||||
class SegmentCreateInput(BaseModel):
|
||||
"""手动创建分段"""
|
||||
content: str = Field(..., min_length=1, description="分段内容")
|
||||
answer: Optional[str] = Field(None, description="Q&A 模式的答案")
|
||||
keywords: Optional[List[str]] = Field(None, description="关键词")
|
||||
|
||||
|
||||
class ChunkPreviewInput(BaseModel):
|
||||
"""分块预览输入"""
|
||||
file_id: str = Field(..., description="文件ID")
|
||||
chunk_strategy: str = Field(default="recursive", description="分块策略")
|
||||
chunk_size: int = Field(default=500, ge=100, le=4000, description="分块大小")
|
||||
chunk_overlap: int = Field(default=50, ge=0, le=500, description="分块重叠")
|
||||
separator: Optional[str] = Field(None, description="自定义分隔符")
|
||||
process_rules: Optional[Dict[str, Any]] = Field(None, description="预处理规则")
|
||||
|
||||
|
||||
class ChunkPreviewItem(BaseModel):
|
||||
"""分块预览结果项"""
|
||||
position: int = 0
|
||||
content: str = ""
|
||||
char_count: int = 0
|
||||
token_count: int = 0
|
||||
word_count: int = 0
|
||||
answer: Optional[str] = None
|
||||
metadata: Optional[Dict[str, Any]] = None
|
||||
|
||||
|
||||
class ChunkPreviewResponse(BaseModel):
|
||||
"""分块预览响应"""
|
||||
chunks: List[ChunkPreviewItem] = Field(default_factory=list)
|
||||
total: int = 0
|
||||
strategy: str = ""
|
||||
chunk_size: int = 0
|
||||
chunk_overlap: int = 0
|
||||
|
||||
|
||||
class RetrievalInput(BaseModel):
|
||||
"""检索输入"""
|
||||
model_config = ConfigDict(protected_namespaces=())
|
||||
|
||||
query: str = Field(..., min_length=1, description="查询文本")
|
||||
knowledge_base_ids: List[str] = Field(..., min_length=1, description="知识库ID列表")
|
||||
top_k: int = Field(default=5, ge=1, le=20, description="返回数量")
|
||||
score_threshold: float = Field(default=0.5, ge=0, le=1, description="相似度阈值")
|
||||
retrieval_mode: Optional[str] = Field(None, description="检索模式(不传则使用知识库配置)")
|
||||
rerank_enabled: Optional[bool] = Field(None, description="是否启用重排序(不传则使用知识库配置)")
|
||||
rerank_model_id: Optional[str] = Field(None, description="重排序模型ID(不传则使用知识库配置)")
|
||||
metadata_filter: Optional[Dict[str, Any]] = Field(None, description="元数据过滤条件")
|
||||
|
||||
|
||||
class RetrievalResult(BaseModel):
|
||||
"""检索结果"""
|
||||
segment_id: str
|
||||
document_id: str
|
||||
document_name: str = ""
|
||||
knowledge_base_id: str
|
||||
knowledge_base_name: str = ""
|
||||
content: str
|
||||
score: float = 0.0
|
||||
token_count: int = 0
|
||||
page_number: Optional[int] = None
|
||||
metadata: Optional[Dict[str, Any]] = None
|
||||
keywords: Optional[List[str]] = None
|
||||
match_source: Optional[str] = Field(None, description="命中来源: vector/fulltext/annotation")
|
||||
parent_content: Optional[str] = Field(None, description="父分段内容(Small-to-Big 模式)")
|
||||
|
||||
|
||||
class RetrievalResponse(BaseModel):
|
||||
"""检索响应"""
|
||||
results: List[RetrievalResult] = Field(default_factory=list)
|
||||
total: int = 0
|
||||
query: str = ""
|
||||
elapsed_time: int = 0
|
||||
retrieval_mode: str = ""
|
||||
rerank_applied: bool = False
|
||||
Reference in New Issue
Block a user