# 听记发言人智能匹配

> 从钉钉听记中定向提取并总结指定人物的发言内容。
> 产品命令见 [minutes.md](../products/minutes.md)、`aisearch`（开源版未引入，悟空内部产品）、[chat.md](../products/chat.md)、[doc.md](../products/doc.md)。

| Recipe                    | 行动指南（固定路线）                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ------------------------- |   |
| minutes-speaker-summarize | 1. **读取转写**：有 URL → 提取 `taskUuid` → `minutes get transcription --id <uuid>`；有时间/关键词 → `minutes list all` 筛选 → 获取转写；无信息 → 必须询问 2. **声纹标注检查**：已标注真实姓名 → 直接跳 Step 6；仅匿名编号（发言人1/2/3）→ 继续 3. **转写原文推断**：利用称呼、自我介绍、上下文指代、发言顺序推断，高置信度 → 跳 Step 6；无法确定 → 继续 4. **并发身份推断**：`aisearch person --keyword "<姓名>" --dimension name` & `chat message list` 取近期 IM & `doc search --keyword "<姓名>"` 前 3 篇 `& wait`；两路以上一致才下结论 5. **置信度判断**：>70% → 直接输出；≤70% → 展示 TOP3 候选音频片段让用户选（最多一次，"都不是"则终止） 6. **结构化总结输出**：核心观点 + 问题/关注点 + Action Item + 立场态度；输出后追问是否替换发言人标注 |

---

## 触发条件

**TRIGGER** when ANY of the following are true:
- 用户提供了听记来源（URL / 时间 / 关键词可定位）**且**指定了一个具体人名（花名/真名/职位称谓均可），目标是获取该人在会议中说了什么
- 用户从 `minutes-detail` 的发言人列表中选定某位发言人，要求查看其内容总结
- 用户贴了听记链接，发言人未完全识别（存在匿名编号），需要做批量智能匹配

**DO NOT TRIGGER** when:
- 用户只要整体纪要，未指定特定人物 → 用 `minutes get summary`
- 用户想纠错发言人标注 → 告知在听记详情页 GUI 操作
- 用户想提取待办 → `meeting-followup` recipe

---

## 详细步骤

### Step 1：读取听记转写

- 有 URL → 从 URL 提取 `taskUuid` → `dws minutes get transcription --id <uuid>`
- 有时间/关键词 → `dws minutes list all` 筛选 → 获取转写
- 什么都没给 → **必须询问**

### Step 2：声纹标注检查

- **已标注真实姓名** → 直接跳 Step 6
- **仅有匿名编号**（发言人1/2/3）→ 继续 Step 3

### Step 3：转写原文推断（优先）

充分利用转写文本中的称呼、自我介绍、上下文指代、发言顺序、内容特征进行推断。能从原文高置信度确定发言人 → 直接跳 Step 6。无法确定 → 继续 Step 4。

### Step 4：并发身份推断

**同时**发起多路查询，不串行等待：

| 优先级 | 路径               | 做什么                                                                                               |
| ------ | ------------------ | ---------------------------------------------------------------------------------------------------- |
| ① 最高 | 日程参与人         | 从听记 info 提取会议时间 → `dws calendar event list --start <会议开始-30min> --end <会议结束+30min>` → 匹配同时段日程 → `dws calendar participant list --event <eventId>` → 获取参与人姓名列表，与转写中匿名发言人做数量/顺序对照 |
| ② 高   | 通讯录 + 组织架构  | `dws aisearch person --keyword <姓名> --dimension name` → 部门/职级/上级/汇报关系                    |
| ③ 高   | 聊天记录           | `dws chat message list` 获取与目标人的近期 IM 消息 → 工作内容/语言风格/职责线索                       |
| ④ 兜底 | 本人文档           | `dws doc search --keyword <姓名>` 取前 3 篇标题+摘要 → 角色精确信号                                   |

**日程参与人匹配规则**（路径①专用）：
- 日程参与人数 = 转写发言人数 → 高置信度，按发言顺序/内容特征一一对应
- 日程参与人数 > 转写发言人数 → 有人未发言，需结合角色推断缩小范围
- 日程参与人数 < 转写发言人数 → 有人未在日程中，需补充其他路径
- **未找到同时段日程** → 主动引导用户：「未找到与该听记时间匹配的日程，是否可以提供会议对应的日程链接或参会人员名单？这将帮助更准确地识别发言人」

**判定规则**：
- 日程参与人 + 通讯录两路信号一致 → 确认身份，置信度最高
- 通讯录 + 聊天两路信号一致 → 确认角色，置信度高，通常无需再查文档
- 仅一路可用或信号矛盾 → 补查文档兜底，两路以上一致才下结论

> 部门名 ≠ 角色，不能用「产品设计部」直接推断是产品设计师；聊天记录往往最直接反映日常工作内容。

**文档类型与角色对照**（仅在文档兜底时参考）：
- PRD/需求文档/商业化方案 → 产品经理
- 视觉规范/原型说明/交互评审 → 产品设计师
- 技术方案/架构设计 → 研发工程师
- 分析报告/底表说明 → 数据分析师

### Step 5：置信度分支

基于 Step 4 角色，在转写中匹配发言模式（产品经理提需求/定优先级，研发讲技术约束，管理者高占比做决策，设计师讲交互细节）。

#### 分支 A：置信度 > 70% → 直接输出总结

无需任何确认，直接进入 Step 6。

#### 分支 B：置信度 ≤ 70% → TOP3 候选音频（仅一次）

列出置信度最高的 TOP3 候选发言人（必须来自不同发言人，不重复），每人附一段代表性转写片段：

> 以下是本次会议中可能是 [人名] 的候选，请确认：
>
> **候选 1**（置信度最高）
> 对应文字："[转写文本片段]"
>
> **候选 2**
> 对应文字："[转写文本片段]"
>
> **候选 3**
> 对应文字："[转写文本片段]"
>
> 请问 [人名] 是哪一位？（1 / 2 / 3 / 都不是）

- 用户选 1/2/3 → 进入 Step 6
- 用户说"都不是" → 告知无法确认，建议在听记详情页手动标注，**不再重复**

### Step 6：总结输出

提取该发言人的全部发言，结合会议上下文综合总结：

```
[人名] 在本次会议中的发言总结

**核心观点**
- 观点1
- 观点2

**提出的问题 / 关注点**（如有）
- ...

**Action Item / 承诺事项**（如有）
- ...

**立场 / 态度**（如有明确倾向）
- ...
```

输出完成后追问：

> 要在本篇听记里把「发言人 X」替换成「[人名]」吗？替换后系统会记住声纹特征，下次会议自动识别。[替换] [暂不]

---

## 核心约束

- **禁止暴露 Speaker_X 编号**：追问中用「发言人 X」等用户可感知的描述，不暴露内部格式
- **禁止碰运气播音频**：必须先做身份预推断，再定向选片段
- **声纹库命中时直接输出**：不做任何额外确认
- **置信度 > 70% 直接输出**：不需要确认
- **音频确认最多一次**：用户说"都不是"则终止，不重复
- **先完成任务，后引导替换**：总结输出完成后再追问替换，不打断主流程

---

## 常见陷阱

- 部门名 ≠ 角色：不能用部门名称代替角色判断
- 聊天记录是快速判断工作内容的捷径，优先于文档
- 单篇文档不够：至少看 3 篇，单篇可能是跨角色协作产出
- 访谈记录 PM 和 UXR 都会写，不能单独判断角色
- TOP3 候选必须来自不同发言人，展示前做去重检查
