跳至主内容
博客

flashduty-cli:在终端中处理故障,并让 AI Agent 安全地参与处理

本文说明我们为什么为故障响应平台开发命令行工具,以及为什么将它设计为 AI 编程 Agent 操作 Flashduty 的入口。这是一篇关于 CLI 设计取舍的工程笔记。

Flashduty 工程团队

flashduty-cli:在终端中处理故障,并让 AI Agent 安全地参与处理

flashduty-cli 是 Flashduty 的命令行工具(CLI)。值班工程师无须离开终端,即可认领故障、查看时间线、检索相似的历史故障。该工具还附带一组 Agent 技能。安装技能后,Claude Code、Cursor 等编程 Agent 也能操作 Flashduty,并遵守安全规则:合并或关闭故障前,必须获得用户确认。

本文介绍开发这一工具的原因,以及几项设计取舍。

为什么提供 CLI 而非仅提供 API

我们观察过一线 SRE 处理故障的过程。他们始终在终端中工作:查看日志、执行 kubectl、运行一系列 grep 命令。告警到达时,切换到浏览器、登录控制台、查找协作空间、再定位故障,会打断他们的工作。每切换一次窗口,注意力就中断一次。

用户也可以基于 Open API 自行编写脚本,但 API 只返回原始数据。要在终端中便捷使用,脚本需要处理分页、解析时间、将 JSON 渲染为对齐的表格、截断长字段,并支持 jq。每个团队各自实现一遍,会造成重复劳动。CLI 统一完成了这些工作:

flashduty incident list                  # 默认看最近 24 小时
flashduty incident get <id>              # 单条 ID 自动切成纵向详情视图
flashduty incident timeline <id>         # 看处理时间线
flashduty incident similar <id>          # 拉相似历史故障

默认输出为对齐的表格,长字段会被截断。添加 --json 参数后,CLI 输出完整数据,可直接交给 jq 处理。时间参数支持 24h、168h、2026-04-01 和 2026-04-01 10:00:00 等写法,无须手动计算 Unix 时间戳。

我们为 CLI 设定了一条边界:CLI 不直接调用 API。所有 API 请求都通过 Go SDK go-flashduty 发出,SDK 与 API 严格一一对应。CLI 只负责三项工作:解析命令、格式化输出,以及提供便利功能(例如按名称查找协作空间 ID)。API 变更时,我们修改 SDK,CLI 只需升级依赖。HTTP 调用代码只保留一份。

支持编程 Agent

许多工程师的终端中同时运行着编程 Agent,例如 Claude Code、Cursor、GitHub Copilot、Codex、Gemini CLI 和 Windsurf。这些 Agent 能够读取代码、执行命令和修改文件。线上告警时,工程师会直接向 Agent 提问:「这个故障是什么情况?谁在值班?与上次故障是否相似?」

但 Agent 默认不了解 Flashduty 的使用方法。Agent 可能猜测 API 用法、手工拼接 curl 命令,甚至不知道这个平台的存在。更严重的情况是执行危险操作,例如未经用户确认就合并两条故障,而合并操作不可撤销。

因此,我们把 Flashduty 的使用方法编写为 Agent 可以安装的技能。flashduty-cli 附带 10 个技能,可通过一行命令安装:

npx skills add flashcatcloud/flashduty-cli -y -g

安装器会检测本机已安装的 Agent,并将技能安装到每个 Agent 中,目前支持 41+ 个编程 Agent。安装完成后,Agent 即可知道应使用哪个命令、如何填写参数,以及哪些操作必须先征得用户同意。

技能的内容

技能并不重复命令列表,而是记录资深值班工程师掌握的知识:数据的组织方式,以及需要禁止的操作。

基础技能名为 flashduty-shared,首先介绍 Flashduty 的三层降噪模型:原始告警事件按 alert_key 去重为告警;告警按聚合规则合并为故障。一条故障可以包含 1~5000 条告警。理解这一结构后,Agent 在下钻或汇总时能够查询正确的层级。

其余九个技能按职责划分:故障生命周期、告警调查、变更追踪、值班查询、协作空间与升级规则、状态页、MTTA/MTTR 分析、团队成员审计和通知模板检查。每个技能只向 Agent 提供本范围内的命令,Agent 无须一次读取全部命令。

基础技能还固定了以下安全规则:

  • 创建或关闭故障前,必须获得用户的明确确认。
  • 禁止合并故障或告警,因为合并操作不可撤销。
  • 执行任何修改数据的操作前,先列出受影响的对象。
  • 无法确定时,先查询后操作,优先使用只读命令。

Agent 最大的风险,是在高度确信的状态下执行不可撤销的操作。因此,我们要求 Agent 在不确定时先向用户确认。

token 也是成本

对 Agent 而言,输出越长,费用越高,占用的上下文也越多。

因此,除表格和 JSON 外,CLI 还支持第三种格式:TOON(Token-Oriented Object Notation,一种为节省 token 设计的格式)。TOON 与 JSON 一样输出完整、不截断、可供机器读取的数据。两者的区别在于列表:当每行字段相同时,TOON 只在开头声明一次字段名,而不在每行重复。对于同一页故障列表,TOON 占用的 token 更少。

flashduty incident list --output-format toon

人阅读输出时关注可读性,模型关注每个 token 的信息量。工具的主要使用者发生变化后,优化目标也应随之调整。

help 文本必须与实际行为一致

CLI 基于 Cobra 开发,支持 bash、zsh、fish 和 PowerShell 的自动补全。但生成补全脚本并不等于补全可用。枚举参数的可选值必须能够正确补全,否则用户会中断操作,Agent 会产生错误。

Agent 了解陌生 CLI 的唯一可靠途径是读取 --help。如果某个子命令的 help 遗漏了参数,或者描述与实际行为不符,Agent 会依据错误信息拼接命令,最终执行失败。

因此我们规定:help 中出现的每个子命令、参数和枚举值,都必须与实际行为一致。这类细节很少受到关注,但它决定了 Agent 能否一次写对命令,而非经过三轮试错。

安装

截至 v1.3.4,flashduty-cli 已覆盖 Flashduty 全部 Open API。安装命令如下:

curl -sSL https://static.flashcat.cloud/flashduty-cli/install.sh | sh

代码和文档见 flashduty-cli 仓库。

相关阅读