feat(memoir): 路由阶段不要求标题,按正文字数门闸延迟 LLM 标题
- 从 story 路由 prompt/校验中移除 new_story_title,改由叙事管线在正文足够长时生成 - 新增 story_title_min_body_chars;短正文使用章节类别占位标题 - CATEGORY_TO_CHAT_STAGE 对齐访谈 state.slots 的 stage 键 - 删除相对口述长度的叙事回退,仅保留 merge JSON 极端缩水类 fallback - evidence_format:解析 object_json 并优化事实条目标点符号 - 更新 narrative / experience 相关单测
This commit is contained in:
@@ -401,8 +401,6 @@ def get_story_route_prompt(
|
||||
|
||||
「故事」在此指:**可独立讲述的一段人生经历**——单一主题或同一事件链;不要假设本批里包含多个互不相关的故事(多段由系统其它步骤处理)。
|
||||
|
||||
**new_story_title 与 reason 只能依据口述中已有信息概括,不得编造口述未出现的人、事、地、物。**
|
||||
|
||||
**路由边界(必须遵守)**:仅根据下方「本批口述合并文本」判断 new_story 与 append_story;不得将系统检索摘要、记忆摘录、图谱事实或其它非用户口述材料当作本批口述内容来匹配候选故事。
|
||||
|
||||
当前章节(写作容器):
|
||||
@@ -419,13 +417,11 @@ def get_story_route_prompt(
|
||||
{{
|
||||
"decision": "new_story" | "append_story",
|
||||
"target_story_id": "<uuid 或 null;append 时必填且必须来自候选>",
|
||||
"new_story_title": "<短标题,6-20 字;new_story 时必填,append 时可 null>",
|
||||
"reason": "<一句中文理由>"
|
||||
}}
|
||||
|
||||
规则:
|
||||
- 若无法自信匹配某一候选,选 new_story
|
||||
- new_story_title 应概括本批新内容,不要与候选标题重复
|
||||
"""
|
||||
|
||||
|
||||
@@ -444,8 +440,6 @@ def get_story_batch_plan_prompt(
|
||||
## 「故事」定义(必须遵守)
|
||||
一段「故事」= **可独立讲述的一段人生经历**:单一主题或同一事件链,能单独成篇。若话题切换、时间线跳到另一件事、人物/主线明显变化,应作为**新的故事**(new_story),而不是塞进同一段 append。
|
||||
|
||||
**new_story_title 与 reason 只能依据各 segment 文本中已有信息,不得编造口述未出现的事实。**
|
||||
|
||||
## 任务
|
||||
将本批 segment **划分为连续若干块**(每块包含至少一个 segment,顺序不能打乱;每个 segment 必须恰好属于一块)。对每一块决定:
|
||||
- **append_story**:内容明显延续、补充**某一已有候选故事**的主题与时间线,且能对应到具体 candidate id
|
||||
@@ -468,7 +462,6 @@ def get_story_batch_plan_prompt(
|
||||
"segment_ids": ["<按顺序列出本块包含的 segment id>"],
|
||||
"decision": "new_story" | "append_story",
|
||||
"target_story_id": "<uuid 或 null;append 时必填且必须来自候选>",
|
||||
"new_story_title": "<短标题,6-20 字;new_story 时必填,append 时可 null>",
|
||||
"reason": "<一句中文理由,可选>"
|
||||
}}
|
||||
]
|
||||
@@ -477,7 +470,6 @@ def get_story_batch_plan_prompt(
|
||||
规则:
|
||||
- `units` 中所有 `segment_ids` 拼接后,必须**不重不漏**地覆盖本批全部 id,且顺序与【本批口述片段】数组一致
|
||||
- 若无法自信匹配某一候选,对该块选 new_story
|
||||
- new_story_title 应概括该块内容,不要与候选标题重复
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -116,7 +116,8 @@ def validate_story_batch_plan(
|
||||
valid_story_ids: set[str],
|
||||
) -> tuple[bool, str | None]:
|
||||
"""
|
||||
校验:segment 全覆盖、顺序一致、append 目标合法、new_story 有标题。
|
||||
校验:segment 全覆盖、顺序一致、append 目标合法。
|
||||
标题由 NarrativeAgent 延迟生成,路由阶段不再要求 new_story_title。
|
||||
返回 (ok, error_code)。
|
||||
"""
|
||||
if not plan.units:
|
||||
@@ -135,10 +136,6 @@ def validate_story_batch_plan(
|
||||
tid = u.target_story_id
|
||||
if not tid or tid not in valid_story_ids:
|
||||
return False, "invalid_append_target"
|
||||
else:
|
||||
title = (u.new_story_title or "").strip()
|
||||
if not title:
|
||||
return False, "missing_new_title"
|
||||
return True, None
|
||||
|
||||
|
||||
@@ -196,10 +193,6 @@ class StoryRouteAgent:
|
||||
new_story_title=decision.new_story_title,
|
||||
reason="invalid_target",
|
||||
)
|
||||
if decision.decision == "new_story" and not (
|
||||
decision.new_story_title and decision.new_story_title.strip()
|
||||
):
|
||||
decision.new_story_title = None
|
||||
return decision
|
||||
|
||||
def plan_batch(
|
||||
|
||||
Reference in New Issue
Block a user