assemble.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. """组装:把帖子+知识片段+解构,组装成 ingest 请求体(对齐 创作知识-重构设计.md §6)。
  2. 纯函数,无 LLM、无 IO。同一帖子拆出的多条知识复用同一 source.id。
  3. """
  4. from __future__ import annotations
  5. import json
  6. from creation_knowledge.models import (
  7. Deconstruction,
  8. IngestPayload,
  9. KnowledgeItem,
  10. Post,
  11. )
  12. def build_ingest_payload(
  13. post: Post, item: KnowledgeItem, deco: Deconstruction
  14. ) -> IngestPayload:
  15. content = json.dumps(
  16. {"what": item.what, "why": item.why, "how": item.how},
  17. ensure_ascii=False,
  18. )
  19. custom_ext: list[dict] = []
  20. if item.source_cards:
  21. custom_ext.append(
  22. {"key": "来源卡片", "type": "str",
  23. "value": "、".join(f"卡片{n}" for n in item.source_cards)}
  24. )
  25. if item.evidence:
  26. ev = " / ".join(
  27. f"{e.text}(卡片{e.card})" if e.card else e.text for e in item.evidence
  28. )
  29. custom_ext.append({"key": "原文证据", "type": "str", "value": ev})
  30. if deco.stage_reason:
  31. custom_ext.append(
  32. {"key": "阶段判断理由", "type": "str", "value": deco.stage_reason}
  33. )
  34. if deco.scope_reason:
  35. custom_ext.append(
  36. {"key": "作用域判断理由", "type": "str", "value": deco.scope_reason}
  37. )
  38. return IngestPayload(
  39. source={
  40. "id": post.id,
  41. "source_type": "post",
  42. "title": post.title,
  43. "author": post.author_name,
  44. "source_metadata": {"platform": post.platform, "url": post.url},
  45. },
  46. title=item.title,
  47. content=content,
  48. dim_attributes=list(item.knowledge_types),
  49. dim_creations=list(deco.stages),
  50. scopes=[{"scope_type": s.scope_type, "value": s.value} for s in deco.scopes],
  51. custom_ext=custom_ext,
  52. )