Back to skills
SKILL.md
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
Works with
Security analysis
100/100Pro scans all 12 files and shows the line behind each finding
npx -y skills add jiabai/awesome-skills --skill key-summary-agent --agent claude-codeAre you the author of Key Summary Agent?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/jiabai-key-summary-agent)---
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.md
- pyproject.toml
- references/delivery-loop.md
- references/output-language.md
- references/persistence.md
- references/prompts.md
- references/validation-and-errors.md
- scripts/key_summary_agent/__init__.py
- scripts/key_summary_agent/delivery.py
- scripts/key_summary_agent/persistence.py
- tests/test_persistence_crash_recovery.py
- tests/test_submit_summary_one_shot.py
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.