| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- """流水线各环节的数据结构(pydantic)。字段对齐业务设计 创作知识-重构设计.md。"""
- from __future__ import annotations
- from typing import Literal, Optional
- from pydantic import BaseModel, Field
- KnowledgeType = Literal["what", "why", "how"]
- ScopeType = Literal["substance", "form", "feeling", "effect", "intent"]
- Stage = Literal["灵感", "选题", "脚本"]
- CardKind = Literal["image", "frame", "segment"]
- class Card(BaseModel):
- """一张"卡片":图文帖的一张图、视频抽出的一帧,或原生视频提炼出的一个时间段。
- 下游溯源只认 index(1-based)。"""
- index: int
- kind: CardKind = "image"
- url: Optional[str] = None # 段卡可无图;图片/帧有 url
- timestamp: Optional[float] = None # 仅 frame:该帧在视频中的秒数
- start: Optional[float] = None # 仅 segment:起始秒
- end: Optional[float] = None # 仅 segment:结束秒
- class Post(BaseModel):
- """fetch_post_detail 的产物:一条帖子的原始内容(文本 + 图片 + 视频)。"""
- id: str # xhs_<content_id>,复用为 ingest source.id
- platform: str = "xiaohongshu"
- url: str
- content_id: str
- title: str = ""
- content_type: str = "" # video / 图文
- body_text: str = ""
- topic_list: list[str] = Field(default_factory=list)
- image_urls: list[str] = Field(default_factory=list)
- video_urls: list[str] = Field(default_factory=list)
- cards: list[Card] = Field(default_factory=list) # 统一视觉卡片(图/帧)
- author_id: Optional[str] = None
- author_name: Optional[str] = None
- raw: dict = Field(default_factory=dict) # 原始响应,整体落 ck_post.raw
- class CardExtract(BaseModel):
- """某张卡片上提取到的知识要点(按卡片归因)。"""
- index: int
- content: str = ""
- class ExtractedContent(BaseModel):
- """extract_content 的产物:多模态汇总后的真实内容。不直接用 body_text。"""
- text: str = "" # 汇总后的正文/讲解
- cards: list[CardExtract] = Field(default_factory=list) # 按卡片归因的提取
- from_image: str = "" # 兼容保留:图片里提取到的知识要点
- from_video: str = "" # 兼容保留:视频里提取到的知识要点
- is_empty: bool = False # 多模态提取后仍无有效内容
- class ScreeningResult(BaseModel):
- """screen_post 的产物。"""
- passed: bool
- score: int = 0
- reason: str = ""
- class Evidence(BaseModel):
- """一条原文证据,链接到它出自的卡片(纯正文证据 card=None)。"""
- text: str
- card: Optional[int] = None
- class KnowledgeItem(BaseModel):
- """split_post 拆出的一个知识片段。knowledge_types 必须与非空的 what/why/how 一致。"""
- title: str
- knowledge_types: list[KnowledgeType]
- what: Optional[str] = None
- why: Optional[str] = None
- how: Optional[str] = None
- source_cards: list[int] = Field(default_factory=list) # 这条知识出自哪些卡片
- evidence: list[Evidence] = Field(default_factory=list)
- class Scope(BaseModel):
- scope_type: ScopeType
- value: str # 具体标签,不只是大类名
- class Deconstruction(BaseModel):
- """deconstruct_item 的产物:阶段 + 作用域。"""
- stages: list[Stage] = Field(default_factory=list)
- scopes: list[Scope] = Field(default_factory=list)
- stage_reason: str = ""
- scope_reason: str = ""
- class IngestPayload(BaseModel):
- """build_ingest_payload 的产物:对齐 创作知识-重构设计.md §6 的 ingest 请求体。"""
- source: dict
- title: str
- content: str # JSON 字符串 {"what":...,"why":...,"how":...}
- dim_attributes: list[str]
- dim_creations: list[str]
- scopes: list[dict]
- custom_ext: list[dict] = Field(default_factory=list)
|