models.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. """取数 / 多模态读取的数据结构(pydantic)。
  2. 只保留基建用到的类型:帖子(Post)、视觉卡片(Card)、多模态提取产物(ExtractedContent)。
  3. """
  4. from __future__ import annotations
  5. from typing import Literal, Optional
  6. from pydantic import BaseModel, Field
  7. CardKind = Literal["image", "frame", "segment"]
  8. class Card(BaseModel):
  9. """一张"卡片":图文帖的一张图、视频抽出的一帧,或原生视频提炼出的一个时间段。
  10. 下游溯源只认 index(1-based)。"""
  11. index: int
  12. kind: CardKind = "image"
  13. url: Optional[str] = None # 段卡可无图;图片/帧有 url
  14. timestamp: Optional[float] = None # 仅 frame:该帧在视频中的秒数
  15. start: Optional[float] = None # 仅 segment:起始秒
  16. end: Optional[float] = None # 仅 segment:结束秒
  17. class Post(BaseModel):
  18. """fetch_post_detail 的产物:一条帖子的原始内容(文本 + 图片 + 视频)。"""
  19. id: str # xhs_<content_id>,复用为 ingest source.id
  20. platform: str = "xiaohongshu"
  21. provider: str = ""
  22. url: str
  23. content_id: str
  24. unique_key: str = ""
  25. title: str = ""
  26. content_type: str = "" # video / 图文
  27. content_mode: str = "" # image_post / video_post / article / unsupported
  28. body_text: str = ""
  29. media_count: int = 0
  30. cover_url: Optional[str] = None
  31. topic_list: list[str] = Field(default_factory=list)
  32. image_urls: list[str] = Field(default_factory=list)
  33. video_urls: list[str] = Field(default_factory=list)
  34. cards: list[Card] = Field(default_factory=list) # 统一视觉卡片(图/帧)
  35. author_id: Optional[str] = None
  36. author_name: Optional[str] = None
  37. raw: dict = Field(default_factory=dict) # 原始响应
  38. class CardExtract(BaseModel):
  39. """某张卡片上提取到的知识要点(按卡片归因)。"""
  40. index: int
  41. content: str = ""
  42. class ExtractedContent(BaseModel):
  43. """extract_content 的产物:多模态汇总后的真实内容。不直接用 body_text。"""
  44. text: str = "" # 汇总后的正文/讲解
  45. cards: list[CardExtract] = Field(default_factory=list) # 按卡片归因的提取
  46. from_image: str = "" # 兼容保留:图片里提取到的知识要点
  47. from_video: str = "" # 兼容保留:视频里提取到的知识要点
  48. is_empty: bool = False # 多模态提取后仍无有效内容