fischer-agentkit/src/agentkit/rag_platform/models.py

191 lines
6.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""RAG 平台 Pydantic 数据模型。
这些是领域模型(非 ORMORM 模型定义在 store.pyU2
与 memory/knowledge_base.py 的 KnowledgeBase protocol 分离 —
rag_platform 服务企业知识库场景memory/ 服务 Agent 运行时记忆。
"""
from __future__ import annotations
import uuid
from datetime import datetime, timezone
from enum import Enum
from pydantic import BaseModel, ConfigDict, Field
def _utcnow() -> datetime:
return datetime.now(timezone.utc)
def _uuid() -> str:
return str(uuid.uuid4())
class KBStatus(str, Enum):
active = "active"
archived = "archived"
class DocumentStatus(str, Enum):
"""文档处理状态机pending → parsing → segmenting → vectorizing → indexed | failed。"""
pending = "pending"
parsing = "parsing"
segmenting = "segmenting"
vectorizing = "vectorizing"
indexed = "indexed"
failed = "failed"
class QueryMode(str, Enum):
"""检索模式embedding 语义 / keywords 全文 / blend 双索引合并。"""
embedding = "embedding"
keywords = "keywords"
blend = "blend"
class KnowledgeBase(BaseModel):
"""知识库领域模型。"""
model_config = ConfigDict(from_attributes=True)
id: str = Field(default_factory=_uuid)
name: str
description: str = ""
owner: str
status: KBStatus = KBStatus.active
# 检索与命中处理默认配置Agent 运行时可覆盖)
default_query_mode: QueryMode = QueryMode.blend
default_hit_processing: str = "model_opt" # model_opt | direct
caching_disabled: bool = False
created_at: datetime = Field(default_factory=_utcnow)
updated_at: datetime = Field(default_factory=_utcnow)
class Document(BaseModel):
"""知识库文档领域模型。"""
model_config = ConfigDict(from_attributes=True)
id: str = Field(default_factory=_uuid)
kb_id: str
filename: str
file_type: str
file_size: int
status: DocumentStatus = DocumentStatus.pending
error_message: str | None = None
created_at: datetime = Field(default_factory=_utcnow)
updated_at: datetime = Field(default_factory=_utcnow)
class Chunk(BaseModel):
"""文档分段后的文本块。"""
model_config = ConfigDict(from_attributes=True)
id: str = Field(default_factory=_uuid)
document_id: str
kb_id: str
content: str
metadata: dict = Field(default_factory=dict)
embedding: list[float] | None = None
class QueryResult(BaseModel):
"""检索结果条目。"""
model_config = ConfigDict(from_attributes=True)
chunk_id: str
content: str
score: float
metadata: dict = Field(default_factory=dict)
document_id: str
kb_id: str
class RetrievalRequest(BaseModel):
"""检索请求 — 支持覆盖 KB 默认配置。
retrieval_mode / hit_processing_mode 为 None 时使用 KB 默认值。
"""
model_config = ConfigDict()
query: str
kb_ids: list[str]
retrieval_mode: QueryMode | None = None # None = 使用 KB 默认
hit_processing_mode: str | None = None # None = 使用 KB 默认
top_k: int = 5
user_id: str | None = None # 用于 ACL 过滤
# ---------------------------------------------------------------------------
# ORM Models (SQLAlchemy 2 DeclarativeBase + Mapped)
# ---------------------------------------------------------------------------
from sqlalchemy import DateTime, ForeignKey, String, Text, UniqueConstraint # noqa: E402
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column # noqa: E402
class ORMBase(DeclarativeBase):
"""rag_platform ORM 基类 — 与 memory/models.py 的 declarative_base() 独立。"""
pass
class KBModel(ORMBase):
"""知识库 ORM 模型。"""
__tablename__ = "rag_platform_kbs"
id: Mapped[str] = mapped_column(String, primary_key=True, default=_uuid)
name: Mapped[str] = mapped_column(String(255))
description: Mapped[str] = mapped_column(Text, default="")
owner: Mapped[str] = mapped_column(String(255), index=True)
status: Mapped[str] = mapped_column(String(32), default="active", index=True)
default_query_mode: Mapped[str] = mapped_column(String(32), default="blend")
default_hit_processing: Mapped[str] = mapped_column(String(32), default="model_opt")
caching_disabled: Mapped[bool] = mapped_column(default=False)
created_at: Mapped[datetime] = mapped_column(DateTime, default=_utcnow)
updated_at: Mapped[datetime] = mapped_column(DateTime, default=_utcnow)
class DocumentModel(ORMBase):
"""知识库文档 ORM 模型。"""
__tablename__ = "rag_platform_documents"
id: Mapped[str] = mapped_column(String, primary_key=True, default=_uuid)
kb_id: Mapped[str] = mapped_column(
String, ForeignKey("rag_platform_kbs.id", ondelete="CASCADE"), index=True
)
filename: Mapped[str] = mapped_column(String(512))
file_type: Mapped[str] = mapped_column(String(64))
file_size: Mapped[int] = mapped_column(default=0)
status: Mapped[str] = mapped_column(String(32), default="pending", index=True)
error_message: Mapped[str | None] = mapped_column(Text, nullable=True)
created_at: Mapped[datetime] = mapped_column(DateTime, default=_utcnow)
updated_at: Mapped[datetime] = mapped_column(DateTime, default=_utcnow)
class KBAclModel(ORMBase):
"""Per-KB 访问控制 ORM 模型。
kb_id FK → rag_platform_kbs.id ON DELETE CASCADEKTD5 不变量)。
ACL 条目与 KB 元数据共享事务边界(同一 PG DB
"""
__tablename__ = "rag_platform_kb_acl"
__table_args__ = (UniqueConstraint("kb_id", "user_id", name="uq_kb_acl_kb_user"),)
id: Mapped[str] = mapped_column(String, primary_key=True, default=_uuid)
kb_id: Mapped[str] = mapped_column(
String, ForeignKey("rag_platform_kbs.id", ondelete="CASCADE"), index=True
)
user_id: Mapped[str] = mapped_column(String(255), index=True)
role: Mapped[str] = mapped_column(String(32), default="viewer") # owner | viewer
created_at: Mapped[datetime] = mapped_column(DateTime, default=_utcnow)