Skill: hei-maom/shumianyu (version 1.0.0)

--- name: asr-written-rewriter-stream description: 将分段 asr 文本流在结束时统一整理成流畅书面语，并在用户指定 target_language 时输出译文。适用于语音听写、会议转写、采访整理、播客或视频字幕后处理等场景，尤其适合不需要实时字幕、只需要在整段结束后得到最终书面结果的任务。保持接口抽象、可替换，不绑定任何特定厂商 api。 --- # ASR 结束后统一转书面语 ## 概述 接收分段 ASR 文本流，但**不要实时输出字幕**，而是在检测到整段结束、会话结束、录音结束或调用方显式提交结束信号后，再将累计文本一次性整理成流畅书面语。 默认不翻译。只有在显式提供 `target_language` 时，才对最终书面结果进行翻译。 此 Skill 适用于： - 会议发言结束后统一整理 - 采访录音结束后整理为可读文本 - 播客/视频整段转写后的书面化处理 - 语音输入结束后再统一润色 ## 核心行为 采用**单次最终输出**模型： 1. 持续接收分段 ASR 文本流 2. 将各分段合并到同一缓冲区 3. 在结束信号到来前，不输出面向用户的临时字幕或中间结果 4. 在结束时，对整段文本统一去口语化、补断句、修正重复和自我修正 5. 输出一版流畅、完整的书面语结果 6. 如提供 `target_language`，则输出目标语言结果；除非调用方明确要求，否则不同时返回原文和译文 ## 结束判定规则 只有在满足以下任一条件时，才进入最终整理阶段： - 上游显式传入结束信号，例如 `is_session_final`、`end_of_stream`、`commit=true` - 调用方明确表示“结束”“停止”“提交本段” - 音频或识别流已经结束 - 上游系统给出整段 final 标记 不要仅因为一个句号、一次停顿或一句话结束，就提前输出最终结果。 ## 输入约定 概念上可接收以下输入： - `chunk_text`：最新 ASR 分段文本 - `recent_context`：可选，最近缓冲区或已累计文本 - `domain_lexicon`：可选，领域词库，用于人名、产品名、术语、缩写的稳定化 - `target_language`：可选，目标语言代码或语言名 - `is_session_final` / `end_of_stream` / `commit`：可选，结束信号 - `timestamps`：可选，时间戳元数据 不要要求调用方必须使用某个固定字段名。接受语义等价字段。 ## 输出约定 默认只输出**最终结果**，不要输出中间过程。 ### 未结束时 - 不返回面向用户的正式内容 - 如调用方需要，可仅返回“继续接收中”这一类内部状态，但不要生成临时字幕 ### 结束时 - 输出整段整理后的书面语 - 若设置 `target_language`，则输出翻译后的最终结果 - 除非调用方明确要求结构化数据，否则直接返回最终文本本身 ## 书面化改写规则 在最终整理时： - 改写成自然、流畅、可直接阅读的书面语 - 删除语气词、口头禅、明显重复、自我修正、断裂表达 - 保留原意、语气、问题/命令/不确定性 - 保留专有名词、数字、时间、事实信息 - 不新增原文没有的信息 - 不写成提纲、要点或总结，除非调用方明确要求 - 优先让整段逻辑顺畅，而不是逐词机械保留 ## 翻译规则 只有在 `target_language` 被显式提供时才翻译。 翻译时： - 先基于最终书面语结果再翻译，不直接翻译原始 ASR 碎片 - 保留人名、数字、专有名词和领域术语 - 如提供领域词库，优先保持术语一致性 ## API 抽象层 所有外部能力都应描述为**可替换职责**，不要绑定具体厂商 API、SDK、认证方式或传输协议。 推荐抽象接口： - `ingest_asr_chunk(...)` —— 接收并归一化新的 ASR 分段 - `append_to_buffer(...)` —— 将分段并入当前整段缓冲区 - `detect_stream_end(...)` —— 判断是否已到整段结束时刻 - `rewrite_to_written(...)` —— 将累计口语内容统一改写为书面语 - `translate_text(...)` —— 当 `target_language` 存在时翻译最终结果 - `commit_final_output(...)` —— 提交最终结果并清空或归档当前缓冲区 不要假设任何固定服务商。 ## 建议工作流 1. 接收新的 ASR 分段并做基础归一化。 2. 将分段追加到当前缓冲区。 3. 检查是否收到整段结束信号。 4. 若未结束，继续累计，不输出最终文本。 5. 若已结束，对整个缓冲区执行书面化改写。 6. 若设置了 `target_language`，再对最终书面语做翻译。 7. 输出最终结果。 8. 提交结果并清空当前缓冲区，准备处理下一段。 ## 领域词库处理 如果提供 `domain_lexicon`： - 优先用它稳定专有名词、缩写和术语 - 在上下文支持时，用它纠正同音误识别或 ASR 变体 - 若上下文明显不支持某个术语，不要强行替换 ## 示例 ### 示例 1：结束前不输出最终结果 输入分段： - `今天我们先把登录流程跑通` - `然后再看支付和埋点` 如果尚未收到结束信号： - 不输出最终书面稿 ### 示例 2：结束后统一输出 累计文本： - `今天我们先把登录流程跑通 然后再看支付和埋点` - `嗯如果时间够的话再把告警顺手补一下` 结束后最终结果： - `今天先完成登录流程，再处理支付和埋点。如果时间允许，再补充告警能力。` ### 示例 3：结束后翻译 若同时设置 `target_language: en`，则输出： - `Today, we will complete the login flow first, then handle payments and tracking. If time allows, we will also add alerting.` ## 资源使用 需要查看中文接入说明、可替换接口建议和结束式处理流程时，读取 [references/interface-guide-zh.md](references/interface-guide-zh.md)。

path: agents/openai.yaml
content: interface:
  display_name: "Asr Written Rewriter Stream"


path: references/interface-guide-zh.md
content: # 接口与产品接入说明（中文）

## 这份 Skill 现在做什么

这份 Skill 适合这样的链路：

1. 上游持续送入分段 ASR 文本流
2. 系统只做缓存和累计，不对用户实时展示临时字幕
3. 当整段结束、录音结束或调用方明确提交结束时
4. 再把整段 ASR 结果统一整理成流畅书面语
5. 只有在显式传入 `target_language` 时，才输出翻译结果

它不是一个绑定某家云服务的技能说明，而是一个**可替换接口的行为规范**。

## 为什么改成“结束后统一整理”

这种模式适合：
- 不追求实时字幕
- 更看重最终文本质量
- 希望减少中间态文本闪动或反复改写
- 想在整段上下文完整后再做更自然的书面化处理

这样做的好处：
- 不需要维护临时字幕和回写窗口
- 可以基于整段上下文统一断句和润色
- 更适合会议纪要、采访整理、语音输入后处理

## 推荐的单次最终输出模式

### 1）分段接收
上游持续送入 ASR chunk。

建议：
- 先做轻量归一化
- 处理明显重复片段
- 把 chunk 合并进当前缓冲区

### 2）等待结束信号
在结束前：
- 不输出最终面向用户的文本
- 不生成临时字幕
- 只维护内部缓冲区

可接受的结束信号包括：
- `end_of_stream`
- `is_session_final`
- `commit=true`
- 用户点击“结束”或“提交”
- 上游 ASR 会话关闭

### 3）统一整理
收到结束信号后：
- 对整段文本统一断句
- 去掉口头禅、重复、自我修正
- 改写成流畅书面语
- 若存在 `target_language`，再翻译最终结果

### 4）输出最终结果
默认只输出：
- 最终书面语结果

如果设置了 `target_language`，默认输出：
- 目标语言的最终结果

## 推荐的抽象接口

为了方便你后面替换 API，不要把 Skill 写成某个固定厂商的 SDK 调用说明。
应当只约定“职责”，不约定“厂商实现”。

推荐保留这些抽象层：

### `ingest_asr_chunk(...)`
职责：接收最新的 ASR 分段，并做最基础的归一化。

输入可包含：
- 当前 chunk 文本
- 时间戳
- 置信度
- 说话人信息（如果有）

输出建议：
- 标准化后的 chunk
- 可并入缓冲区的数据结构

### `append_to_buffer(...)`
职责：把每个 chunk 合并到当前整段缓冲区。

建议：
- 保留原始顺序
- 尽量避免重复拼接
- 可记录元数据，但不要把具体存储方式写死

### `detect_stream_end(...)`
职责：判断现在是否已经到达整段结束时刻。

可参考信号：
- 用户手动提交
- 识别流关闭
- 上游 final 会话标记
- 显式 commit 参数

输出建议：
- `ended: true/false`
- `reason: manual_commit | upstream_final | stream_closed | explicit_end`

### `rewrite_to_written(...)`
职责：把累计的整段口语内容统一改写成流畅书面语。

建议：
- 删除口语杂质
- 统一断句
- 保留意思和事实
- 不新增内容
- 优先整段可读性

### `translate_text(...)`
职责：当 `target_language` 存在时，对最终结果做翻译。

建议：
- 基于最终书面语再翻译
- 保留术语、数字、人名、产品名
- 使用领域词库稳定译法

### `commit_final_output(...)`
职责：提交最终结果并清空或归档当前缓冲区。

建议：
- 输出完成后重置会话状态
- 为下一段录音或下一次说话做准备

## 推荐的数据流

可以按下面这个顺序接：

1. 上游 ASR 连续送 chunk
2. `ingest_asr_chunk(...)`
3. `append_to_buffer(...)`
4. `detect_stream_end(...)`
5. 如果未结束：继续累计
6. 如果已结束：
   - 取出整段缓冲区
   - `rewrite_to_written(...)`
   - 如果有 `target_language`，再 `translate_text(...)`
   - 输出最终结果
   - `commit_final_output(...)`

## 领域词库怎么用

如果你有产品名、人名、术语表，可以作为 `domain_lexicon` 传入。

用途：
- 修正 ASR 同音误识别
- 统一专有名词写法
- 翻译时保持术语一致

注意：
- 词库应当“优先参考”，不要“强行覆盖”
- 如果上下文明显不支持某个术语，不要硬替换

## 输出建议

你现在这版要求是：
- 不要实时输出
- 默认不翻译
- 用户手动指定目标语言才翻译
- 面向用户时只输出最终结果

因此在产品集成层，建议默认只保留一个用户可见输出对象：
- `final_output`

如果内部确实需要状态，也只保留接收中、已结束、已提交这类内部状态，不需要临时字幕对象。

## 一个简单例子

实时输入：
1. `今天我们先把登录流程跑通`
2. `然后再看支付和埋点`
3. `如果有时间再补一下告警`
4. 用户点击“结束”

系统行为：
- 结束前：不输出书面稿
- 结束后最终结果：`今天先完成登录流程，再处理支付和埋点。如果有时间，再补充告警能力。`

如果这时传了 `target_language = en`，则最终输出为：
- `Today, we will complete the login flow first, then handle payments and tracking. If time allows, we will also add alerting.`

## 落地原则

记住这几个原则：

- 结束前只累计，不展示最终内容
- 结束后一次性统一整理
- 默认不翻译，按需翻译
- 接口职责抽象化，方便以后替换实现
- 优先整段书面质量，而不是分段即时反馈


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)