llm_schema.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. """
  2. LLM对话相关的数据传输对象定义
  3. 定义AI对话API请求和响应的数据结构,包含联网搜索功能扩展
  4. 需求: 4.1, 4.2, 5.1, 5.2, 5.3, 6.1, 6.2, 6.4
  5. 搜索需求: 2.4, 5.3, 6.2, 10.3
  6. """
  7. from typing import List, Literal, Optional, Union, Dict
  8. from pydantic import BaseModel, Field, field_validator
  9. class ImageContent(BaseModel):
  10. """图像内容"""
  11. type: Literal["image_url"] = "image_url"
  12. image_url: dict = Field(..., description="图像URL信息,包含url字段(支持base64格式)")
  13. class TextContent(BaseModel):
  14. """文本内容"""
  15. type: Literal["text"] = "text"
  16. text: str = Field(..., description="文本内容")
  17. class ChatMessage(BaseModel):
  18. """对话消息"""
  19. role: Literal["system", "user", "assistant"]
  20. content: Union[str, List[Union[TextContent, ImageContent]]] = Field(..., description="消息内容,可以是字符串或多模态内容列表")
  21. class ChatRequest(BaseModel):
  22. """对话请求"""
  23. model: str = Field(..., description="模型名称")
  24. messages: List[ChatMessage] = Field(..., min_length=1, description="对话消息列表")
  25. stream: bool = Field(default=True, description="是否流式输出,默认启用")
  26. temperature: Optional[float] = Field(default=None, ge=0, lt=2, description="采样温度 [0, 2)")
  27. top_p: Optional[float] = Field(default=None, gt=0, le=1.0, description="核采样概率 (0, 1.0]")
  28. max_tokens: Optional[int] = Field(default=None, gt=0, description="最大输出token数")
  29. conversation_id: Optional[int] = Field(default=None, description="会话ID,用于记录对话历史")
  30. enable_thinking: bool = Field(default=False, description="是否启用思考模式(仅Qwen3系列支持)")
  31. thinking_budget: Optional[int] = Field(default=None, gt=0, description="思考过程的最大Token数")
  32. @field_validator('messages')
  33. @classmethod
  34. def validate_messages(cls, v):
  35. if not v:
  36. raise ValueError('消息列表不能为空')
  37. return v
  38. class UsageInfo(BaseModel):
  39. """Token使用统计"""
  40. input_tokens: int
  41. output_tokens: int
  42. total_tokens: int
  43. class ChatResponse(BaseModel):
  44. """对话响应"""
  45. content: str
  46. finish_reason: str
  47. usage: UsageInfo
  48. reasoning_content: Optional[str] = Field(default=None, description="思考过程内容")
  49. class StreamChunk(BaseModel):
  50. """流式响应块"""
  51. content: str
  52. finish_reason: Optional[str] = None
  53. usage: Optional[UsageInfo] = None
  54. reasoning_content: Optional[str] = Field(default=None, description="思考过程内容(增量)")
  55. # ==================== 联网搜索功能扩展 ====================
  56. class SearchOptions(BaseModel):
  57. """搜索配置选项"""
  58. enable_search: bool = Field(default=False, description="是否启用联网搜索")
  59. search_strategy: Literal["turbo", "max", "agent"] = Field(default="turbo", description="搜索策略")
  60. forced_search: bool = Field(default=False, description="是否强制搜索")
  61. enable_search_extension: bool = Field(default=False, description="是否启用垂域搜索")
  62. freshness: Optional[Literal[7, 30, 180, 365]] = Field(default=None, description="搜索时效性(天)")
  63. enable_source: bool = Field(default=False, description="是否返回搜索来源")
  64. enable_citation: bool = Field(default=False, description="是否启用角标引用")
  65. citation_format: Literal["[<number>]", "[ref_<number>]"] = Field(default="[<number>]", description="角标格式")
  66. prepend_search_result: bool = Field(default=False, description="是否提前返回搜索结果")
  67. intention_options: Optional[Dict[str, str]] = Field(default=None, description="自然语言搜索控制")
  68. @field_validator('freshness')
  69. @classmethod
  70. def validate_freshness_with_strategy(cls, v, info):
  71. """验证时效性参数仅对turbo策略生效"""
  72. if v is not None:
  73. # 注意:这里无法直接访问search_strategy,因为Pydantic的验证顺序
  74. # 实际的策略兼容性验证将在SearchOptionsValidator中进行
  75. pass
  76. return v
  77. class SearchResult(BaseModel):
  78. """搜索结果"""
  79. index: int = Field(..., description="搜索结果索引")
  80. title: str = Field(..., description="页面标题")
  81. url: str = Field(..., description="页面URL")
  82. snippet: Optional[str] = Field(default=None, description="内容摘要")
  83. class EnhancedChatRequest(ChatRequest):
  84. """增强的对话请求,支持搜索选项"""
  85. search_options: Optional[SearchOptions] = Field(default=None, description="搜索配置选项")
  86. class EnhancedChatResponse(ChatResponse):
  87. """增强的对话响应,包含搜索信息"""
  88. search_info: Optional[Dict] = Field(default=None, description="搜索信息")
  89. search_results: Optional[List[SearchResult]] = Field(default=None, description="搜索结果列表")
  90. class EnhancedStreamChunk(StreamChunk):
  91. """增强的流式响应块,包含搜索信息"""
  92. search_info: Optional[Dict] = Field(default=None, description="搜索信息")
  93. search_results: Optional[List[SearchResult]] = Field(default=None, description="搜索结果列表")