""" 语义搜索相关的 Pydantic Schema """ from __future__ import annotations from typing import Optional from pydantic import BaseModel, Field class SearchRequest(BaseModel): """语义搜索请求""" query: str = Field(..., min_length=1, max_length=1000, description="搜索查询文本") top_k: int = Field(default=10, ge=1, le=100, description="返回结果数量") course_name: Optional[str] = Field(None, description="按课程名称过滤") teacher_name: Optional[str] = Field(None, description="按讲师名称过滤") live_date_from: Optional[str] = Field(None, description="直播日期起始 (YYYY-MM-DD)") live_date_to: Optional[str] = Field(None, description="直播日期结束 (YYYY-MM-DD)") threshold: float = Field(default=0.5, ge=0.0, le=1.0, description="相似度阈值") use_fulltext: bool = Field(default=True, description="是否同时使用全文搜索混合排序") class SearchResult(BaseModel): """单条搜索结果""" chunk_id: int = Field(..., description="分块 ID") page_id: int = Field(..., description="知识页面 ID") page_title: str = Field(..., description="页面标题") content: str = Field(..., description="分块文本内容") score: float = Field(..., description="相似度分数") course_name: Optional[str] = None teacher_name: Optional[str] = None live_date: Optional[str] = None highlight: Optional[str] = Field(None, description="高亮摘要") class SearchResponse(BaseModel): """搜索结果响应""" query: str = Field(..., description="原始查询文本") total: int = Field(..., description="结果总数") results: list[SearchResult] = Field(default_factory=list, description="搜索结果列表") elapsed_ms: float = Field(..., description="搜索耗时(毫秒)")