Skip to content
Back to skills

Key Summary Agent

ASecurity

把要点总结做成可靠交付的 LLM agent——用双工具契约强制产出 Mermaid 脑图与 Markdown 要点总结,而不是指望 LLM 自觉按格式回复。触发场景:(1) 实现总结类功能(视频或播客文字稿、访谈与演讲记录、会议纪要、长文),要求产物必须落盘且格式能被程序解析;(2) LLM 经常以纯文本回复糊弄、不按结构输出,或产物夹带代码围栏与解释文字;(3) 总结功能需要补确定性校验、稳定错误码、运行时失败不污染已有文件、原子落盘与多语言标题本地化。产出固定为「Mermaid 脑图 + Markdown 要点总结」双产物。

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
toolspythonapi

Works with

  • api

Security analysis

A100/100

Pro scans all 12 files and shows the line behind each finding

Scanned November 7, 2026

npx -y skills add jiabai/awesome-skills --skill key-summary-agent --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Key Summary Agent?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Key Summary Agent
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jiabai-key-summary-agent/badge)](https://www.skillsdirectory.com/skills/jiabai-key-summary-agent)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: key-summary-agent
description: 把要点总结做成可靠交付的 LLM agent——用双工具契约强制产出 Mermaid 脑图与 Markdown 要点总结,而不是指望 LLM 自觉按格式回复。触发场景:(1) 实现总结类功能(视频或播客文字稿、访谈与演讲记录、会议纪要、长文),要求产物必须落盘且格式能被程序解析;(2) LLM 经常以纯文本回复糊弄、不按结构输出,或产物夹带代码围栏与解释文字;(3) 总结功能需要补确定性校验、稳定错误码、运行时失败不污染已有文件、原子落盘与多语言标题本地化。产出固定为「Mermaid 脑图 + Markdown 要点总结」双产物。
agent_created: true
---

# Key Summary Agent

把一段长文本交给 LLM,稳定拿到**两份可落盘产物**:一张 Mermaid 思维导图、一篇 Markdown 要点总结。

适用输入:视频或播客文字稿、访谈与演讲记录、会议纪要、讲座或课程录音转写、长篇文章或报告。

本技能解决的是**交付可靠性**,不是提示词措辞。直接给 LLM 一段 prompt 然后解析自由文本,会得到代码围栏、寒暄、解释文字,有时干脆是空回复。这里用**双工具交付契约**把「交产物」变成结构性动作:LLM 只能通过工具交产物,不交就跑不完。

## 何时使用

- 实现总结类功能,要求产物必须能写进文件且格式能被程序解析
- 已有总结功能但输出格式不稳、经常空跑需要重跑
- 需要「运行时失败不破坏上一轮已成功的结果」
- 提炼长文本时要同时给出可视化结构(脑图)与文字浓缩(要点)

## 何时不用

- 只做一次性的手动提炼,不关心格式稳定性 → 两步提示词就够
- 要产出结构化 JSON schema 而非 Markdown + Mermaid → 本技能是纯文本双产物范式
- 需要联网核查或补充外部背景知识 → 本技能严格 source-grounded,禁止引入原文之外的事实

## 核心架构:双工具顺序交付

产物不是「问出来」的,是被工具接住的。两次交付之间存在真实依赖——总结要参考脑图的逻辑结构,所以两个工具**不同时开放**。

```
原文
  │
  ▼
第一轮 LLM
  │  调用 submit_mindmap
  ▼
校验 ──► 通过
  │
  ▼
工具结束钩子
  ├─ 移除 submit_mindmap
  ├─ 挂载 submit_summary
  └─ 注入「总结任务」(原文 + 已通过的脑图)
  │
  ▼
第二轮 LLM
  │  调用 submit_summary
  ▼
校验 ──► 通过 ──► 返回空值 → 运行结束
```

以下三条是这套编排的核心,缺一不可:

1. **工具轮换与 one-shot**:`submit_mindmap` 成功后立即从工具集移除,换上 `submit_summary`。LLM 无法跳过第一步直接写总结,也无法重复提交脑图;`submit_summary` 由 handler 保证 one-shot,重复提交只返回固定文案,不覆盖第一份总结。
2. **拦截提前收尾**:一个「完成前」钩子检查两份产物是否齐全,缺任一就返回「未完成」,并注入一条点名缺失工具的提醒;若第二步工具或任务提示词没挂上,先补挂并补注入,再点名。**纯文本回复绝不算交付。**
3. **最终工具返回空值**:这在多数工具循环 runner 里是「直接完成」信号,可省掉最后一次多余的 LLM 调用。若返回确认字符串,模型会再走一轮——而那一轮可能不调工具,直接把结果改坏。**不同 runner 对这个信号的约定不同**(空值、特殊标记、独立 API),动手前先查清你用的 runner 是哪种。

## 工作流

### 步骤 1:入口校验(在碰网络之前)

按此顺序校验,失败都应**先于**任何 LLM 或网络调用:

1. 原文 strip 后非空 → 否则 `EMPTY_TRANSCRIPT`
2. 轮次预算 `max_turns` 必须是整数且落在 2–6(默认 6);类型不对或越界 → `INVALID_MAX_TURNS`。一轮 = 一次 LLM 调用;脑图与总结各至少需要一次,所以 1 轮不可能产出两份产物。判类型要用**精确类型判定**而非 `isinstance`:Python 里 `bool` 是 `int` 的子类,`isinstance(True, int)` 为真,布尔值会先被当成整数 1,再被范围校验拒绝;错误码虽然仍是 `INVALID_MAX_TURNS`,但归因会从「类型错」变成「越界」。其它语言同理,注意挡住布尔值与 `"6"` 这类字符串。
3. 输出语言必须在受支持闭集内;非法值 → `UNSUPPORTED_LANGUAGE`,**不要静默降级到默认语言**——用户会拿到语言不对的一稿,而且很难归因。
4. 最后才构建 LLM provider,配置缺失抛 `CONFIG_MISSING`

顺序本身是设计:前三条是本地纯函数,能让绝大部分调用错误在零成本、零副作用时被拦住,不必付一次 LLM 调用才发现参数写错。

### 步骤 2:构建 LLM provider

两种凭据模式,按部署形态二选一:

- **自托管常量凭据**:从配置源读一组值(API key、model、base URL、provider 类型),构建一次后复用。校验至少要确认 key 与 model 非空、provider 类型在你支持的集合内。
- **按次 checkout**:每次 LLM 调用前向自己的后端换一次短期凭据(per-call key rotation)。要求「checkout 地址、会话令牌、请求幂等 ID」三项都非空。幂等 ID 建议带上「第几次调用」的后缀,便于服务端去重与审计。

两种模式有一条共同要求:**底层客户端重试次数设为 0。**

重试不是 provider 的职责,恢复由外层的轮次循环统一负责。让 provider 自己重试会把错误吞掉:外层跑到轮次耗尽才失败,且拿不到根因,只剩「跑完了但没有产物」这种最难排查的现象。

### 步骤 3:跑交付循环

初始只挂载 `submit_mindmap`,系统提示词锁定角色与调用顺序。每轮推进 runner 一步,直到其报告完成或轮次耗尽。收尾处理按固定优先级:

- 末次响应被标记为错误 → 按白名单映射:白名单内的 code 原样沿用,其余(含无法解析 code 的自由文本)归为 `LLM_REQUEST_FAILED`
- 否则先查脑图:缺或为空 → `INVALID_MINDMAP`
- 再查总结:缺或为空 → `EMPTY_SUMMARY`
- 两份都缺时固定报 `INVALID_MINDMAP`,不要依赖下游的检查顺序

runner 的空输出重试设为 0、provider 重试设为 0;恢复只由完成前钩子的「拒绝 + 提醒」和下一轮 LLM 调用承担。不要给重试另开预算——那会变成看不见的第 7 轮。详见 `references/delivery-loop.md`。流式输出建议关掉——产物走工具交付,流式没有意义反而让解析复杂化。

### 步骤 4:归一化函数(在工具 handler 与落盘前复用)

LLM 输出**永远**当作脏数据处理。两个归一化函数必须是纯函数且幂等,因为工具可能在重试路径里被调用多次。它们不是循环结束后的独立步骤:**工具 handler 接收时调用一次并写入交付容器,落盘前再防御性调用一次。**

- **总结**:提取围栏内内容(允许前面有解释文字)→ 找到首个一级标题 `# ` 则从其开始截断;找不到则保留全文并补本地化标题 → 补尾部换行 → 统一换行为 `\n`。成对的内部围栏原样保留;孤立的尾部闭栏在提取阶段丢弃。
- **脑图**:提取围栏内内容 → 从第一处整行等于 `mindmap` 的位置截断,**丢弃其前所有内容** → 找不到 `mindmap` 行则判定为空。成对的内部围栏原样保留;孤立的尾部闭栏在提取阶段丢弃。

**幂等不是口号:** 同一份输出连续归一化两次,结果必须完全相同。围栏裁剪只允许发生在 `unwrap_code_block` 里,且只能丢弃「位于末尾、且前面围栏已经配对的闭栏」;不要在各归一化函数末尾再无条件裁掉 ```,那会把成对内部围栏截成悬空开栏,第二次归一化就会判空。有开栏无闭栏一律判空(输出很可能被截断);唯一例外是「位于末尾、前面围栏已经配对的闭栏」,它按孤立闭栏丢弃。详见 `references/validation-and-errors.md`。

### 步骤 5:原子落盘

**先校验再写**。两份产物只要有任一非法,就不得触碰已有文件——用户上一次成功的结果必须原样保留。立即落盘时按「双文件提交协议」执行:提交阶段任一 `replace` 失败都要尽力回滚,并**一律**抛 `ATOMIC_WRITE_FAILED`;回滚成功也一样,回滚失败只决定是否保留备份。**两次 rename 不是跨崩溃事务。** 要覆盖进程在两次 `replace` 之间崩溃,必须启用提交日志与启动恢复;没有日志时,崩溃可能留下半写,只能靠备份人工恢复。详见 `references/persistence.md`。

## 六条不可妥协的约束

1. **纯回复不算交付。** 没有「完成前拦截」,模型在长文本场景下的高频失效就是「我已经为你总结了要点……」然后整轮结束。这是最高频失效模式。
2. **校验首先在工具里,落盘前再防御性校验一次。** 工具 handler 返回**固定文案**(每个工具的每类非法输入各一句,同类内不区分具体内容),不向模型抛异常、不回显入参内容。禁止把 LLM 输出或 provider 错误原文拼进给模型的反馈里。
3. **错误码稳定且不含秘密。** 只有白名单内的 **provider** 错误码可透传,其余一律归为 `LLM_REQUEST_FAILED`,避免 provider 原文里的凭据泄进日志或 UI。
4. **脑图不生产事实,只组织逻辑。** 它是第二步的输入之一,但不能成为新事实来源——否则脑图生成时自行发挥出的内容会被总结当作可信来源二次传播,形成事实漂移。
5. **语言是冻结闭集。** 标题、Mermaid 示例节点与 `prompt_instruction` 由语义表注入,不做运行期推断。见 `references/output-language.md`。
6. **延迟落盘模式下不写任何产物文件。** 该模式只回产物内容、路径与字节,由调用方统一提交事务。双文件半写比全不写更糟。

## 参考资源

| 文件 | 何时读 |
| --- | --- |
| `references/prompts.md` | 需要复用或改造两步提示词与系统提示词 |
| `references/delivery-loop.md` | 实现双工具、钩子编排、one-shot 与轮次预算;排查「跑完没产物」 |
| `references/validation-and-errors.md` | 实现归一化函数、对外错误码契约与测试断言 |
| `references/persistence.md` | 实现双文件落盘、原子写、提交日志与崩溃恢复、失败语义 |
| `references/output-language.md` | 需要多语言标题、Mermaid 示例节点与 `prompt_instruction` 的取值 |
| `scripts/` + `tests/` | 部分参考实现:one-shot 交付 handler 与双文件原子提交协议;对应测试可在技能目录运行 `python -m pytest` |

## 质检清单

实现或改造后逐条验证:

1. 工具收到非字符串入参(如 `None`、数字、数组、对象、布尔)或缺参时返回固定文案,且不污染交付状态;`submit_summary` 重复提交时保留第一份总结并返回固定文案
2. 非 mindmap 的图源码(如 `graph TD\n A-->B`)归一化后为空;「先解释、再围栏」的脑图能提取出干净源码;成对内部围栏不被裁成悬空开栏;末尾孤立闭栏被丢弃;有开栏无闭栏判空
3. 「完成前」钩子在两份产物齐全前恒返回未完成;钩子重复触发时不重复注入总结任务;工具结束钩子未触发时,补挂 `submit_summary` 会同时补注入第二步任务
4. 越界轮次预算(含 1)、非法输出语言在构建 provider 之前被拒,且分别以 `INVALID_MAX_TURNS` / `UNSUPPORTED_LANGUAGE` 失败
5. 校验失败时已有产物文件内容保持不变;第二个文件替换失败时第一个文件回滚;只要提交失败就以 `ATOMIC_WRITE_FAILED` 结束(回滚成功也一样),回滚失败时保留备份;启用提交日志时,模拟两次 `replace` 之间崩溃后能前滚或回滚到一致状态
6. 延迟落盘模式下磁盘上无新产物文件,但返回的字节非空
7. 非白名单的错误码不被回显到异常信息里;白名单内的 provider 错误码在最终响应处理中保持原样,其余归为 `LLM_REQUEST_FAILED`
8. 同一份总结在 CRLF / LF 下写出的字节换行一致,不出现 `\r\r\n`;「先解释、再围栏」的总结能提取出干净正文;同一输入连续归一化两次结果相同;成对内部围栏不被裁成悬空开栏;末尾孤立闭栏被丢弃(前面的围栏保持成对);有开栏无闭栏判空

Files in this skill

  • SKILL.md12.4 KB
  • pyproject.toml485 B
  • references/delivery-loop.md11.1 KB
  • references/output-language.md4 KB
  • references/persistence.md12.4 KB
  • references/prompts.md4.7 KB
  • references/validation-and-errors.md13.3 KB
  • scripts/key_summary_agent/__init__.py321 B
  • scripts/key_summary_agent/delivery.py2.1 KB
  • scripts/key_summary_agent/persistence.py13.6 KB
  • tests/test_persistence_crash_recovery.py8 KB
  • tests/test_submit_summary_one_shot.py2.6 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.