框架: parse试拆三轮病理修复——ingest字段指纹改型+0卡不软删(防重跑自噬损耗)+parse_llm判重名录排除本章

This commit is contained in:
zizi 2026-07-13 16:28:08 +08:00
parent 7be76b9ebb
commit 5ab7783b09
2 changed files with 27 additions and 10 deletions

View File

@ -171,12 +171,15 @@ def patterns(work_id, chapter_order, file_):
ch_id, src = chapter_of(conn, work_id, chapter_order)
contracts = {t: field_contract(conn, t) for t in PATTERN_TYPES}
book = conn.execute("SELECT title FROM muse_content_work WHERE id=%s", (work_id,)).fetchone()[0]
# 幂等:重跑本章 = 软删本章旧 draft
conn.execute(
"""UPDATE muse_knowledge_draft SET deleted=TRUE, updater=%s
WHERE tenant_id=%s AND source_type='parse_book' AND source_id=%s
AND draft_payload->>'章序'=%s AND deleted=FALSE""",
(ACTOR, TENANT, work_id, str(chapter_order)))
# 幂等:重跑本章 = 软删本章旧 draft。
# 但新轮 0 卡时保留旧卡——LLM 判卡有随机性,重跑「0 卡」不应清掉上轮已验证的产出
#(实测组合病:判重名录+随机性+软删 → 每次重跑都损耗卡)
if cards:
conn.execute(
"""UPDATE muse_knowledge_draft SET deleted=TRUE, updater=%s
WHERE tenant_id=%s AND source_type='parse_book' AND source_id=%s
AND draft_payload->>'章序'=%s AND deleted=FALSE""",
(ACTOR, TENANT, work_id, str(chapter_order)))
ok, rejected = 0, []
for i, c in enumerate(cards):
t = c.get("型")
@ -189,10 +192,19 @@ def patterns(work_id, chapter_order, file_):
if not (src_ref.get("书名") and src_ref.get("回目")):
reasons.append("出处不完整(需书名+回目)")
fields = c.get("字段") or {}
if t in contracts:
retyped = None
if t in contracts and fields:
illegal = set(fields) - contracts[t]
if illegal:
reasons.append(f"字段越合同:{sorted(illegal)}")
# 字段指纹改型:LLM 的 type 标注不可靠(实测 M3 系统性全标 craft),
# 五型字段 key 互不重叠——字段集合全命中唯一他型合同时,以字段为准改型
fits = [t2 for t2 in PATTERN_TYPES
if t2 != t and fields and set(fields) <= contracts[t2]]
if len(fits) == 1:
retyped = f"{t}→{fits[0]}(字段指纹改型)"
c["型"] = t = fits[0]
else:
reasons.append(f"字段越合同:{sorted(illegal)}")
texts = [c.get("名称"), c.get("一句话摘要"), *fields.values()]
leak = leak_check([x for x in texts if x], src)
if leak:
@ -203,6 +215,8 @@ def patterns(work_id, chapter_order, file_):
payload = {"型": t, "名称": c["名称"], "一句话摘要": c.get("一句话摘要", ""),
"字段": fields, "出处": src_ref, "目标库": "公共范式库",
"章序": chapter_order, "来源": f"拆书@{book}", "状态": "草稿"}
if retyped:
payload["改型"] = retyped # 审计:机械改型可追溯
cid = f"parse-{work_id}-{chapter_order}-{i}-" + hashlib.sha256(
json.dumps(payload, ensure_ascii=False, sort_keys=True).encode()).hexdigest()[:8]
conn.execute(

View File

@ -167,10 +167,13 @@ def main(work_id, from_, to, model):
JOIN muse_content_chapter c ON c.id=s.chapter_id
WHERE s.tenant_id=%s AND s.work_id=%s AND c.order_no<%s AND s.deleted=FALSE""",
(TENANT, work_id, ch)).fetchall() for e in ents]
# 判重名录排除本章自己的卡:否则重跑时 M3 对着自己首轮的卡判重不出卡,
# ingest 幂等软删旧卡后插 0 张——卡被自己删了(重跑自噬,实测病)
cards = conn.execute(
"""SELECT draft_payload->>'型', draft_payload->>'名称' FROM muse_knowledge_draft
WHERE tenant_id=%s AND source_type='parse_book' AND deleted=FALSE""",
(TENANT,)).fetchall()
WHERE tenant_id=%s AND source_type='parse_book' AND deleted=FALSE
AND NOT (source_id=%s AND (draft_payload->>'章序')::int=%s)""",
(TENANT, work_id, ch)).fetchall()
outline = None
if s_st == "done":
r = conn.execute(