关于 kestra-flow-hardening
用于审查现有 Kestra 流程的技能,会按严重程度报告可靠性、幂等性和防护缺口,并在用户确认后修改流程。它依据目标版本的流程架构校验建议,避免不适用的配置。
主要功能
- 01审查流程可靠性缺口
- 02按严重程度排序发现
- 03依据架构核验配置
- 04评估重试的幂等风险
- 05确认后进行针对性修改
- 06支持批量流程审查
适用场景
- 01为生产环境加固流程
- 02排查重试与超时配置
- 03审查目录中的流程
- 04为关键流程添加告警与 SLA
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ kestra-io/ agent-skills --skill kestra-flow-hardening安装后在 Claude Code 中输入/kestra-flow-hardening确认已加载。
附带文件references/hardening-patterns.md
详细介绍
Kestra Flow 加固技能
审核现有 Kestra 流,发现韧性/幂等性/防护措施方面的缺口,并按严重程度排序生成报告,然后应用用户确认的修改。
这是与相关技能配套的审核技能:
| 技能 | 负责内容 |
|---|---|
kestra-flow | 编写 — 根据意图创建/修改/调试流 YAML |
kestra-flow-hardening | 审核 — 查找缺口、建议并应用防护措施 |
kestra-ops | 运维 — 通过 kestractl 验证/部署/运行 |
对于“构建新流”,转交给 kestra-flow;对于“验证/部署这个流”,转交给 kestra-ops。
适用场景
用户要求加固、审核、审查,或使流达到生产就绪/具备韧性/具备幂等性时触发:
- “加固这个流/这些流,使其适用于生产环境。”
- “审核我的流——要保证可靠性,还缺少什么?”
- “为这个流添加重试、超时和错误处理。”
- “审查此命名空间中的流,找出韧性方面的缺口。”
不要使用此技能根据描述编写全新的流——这属于 kestra-flow。
必需输入
- 一个或多个流,按优先级排列:
- 在聊天中直接粘贴的 YAML
- 文件路径、glob 或目录(例如
./flows/、./flows/*.yml) - 运行中的实例 — 通过
kestra-ops/kestractl获取流(用户可配合使用这些技能;此技能不要求实例正在运行) - 命名空间/目录批次
- Kestra 版本和版本类型(OSS/EE)。 如果未知,询问一次;默认为最新 OSS。用于筛选特定版本/版本类型的建议。
工作流
步骤 1 — 获取流架构(权威依据)
curl -s https://api.kestra.io/v1/plugins/schemas/flow
读取原始 JSON。架构是目标版本中属性及其类型的唯一依据。切勿建议架构中不存在的属性——这样才能捕捉版本陷阱,例如 retry.maxAttempt(0.24 之前)与 retry.maxAttempts 之间的差异。
步骤 2 — 确认范围和背景
- 确定输入形式(粘贴内容/文件/glob/目录/命名空间)。
- 确认版本和版本类型(未提供时默认为最新 OSS)。
- 对于目录或命名空间,在生成报告前收集其中的所有目标流。
步骤 3 — 根据流的信号调整评估尺度(保持适度)
加固力度必须与流的实际用途及运行环境相称。读取以下信号并据此调整审核内容——不要对每个流都套用固定清单:
- 存在触发器/调度 → 并发、SLA 和重叠行为变得相关;手动运行的流对此需求要小得多。
- 存在实际副作用(写入、外部调用、云任务、脚本) → 韧性和幂等性方面的发现很重要;纯计算或仅记录日志的流则不需要这些措施。
- 命名空间作为环境提示 —
prod.*/staging.*会提高要求;dev.*/sandbox.*/tutorial.*则可适度处理(“看起来像开发环境——除非你准备将其提升到更高环境,否则暂不加固”)。 - 已有控制措施 → 应予以认可;切勿重复指出已有的问题。
绝不臆造风险。 如果某个流确实可靠,返回*“没有严重或高危问题;此流的加固程度合理”*是正确且值得鼓励的结果。不要为了显得忙碌而捏造低严重性的小问题。
第 4 步 — 运行审计分类
评估每个相关维度。有关每种构造的精确、可复制粘贴的 YAML,以及“何时应用/何时不应用”的指南,请加载
references/hardening-patterns.md。
弹性
- 对容易发生瞬时故障的任务(HTTP、JDBC、云 API)进行重试——参见下文的幂等性等级。
- 为每个可运行任务设置超时(脚本、查询、云作业——用于控制挂起和成本)。
- 在整个执行流程重放有意义时,使用流程级
retry。
故障处理
- 使用全局
errors发送告警;在可流动任务内使用局部errors进行有针对性的清理。 - 使用
finally拆除资源(容器、临时基础设施)——执行期间仍处于 RUNNING 状态时运行。 - 使用
afterExecution和runIf,根据最终状态(SUCCESS/FAILED/WARNING)发送通知。 - 仅在确实非关键的任务上使用
allowFailure/allowWarning。
并发与幂等性
- 对访问共享系统/受速率限制系统的流程,设置
concurrency限制和behavior(QUEUE/CANCEL/FAIL)。 - 幂等性防护——使用
system.correlationId+ 重复检查(EE),或基于 KV 的状态防护(OSS)。 - 设置触发器
allowConcurrent/Schedule 重叠行为。
防护措施与契约
- 使用
checks(≥ 1.2)验证执行前输入。 - 使用
sla——MAX_DURATION/EXECUTION_ASSERTION,并设置违约标签 + 告警。 - 对输入进行类型定义——使用
SELECT/ENUM/SECRET,而非宽松的STRING。
规范性
- 当流程超过约 100 个任务或执行上下文过度膨胀时,提取子流程。
- 对大型输出使用
store: true/stores,而不是将数据保留在执行上下文中。 - 添加描述、标签并遵循命名规范。
- 不要硬编码机密/凭据(沿用
kestra-flow的规则——参见下文的共享规则)。
平台适配性与可维护性(建议——非加固要求,绝不构成阻碍) 这些是建议,不是风险。它们绝不带有严重性,也绝不构成阻碍;而是在单独的 建议 部分中显示(参见报告格式)。使用这些建议引导用户采用更易于维护的流程,而不是将其作为门槛。
- 较长的内联脚本 → Namespace Files。 带有大型内联
script:/commands:块(大约超过 15–20 行,或包含实际程序逻辑)的Script任务更难阅读、测试和版本管理。建议将代码移入 Namespace File,并通过Commands任务调用(namespaceFiles: {enabled: true, include: [...]}),或在Script任务中通过read('path')读取。Kestra 自身的指南:生产工作负载使用Commands,快速迭代使用Script。 - 脚本重复实现插件功能 → 原生插件。 如果脚本重新实现了某个 Kestra 插件已有的功能,建议改用原生任务,以减少需要维护的自定义代码。将常见用法与插件系列进行模式匹配,并且在命名任务前,先确认获取的架构中存在该任务:
curl/wget/requests→io.kestra.plugin.core.http.Request/Downloadpsql/mysql/sqlite3→ 对应的 JDBC 插件(io.kestra.plugin.jdbc.*)aws/gcloud/azCLI → 云插件(io.kestra.plugin.aws|gcp|azure.*)dbt→io.kestra.plugin.dbt.*;gitclone →io.kestra.plugin.git.Clone
- 如果上下文中提供了 Namespace Files,评估脚本逻辑中有多少可以由原生任务替代,并量化说明(“N 个步骤中约有 X 个可对应到原生插件任务”)。
步骤 5 — 按严重性对每项发现分类
| 严重性 | 定义 | 示例 |
|---|---|---|
| Critical | 会在生产环境中导致数据损坏、重复副作用或静默丢失 | 对非幂等写入启用重试 / allowFailure;对非原子状态更新不设并发限制;硬编码机密 |
| High | 会导致服务中断 / 挂起 / 成本暴增或未检测到的故障 | 云任务 / 脚本任务没有超时;没有 errors 告警;关键业务计划没有 SLA |
| Medium | 降低韧性 / 可恢复性 | HTTP / JDBC 缺少瞬时重试;没有 finally 清理导致资源泄漏;输入类型过于宽松 |
| Low | 整洁度 / 可维护性 | 缺少描述 / 标签;命名;未设置大输出的 store |
平台适配建议(长脚本 → Namespace Files;脚本 → 原生插件) 不评定严重性,而是单独报告为 Advisory,且绝不会阻止操作。
步骤 6 — 应用幂等性判断(建议重试之前)
对于易出错的读取操作,重试是好建议;但对于非幂等写入,重试则是灾难性的 (重复扣费、重复插入)。建议重试之前,先对每个候选任务分类:
| 层级 | 检测方式 | 重试建议 |
|---|---|---|
| Safe | 按类型判断为只读(HTTP GET、SELECT、fetch / list、Log) | 可自由建议重试 |
| Conditionally safe | 写入操作具有天然幂等键,或属于事务性 / upsert 任务 | 建议重试,并说明前提条件 |
| Unsafe / unknown | 不透明脚本、指向未知端点的 POST / PUT、非事务性写入 | 不要建议盲目重试。 在报告中标出幂等性问题,并列出两种分支:去重保护(correlationId / KV)与安全时重试。由用户在确认时决定。 |
步骤 7 — 输出报告
格式(发现按全局顺序编号,方便用户按编号选择):
## Hardening audit: <flow id> (<namespace>, v<X.Y>, OSS/EE)
### Critical
1. **<title>** — `tasks.<id>`
Risk: <what breaks in production if unfixed>
Caveat: <e.g. only safe if this endpoint dedupes on a key>
Proposed: <the edit, or both branches for unknown-safety tasks>
### High
2. ...
### Medium
### Low
### Advisory (platform-fit) — not hardening, optional
- **Long inline script** — `tasks.transform`
Move the ~40-line script into a Namespace File and call it from a `Commands` task
(versioned, testable, editable in the Code Editor).
- **Script duplicates a plugin** — `tasks.fetch`
This `curl` shell task can be `io.kestra.plugin.core.http.Request` (verified in schema).
---
Summary: N Critical · N High · N Medium · N Low · N Advisory
Reply with the numbers to apply (e.g. `1,4,7`), `all`, or `none`.
- 按严重性分组;每项发现都说明风险 + 注意事项 + 建议修复方案 + 严重性。
- 差异留到确认时再展示,让报告易于浏览。
- 明确标出结构性编辑(插入幂等性保护、流程级重试行为),因为这些操作会新增任务,而非只修改一行。
- 批量处理:输出一份跨所有流程、按严重性排序的汇总报告,并附上逐流程摘要表;确认后再逐个流程编辑。
- 仅 EE 适用的发现(例如 correlationId 保护):始终标注为 EE,提供 OSS 替代方案(KV 保护),并将 EE 方案描述为增值选项。
步骤 8 — 应用已确认的编辑
执行 apply 1,4,7 / all 时:
- 精准编辑,保留结构。 只修改相关任务 / 区块。保留根级
id/namespace、任务顺序和注释。绝不重组无关部分。 - 文件输入 → 原地编辑文件。粘贴的 YAML → 返回修改后的 YAML。批量处理 → 编辑每个文件。
- 根据获取的架构重新验证每项编辑(属性和类型必须存在)。
- 初始的编号选择即表示知情同意(报告已说明每项风险 / 注意事项)——不要针对每项发现再次询问,但应用时要展示差异。
- 可建议使用
kestractl flow validate(通过kestra-ops)作为可选的最终检查;不要求连接运行中的实例。
通用规则(继承自 kestra-flow)
不要重复陈述——复用 kestra-flow 技能的规则,避免规则不一致:
- 架构合规——仅使用架构定义的任务类型和属性。
- 不硬编码机密 / 凭据——使用
SECRET类型的inputs或{{ secret('...') }}。 - 引号——优先使用双引号;必要时在内部使用单引号。
- 保留结构——仅修改相关部分;保留
id/namespace。
示例提示词
- “增强此工作流,使其适用于生产环境。”(内联粘贴)
- “审查
./flows/ingest.yml,并在安全的情况下添加重试和超时。” - “检查
./flows/中的所有工作流,找出韧性方面的缺陷,并按严重程度从高到低排序。” - “确保此定时工作流具备幂等性——它有时会运行两次。”(幂等性等级判断)
- “为这个业务关键型工作流添加告警和 SLA。”