重构回忆录为 story-first / markdown-first 架构并整合图片意图与前端 UI 修复
本次 squash merge 将 codex-story-first-image-intent 的整体改动合入 development,核心内容包括: 1. 后端数据与迁移:新增 stories、story_versions、story_image_intents、chapter_cover_intents、assets 等模型与 Alembic 迁移,建立 story-first、markdown-first、asset-first 的主数据链路。 2. 生成与任务链:引入 StoryBuilderOrchestrator、ChapterComposerOrchestrator、story_image_tasks、chapter_cover_tasks,图片生成从正文占位符改为结构化 intent -> asset -> markdown 回填。 3. 并发与一致性:为 story/chapter intent 增加 claim_token、claimed_at、attempt_count,采用数据库原子 claim 为主、Redis 锁为辅,避免重复生成、锁误删和 processing 卡死。 4. Memoir 读写路径:章节 canonical_markdown 成为正文真源,列表/详情接口补齐 markdown、cover_asset、word_count 等字段,PDF 与 asset 解析链路同步升级。 5. Memory / Retrieval:扩展 transcript ingest、chunking、evidence 检索与 story 聚合基础设施,为后续 story-first RAG 与多 agent 编排提供底座。 6. App 端体验:章节页继续走 MarkdownRenderer 阅读链,同时吸收 fix3-19 的跨平台 UI glitch 修复;更新对话页、首页、文案资源与章节列表映射逻辑。 7. 测试与文档:补充 asset resolver、story image task、章节封面派发、markdown 映射等回归测试,并加入图片占位符退役设计文档。
This commit is contained in:
@@ -57,8 +57,8 @@ _IMAGE_PLACEHOLDER_ANY_BRACES_RE = re.compile(
|
||||
|
||||
def inject_image_placeholder_template(content: str) -> str:
|
||||
"""
|
||||
入库前对章节正文做占位符处理:用正则匹配所有图片占位符位置,拼上固定模板。
|
||||
支持任意层数花括号,输出统一为四层大括号 + 固定模板 + 描述。
|
||||
对正文中的 IMAGE 占位符拼上固定风格模板(四层花括号)。
|
||||
**线上写路径已不使用**;保留供离线迁移脚本处理历史数据。
|
||||
"""
|
||||
if not content or not content.strip():
|
||||
return content
|
||||
@@ -92,7 +92,6 @@ def get_system_prompt() -> str:
|
||||
4. 将口语化表达改写为书面语,保持原意和情感
|
||||
5. 生成合适的章节标题和段落结构
|
||||
6. 提取关键信息,形成连贯的叙述
|
||||
7. 建议插图位置(在描述场景、人物、地点的地方)
|
||||
|
||||
## 内容筛选原则(最重要)
|
||||
对话中往往夹杂大量与回忆录无关的噪音,你必须严格筛选,只保留有价值的内容:
|
||||
@@ -171,24 +170,14 @@ def get_text_rewrite_prompt(
|
||||
请按照以下格式返回 JSON:
|
||||
{{
|
||||
"title": "章节标题",
|
||||
"content": "改写后的书面语内容(包含图片占位符)",
|
||||
"content": "改写后的书面语内容",
|
||||
"summary": "章节摘要(50字以内)"
|
||||
}}
|
||||
|
||||
要求:
|
||||
1. 标题要简洁有力,能概括章节主题
|
||||
2. 内容要流畅自然,保持原意和情感
|
||||
3. 如果已有章节内容,请将新内容与已有内容自然融合
|
||||
4. 在内容中适当位置插入图片占位符
|
||||
|
||||
## 图片占位符格式(必须严格遵守)
|
||||
- **唯一合法格式**:开头恰好四个左花括号、结尾恰好四个右花括号,中间为 IMAGE:具体描述。即:{{{{IMAGE:具体的图片描述}}}}
|
||||
- 禁止使用两层 {{ }}、六层 {{{{{{ }}}}}} 或任意其它层数,否则会在手机端显示异常。
|
||||
- 占位符单独占一行,描述要具体、有画面感。系统会在入库前自动拼上统一风格模板,你只需写场景描述即可。
|
||||
|
||||
正确示例(仅此格式):
|
||||
{{{{IMAGE:南方小镇的青石板路,两旁是白墙黑瓦的老房子}}}}
|
||||
{{{{IMAGE:奶奶坐在院子里的藤椅上,手里摇着蒲扇}}}}"""
|
||||
3. 如果已有章节内容,请将新内容与已有内容自然融合"""
|
||||
|
||||
|
||||
def get_state_extraction_prompt(
|
||||
@@ -350,30 +339,11 @@ def get_narrative_prompt(
|
||||
3. **只输出新内容的改写结果**,不要重复已有内容
|
||||
4. 如果有衔接上下文,确保新内容与之自然衔接(语气、时间线连贯)
|
||||
5. 语气自然,有情绪
|
||||
6. 在适合配图的地方插入图片占位符
|
||||
7. 如果有用户的基本信息(出生地、成长地等),在叙述中自然融入地域文化和时代背景
|
||||
6. 如果有用户的基本信息(出生地、成长地等),在叙述中自然融入地域文化和时代背景
|
||||
8. **不要将对话中的交互性语言(如"我跟你说"、"你知道吗")写入叙述**
|
||||
9. **不要在正文中插入章节标题或分类标签**(如"章节:信念与价值观"、"## 童年与成长背景"等),章节标题由系统单独管理
|
||||
|
||||
## 图片占位符格式(必须严格遵守)
|
||||
- **唯一合法格式**:开头恰好四个左花括号、结尾恰好四个右花括号,即:{{{{IMAGE:具体的图片描述}}}}
|
||||
- 禁止两层 {{ }}、六层 {{{{{{ }}}}}} 或其它层数,否则会在手机端显示多余花括号。
|
||||
- 占位符单独占一行,描述要具体、有画面感。系统会在入库前自动拼上统一风格模板,你只需写场景描述即可。
|
||||
|
||||
正确示例(仅此格式):
|
||||
- {{{{IMAGE:南方小镇的青石板路,两旁是白墙黑瓦的老房子}}}}
|
||||
- {{{{IMAGE:奶奶坐在院子里的藤椅上,手里摇着蒲扇}}}}
|
||||
- {{{{IMAGE:少年背着书包站在火车站台上,回望身后的小镇}}}}
|
||||
- {{{{IMAGE:泛黄的大学录取通知书,压在一摞旧课本下}}}}
|
||||
|
||||
图片占位符要求:
|
||||
- 描述要具体、有画面感,便于后续生成或匹配图片
|
||||
- 每 200-300 字左右可以插入一个
|
||||
- 单独占一行,不要嵌入段落中
|
||||
- 不要使用括号或星号等其他格式
|
||||
- **花括号必须且仅能为四层**:{{{{ 与 }}}} 各四个,不多不少
|
||||
|
||||
只输出新对话内容的改写结果(包含图片占位符)。如果对话中没有值得记录的人生经历内容,输出空字符串。
|
||||
只输出新对话内容的改写结果。如果对话中没有值得记录的人生经历内容,输出空字符串。
|
||||
"""
|
||||
|
||||
|
||||
@@ -415,19 +385,18 @@ def get_narrative_json_prompt(
|
||||
1. 从对话中提炼与人生经历相关的核心内容,过滤语气词、寒暄、与AI的交互
|
||||
2. 使用第一人称,改写为流畅的书面叙述,不要直接引用对话原话
|
||||
3. 只输出新内容的改写,不要重复已有内容
|
||||
4. 每 200-300 字左右一个段落,每个段落配一张图
|
||||
4. 每 200-300 字左右一个段落
|
||||
5. 如有衔接上下文,确保新内容与之自然衔接
|
||||
|
||||
## 输出格式(严格 JSON)
|
||||
{{
|
||||
"paragraphs": [
|
||||
{{"content": "段落正文", "image_description": "该段配图的场景描述,具体有画面感"}},
|
||||
{{"content": "段落正文"}},
|
||||
...
|
||||
]
|
||||
}}
|
||||
|
||||
- content: 本段纯正文,不含占位符
|
||||
- image_description: 该段配图的场景描述,具体、有画面感,便于生成图片。示例:南方小镇的青石板路,两旁是白墙黑瓦的老房子
|
||||
- content: 本段纯正文
|
||||
|
||||
如果对话中没有值得记录的人生经历内容,输出:{{"paragraphs": []}}
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user