#!/usr/bin/env python3 """Prompt templates for the staged pipeline. Kept in one module so wording changes are reviewable in isolation — prompt text is the most-edited and least-typechecked part of the system. """ CLEAN_SYS = ( "你只做会议转写的去口语化和断句,不做事实判断、术语纠错或总结。" ) CLEAN_RULES = """任务:对给定片段做「去口语化」。 只做三件事: 1. 删除无意义语气词、结巴和紧邻的机械重复。 2. 补标点,把明显破碎的口语整理成可读句子。 3. 保留原有说话人分段。 不要总结,不要纠正人名、术语或数字,不要增加解释。听不懂的词原样保留。 数字、英文、项目代号、【说话人】和 `[…重复噪声已折叠:…]` 必须保留。 只输出清洗后的正文。""" NORMALIZE_SYS = ( "你是会议转写的实体、术语和数字规范化裁决器。只处理给出的候选,不做去口语化或总结。" ) NORMALIZE_RULES = """任务:在清洗文本中裁决候选词并作最小修改。 - A 组映射已经由程序执行,不要撤销。 - B 组只有在整句语义、人物/公司/项目关系和近期语境共同支持时才替换。 - 多个候选无法区分时保留原词,紧跟 `[?候选A/候选B]`。 - 中文数字仅在类型和单位明确时转成阿拉伯数字;项目编号逐字转换,如“四幺八二”→“4182”。 - 数值、单位或身份不确定时保留原文并加 `[?…]`,不得猜测。 - 不增加候选清单和背景资料中没有的事实。 只输出规范化后的正文,保留全部【说话人】标签。""" EVIDENCE_SYS = "你从一段会议转写中提取可追溯的事实卡片,不撰写纪要。" EVIDENCE_PROMPT = """从下面片段提取值得进入会议草稿的关键信息。 保留:结论、决定、行动项、负责人、关键数字、争议、未决问题、重要关系和判断依据。 省略:寒暄、重复表态、无意义细节。 不得补充背景事实,不确定的主体或数字必须标“待确认”。 每条都带片段编号 `{chunk_id}`,格式: - [片段 {chunk_id}] 类型|主体|事实或线索|置信度:明确/较可信/待确认 片段: {body}""" JUDGE_RULES = """附加任务:术语/人名校正裁决。 下面给出脚本按「发音相近 + 本场语境」自动圈出的**候选**(只是嫌疑,未必对)。 每个候选都带来源说明,括号里的含义: - `已确认别名`:Kai 已经确认过的固定叫法或已知误识别映射。**证据最强**,若句子读得通就应当替换。 - `机构简称`/`去姓称名`/`称谓`:口语里的简称形式(如「迈威」指迈威生物、「光辉」指李光辉、 「老万」「万总」指姓万的人)。**这类是正常口语,不是错字**——判定为同一实体后直接用全名。 - `一字之差`/`同篇另一写法`:同一实体在本篇中的其他写法,通常是转写漂移,应统一。 - `X(本次在谈)`:该候选所属公司正是本次录音讨论的对象,是**强支持证据**。 - `X(近期相关)`:该公司近期与本人有往来,是弱支持证据。 候选分两组: - **A 组「已确认映射」**:Kai 已人工核对的固定对应。只要句中该词确实指人/机构,**必须替换**, 不要保留原写法、不要加「疑似」、不要标 `[?…]`。这类是 ASR 的固定误识别或口语简称, 不是需要你判断的疑点。 - **B 组「待判断候选」**:只是嫌疑,按下面规则裁决。 逐条按**它所在的整句**判断: - 如果原词在句中读得通(是常用词、副词、动宾结构),**保留原词**,不要改。 - 候选带「已确认别名」或带「(本次在谈)」支持、且句中指的确实是人/机构时,**应当替换为全名**, 不要因为"转写没明说"而回避——简称就是口语常态。 - 同一候选有多个可能人物时(例如「徐总」可能是三个人),**不要硬选**:保留原词并标注 `[?候选A/候选B]`,把判断留给后续环节。 - 其余拿不准的:保留原词,并在该词后紧跟标注 `[?候选词]`(例如 `元烨[?原液]`)。 - 标注了「此词本身是常用词」的,默认保留原词,除非句子完全读不通。 候选清单: {candidates}""" CONTEXT_FOR_CLEAN = """本场背景(来自既有笔记与长期记忆,仅供你判断术语与人名的写法,**不要**把这些内容写进输出): {context}""" KEYWORD_PROMPT = """从下面的会议转写摘选中,提取用于检索背景资料的关键词。 只要专有名词:人名、公司名、项目/产品代号、机构、专业术语。 转写有识别错误,可以给出你认为正确的写法。 输出一行,用空格分隔,最多 25 个词,不要任何其他内容。 转写摘选: {sample}""" # The provenance rule below exists because of a measured failure: with background # context injected, drafts asserted context-derived facts as transcript facts # (「谭凯(白帆生物总经理)」、「此项目负责人为 [[冯昆仑]](背景确认)」) even when the # recording never said them. The facts were often correct, but a meeting note that # cannot distinguish "said on the call" from "known from notes" is unsafe to finalize. DRAFT_PROMPT = """你是会议录音整理助手,正在根据**带来源编号的事实卡片**产出「粗整理草稿」。 严格遵循: 1. 只产出粗整理草稿,**不是**正式纪要。 2. 清楚区分三类信息:明确事实 / 讨论中的想法 / 推测·高不确定。 3. **出处标注(重要)**:本草稿的每一条断言都必须能追溯到来源。 - 来自本次转写的内容:正常写。 - 来自下方「本场背景」而转写中**没有**说到的内容(例如某人的职务、公司归属、 项目历史):必须加后缀 `〔背景〕`,并且**不得**写成「明确事实」。 - 你自己的推断:加后缀 `〔推断〕` 或写「疑似」。 - 绝不把背景知识或推断伪装成转写内容。转写里没说的职务、公司名、金额、日期, 一律不能不加标注地断言。 4. 用 [[双链]] 标注有把握的人物/公司/项目;不确定的用纯文本 + 「疑似」。 5. 转写中形如 `词[?候选]` 的标注表示清洗阶段无法确定的词,请结合全文语境判断, 并在「待确认」中列出。 6. 形如 `[…重复噪声已折叠:…]` 的标记表示该处录音是长段非语音噪声(保持音/静默), 不要当成内容;如影响理解可在「待确认」提一句。 7. 末尾必须有一节 `## 待你确认`,列出需要人工复核的关键不确定点(名词、说话人归属、 日期、金额、结构)。 7a. 正文标题后、议题正文前必须先写 `## 通话背景(待确认)`,用 2-4 句话概括: 通话类型、参与方、正在处理的事项、各方关系。只写本次转写能支持的内容;推断必须 明标「疑似」。这段会先交给用户判断背景是否靠谱,以及是否值得携带正确背景重跑。 **结构要求(按议题归拢,不要平铺)**: 8. 正文按**议题**分节(一、二、三…),一个议题一节。每节内部用这个顺序: 先一句「结论/当前状态」,再列支撑事实,最后写「待办/下一步」(如果有)。 同一议题的事实必须收在同一节,不要因为在录音里出现的先后不同就拆成多条平行 bullet。 9. 事实合并:同一件事的多次提及、同一金额/时间的重复确认、同一人的多轮补充, **合并成一条**并保留关键数字与限定条件,不要逐句罗列。 单节内的 bullet 控制在 7 条以内;超出说明该拆成子议题或该合并。 10. 每条 bullet 只讲一件事,避免「A,同时 B,另外 C」的堆叠长句。 **关于人名与简称(重要)**: 11. 转写里的简称、称谓、老X/X总/X博就是口语常态,不是缺陷。若上下文足以确定指谁 (例如正在谈某公司、而背景里该公司只有一位对应角色的人),**直接写全名并加 [[双链]]**, 不要写成「具体身份不确定,需人工核实」。这类过度回避会让草稿失去价值。 12. 只有在**真的存在多个候选且无法区分**时才标「疑似」,并把候选一起列出 (例如「徐总(疑似 [[徐劲前]] 或 [[邹洵]])」),而不是笼统写「身份不明」。 13. 判定简称指向谁时使用背景里的任职信息,这属于**辨识**而非越界断言, 不需要加〔背景〕;但如果你要额外陈述这个人的职务、公司归属本身,那就要加〔背景〕。 14. 对匿名说话人,除非事实卡片已经给出有证据的候选,否则只写“身份待确认”; 不要从背景中枚举可能的人名让用户猜。 {speaker_note} {context} frontmatter 严格用下列字段: --- date: {date} type: minutes tags: [会议纪要, 草稿, 待确认] source: 录音转录 source_detail: {source_detail} status: 草稿待确认 people: [有把握的人名…] companies: [有把握的公司…] transcript: {transcript} {extra_fm}--- 事实卡片: {body} 只输出 markdown 草稿全文,不要任何额外说明。""" SPEAKER_NOTE = { "qwen3cam": ( "转写来自 Qwen3-ASR + CAM++ 分角色 + 声纹:\n" "- 中文真名的说话人是**声纹已确认**的,直接用,不要写「疑似」。\n" "- `speaker_N` 是声纹未命名的说话人,按内容/口吻推断是谁并标「疑似」。\n" "- 不同 speaker_N 是不同真人(CAM++ 已分),但可能过度聚类(同一人被拆成多个 N)," "按内容合并同一真人。\n" "- frontmatter 的 people 优先填**声纹命名的真人**。"), "vibevoice": "转写带 S# 说话人标签,仅作软提示,块间编号不保证一致。", "qwen3-plain": "转写**无说话人信息**,据内容推断发言归属,不要臆造 speaker 标签。", }