fix(roundtable): 预期行为↔驱动因素严格 1:1,根治结构化抽取多对一/一节点多出边
报告把某行为体的多个驱动因素合并写进一个表格单元格(其余预期行为行留空), 导致结构化抽取把「多条预期行为汇聚到一个驱动因素」(多对一)、或一个节点冒出 多条连线。根因:1:1 两层节点数不相等时,模型与确定性补边(_derive_layered_edges) 都只能退化成多对一/比例平铺。 修复(让两层严格等量、一一配对): - extraction_spec rwfx relations_note①: 强化为「严格 1:1」——为每条预期行为归纳 那一个核心驱动因素、两层等量、每个驱动因素 from 只连一条预期行为、严禁多对一/ 一节点多出边;源数据把多个驱动因素合并在一处时必须按预期行为拆开/重新归纳成等量 - extraction_spec completeness_note: 驱动因素层节点数=预期行为层节点数(1:1 特例) - build_summary_directive: 让报告本身把 1:1 相邻层写成逐条配对表(一行一对、数量相等), 不要把多个下层条目用「+」合并塞进一个单元格或只写第一行——从源头消除多对一 - flow_extract 校验新增「一对一层级必须严格 1:1、绝不多对一」必查必补项 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
b5f11ad790
commit
8447790c47
2 files changed
+26
-8
No files matched your search
@@ -576,13 +576,18 @@ def _validate_messages(req: FlowExtractRequest, extracted: str) -> list[Any]:
|
||||
+ "层间关系(哪层一对一、哪层一对多)**以上面给出的业务链规范为准**:一对一层级按位次配对(下层第i条连上层第i条);"
|
||||
+ "**一对多**层级里下层每条连到它**所属**的那一条上层节点,**绝不能把多条上层节点汇聚到同一个下层节点**(那是把一对多画反成多对一,是本次要重点纠正的错)。"
|
||||
+ "缺 `from` / 把一对多画成多对一 是最常见错漏,**绝不能让任何非根节点悬空、也不要张冠李戴**;"
|
||||
+ "② **候选 / 多条目是否抽全(必查必补)**:对照数据来源逐层核对——候选目的、候选叙事、某行为体名下的多条预期行为等,"
|
||||
+ "② **一对一(1:1)层级必须严格 1:1、绝不多对一(按业务链规范,如预期行为↔驱动因素;本次重点纠错)**:"
|
||||
+ "这两层节点数**必须完全相等**、按位次一一配对;**每个下层节点的 `from` 只能写一条上层节点**,"
|
||||
+ "**绝不允许多条上层节点共用 / 汇聚到同一个下层节点**(多对一),也不允许同一条上层节点被多个下层节点指向"
|
||||
+ "(即 1:1 两层里任何节点都不能冒出 / 汇入多条连线)。若发现下层节点偏少(被合并)导致只能多对一,"
|
||||
+ "**必须按上层逐条拆分 / 补出等量的下层节点**(每条上层各配一个,内容综合提炼),使两层等量后再逐一配对;"
|
||||
+ "③ **候选 / 多条目是否抽全(必查必补)**:对照数据来源逐层核对——候选目的、候选叙事、某行为体名下的多条预期行为等,"
|
||||
+ "**报告/交付里有几条就该有几个节点**;发现被漏抽的候选项(尤其是没被选中的候选)、或被合并成一条的多个条目,"
|
||||
+ "**必须拆/补成独立节点**(落选候选项也要在,detail 注明候选/未选用)。报告条目被压缩时回到《各席位原始交付产物》补全。"
|
||||
+ "③ **每层每条都在、没漏层没漏条目**,节点数只能 ≥ 原图、不能变少;尤其一对多的下层(如某层一条对应下层多条)不要被合并成一条;"
|
||||
+ "④ 每个节点的 `group`(层级名)标对;一对一层级内条目按相同位次对齐,一对多层级下层每条紧挨其所属上层条目分组;"
|
||||
+ "⑤ 每个节点的 `detail` **原样保留、不要简化或精简理由**——理由要完整,不要删减内容;"
|
||||
+ "⑥ 没有汇总/阶段编号节点;只在确有错漏时才动,没问题就原样规范化输出。"
|
||||
+ "④ **每层每条都在、没漏层没漏条目**,节点数只能 ≥ 原图、不能变少;尤其一对多的下层(如某层一条对应下层多条)不要被合并成一条;"
|
||||
+ "⑤ 每个节点的 `group`(层级名)标对;一对一层级内条目按相同位次对齐,一对多层级下层每条紧挨其所属上层条目分组;"
|
||||
+ "⑥ 每个节点的 `detail` **原样保留、不要简化或精简理由**——理由要完整,不要删减内容;"
|
||||
+ "⑦ 没有汇总/阶段编号节点;只在确有错漏时才动,没问题就原样规范化输出。"
|
||||
+ "\n输出修复后的完整 ```flow-json 代码块(含全部节点 + 每个非根节点的 from)。"
|
||||
)
|
||||
return [SystemMessage(content=_system_prompt()), HumanMessage(content=user)]
|
||||
|
||||
+16
-3
@@ -64,7 +64,16 @@ _RWFX = ChainSpec(
|
||||
levels=["任务", "目的", "行为体", "预期行为", "驱动因素", "叙事"],
|
||||
relations_note=(
|
||||
"层间关系(务必分清一对一 / 一对多,连线别画反):\n"
|
||||
"① **「预期行为」与「驱动因素」一一对应**——两层数量必须相等、一个预期行为恰对一个驱动因素,按相同位次配对;\n"
|
||||
"① **「预期行为」与「驱动因素」严格一对一(1:1,本次必须重点纠正的错)**:\n"
|
||||
" 为**每一条**预期行为,归纳出驱动它的**那一个**核心驱动因素,两两配成一对——"
|
||||
"两层节点数**必须完全相等**(有 N 条预期行为就出 N 个驱动因素),按相同位次一一对应;\n"
|
||||
" 每个驱动因素的 from **只能写它对应的那一条预期行为**;**严禁多对一**:"
|
||||
"不许多条预期行为汇聚连到同一个驱动因素,也不许一条预期行为被多个驱动因素指向——"
|
||||
"**这两层里任何一个节点都不能冒出 / 汇入多条连线**(每条预期行为只伸出一条线连到它唯一的驱动因素);\n"
|
||||
" ⚠️ 数据来源常把某行为体的多个驱动因素**合并写在一处**(一个表格单元格里用「+」「、」连接、或「表层触发→深层」一整段、"
|
||||
"或只在第一条预期行为那行写驱动因素、其余行留空)——**这种情况绝不能抽成「一个驱动因素节点连到多条预期行为」**,"
|
||||
"而要**按预期行为把驱动因素拆开 / 重新归纳**:给每条预期行为各配一个驱动因素节点(其内容综合提炼该条预期行为背后最核心的那个原因),"
|
||||
"拆分 / 提炼后务必让两层等量、严格一一对应;\n"
|
||||
"② **「驱动因素」→「叙事」是一对多**——**一个驱动因素对应多个叙事**(每个驱动因素抽出它名下的若干条叙事),"
|
||||
"每条叙事的 from **连到它所属的那一个驱动因素**(叙事的上一层是驱动因素,不是预期行为);"
|
||||
"**绝不能把多个驱动因素汇聚连到同一个叙事节点**(那就把一对多画反成多对一了,是常见错误);也不要把全部叙事合并成一个节点;\n"
|
||||
@@ -75,7 +84,8 @@ _RWFX = ChainSpec(
|
||||
" · **目的**:报告若列了多个候选目的(如「Top 3 候选目的」「从8个优选出3个」),就把**这些候选目的全部**抽成"
|
||||
"目的节点(被标「确定」的也只是其中一个),不要只抽被选中的那一个;\n"
|
||||
" · **行为体 / 预期行为**:每个行为体名下报告列了几条预期行为(常 3-5 条)就出几个预期行为节点,**不许把一个行为体的多条预期行为合并成一条**;\n"
|
||||
" · 预期行为↔驱动因素 两层节点数必须相等并按位次配对(一个预期行为恰对一个驱动因素);\n"
|
||||
" · **驱动因素(1:1 特例,按上面①处理)**:驱动因素层节点数 **= 预期行为层节点数**——每条预期行为各配一个核心驱动因素,"
|
||||
"**绝不能因为报告把多个原因挤在一处 / 留空,就只抽 1 个驱动因素去连多条预期行为(多对一,本次最严重的错)**,也不要抽得比预期行为多;务必两层等量、位次一一配对;\n"
|
||||
" · **叙事**:报告若列了多个候选叙事方案(如「3 组候选叙事」),**全部**抽成叙事节点(含未选用的),不要只出一两个;"
|
||||
"叙事层通常比驱动因素层**更宽**,每条叙事连到它所属/对接的那一个驱动因素——不要让多个驱动因素指向同一叙事。"
|
||||
),
|
||||
@@ -180,7 +190,10 @@ def build_summary_directive(business_code: str | None) -> str:
|
||||
f"【{spec.label} 业务链完整性核对(强制)】本次为 {spec.label} 业务场景,其完整业务链层级为:{arrows}。\n"
|
||||
f"{spec.relations_note}\n"
|
||||
"撰写报告时请**额外核对各席位交付 + 共识是否完整覆盖了上述每一个层级**:"
|
||||
"报告文件本身按现有信息给出尽量完整的版本(**不要在 .md 文件里写「待补充」之类提示**);"
|
||||
"报告文件本身按现有信息给出尽量完整的版本(**不要在 .md 文件里写「待补充」之类提示**);\n"
|
||||
"⚠️ **呈现「一对一(1:1)」相邻层级时(如预期行为↔驱动因素)务必逐条配对**:每一条上层条目单独成一行、"
|
||||
"紧跟它**唯一对应的那一条**下层条目(一行一对、数量相等);**绝对不要把下层的多个条目用「+」「、」合并塞进一个单元格、"
|
||||
"也不要只在第一行写、其余行留空**——那会让后续结构化抽取把它误画成「多条上层汇聚到一个下层」(多对一)。每条上层条目都要有它自己专属的那一条下层条目。\n"
|
||||
"并在**对话回复正文、报告之后的「核对说明」里逐层说明各层级是否覆盖、缺了哪层 / 哪层条目不足**"
|
||||
"(即便各层级都已覆盖,也要写一句「各层级均已覆盖」),可在对话里让我补全;这段核对只在对话里、不写进 .md 文件,不要跳层。"
|
||||
)
|
||||
Reference in new issue
Block a user