Python SDK 脚本
SKILL_SESSION_ID={session-id} python3 scripts/deploy.py
Terraform
SKILL_SESSION_ID={session-id} terraform apply
脚本和 Terraform 配置应从环境读取 `SKILL_SESSION_ID`(缺失时默认为空字符串)。SDK 模式见 `references/how-to-implement-by-common-sdk.md`。
### 执行诊断
按模式选择方法在使用说明和执行约束中定义。流式输出规则在执行约束中定义(每个实例结果就绪即输出)。
---
#### 控制台诊断(CreateDiagnosticReport)
> **仅适用于单实例诊断。** 批量模式下不要使用此方法。
1. **创建诊断报告**(为单个实例调用一次):
aliyun ecs create-diagnostic-report \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-ecs-gpu-diagnosis/{session-id} \
--biz-region-id '${REGION_ID}' \
--region '${REGION_ID}' \
--resource-id '${INSTANCE_ID}' \
--metric-set-id 'dms-instanceGPUdevice' \
--output cols=ReportId
从输出中提取 `ReportId` 供后续查询。
2. **轮询诊断结果**
aliyun ecs describe-diagnostic-reports \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-ecs-gpu-diagnosis/{session-id} \
--biz-region-id '${REGION_ID}' \
--region '${REGION_ID}' \
--report-ids '${REPORT_ID}'
按 `Status` 处理:**"Finished"** → 解析 `Issues` 字段;**"InProgress"** → 等待 30 秒重试;**"Failed"** → 报告失败。最多轮询 10 次(约 5 分钟);如果仍在运行,提示用户稍后手动查询。
3. **结果解读**
诊断完成时,报告返回 `Issues` 数组(每个 Issue 包含 `IssueId`、`MetricId`、`Severity`、`MetricCategory`)。按 IssueId 映射表输出诊断描述和处理措施:
| IssueId | 诊断描述 | 异常处理措施 |
|---------|------------------------|----------------------------|
| GuestOS.GPU.MemoryEccCheckError | 检测 GPU 双位错误情况 | 根据错误计数提示用户重启实例 |
| GuestOS.GPU.InfoRomCorrupted | 检测 GPU infoROM 固件信息 | 将向用户发送运维通知 |
| GuestOS.GPU.DriverVersionMismatch | 检测内核升级导致的驱动异常 | 用户需要卸载并重新安装驱动 |
| GuestOS.GPU.FabricmanagerCheck | 检测 Fabricmanager 组件运行状态 | 用户需要安装或启动 Fabricmanager 组件服务 |
| GuestOS.GPU.PowerCableError | 检测 GPU 电源线和供电状态 | 将向用户发送运维通知 |
| GuestOS.GPU.DeviceLost | 检测 GPU 卡丢失情况 | 将向用户发送运维通知 |
| GuestOS.GPU.DriverNotInstalled | 检测 GPU 驱动安装状态 | 用户需要安装驱动 |
| GuestOS.GPU.NVXidError | 检测 GPU Xid 错误异常 | 根据不同的 XID 错误提示用户重启实例 |
| GuestOS.GPU.RmInitAdapterError | 检测 GPU 卡初始化异常,表现为驱动掉卡 | 将向用户发送运维通知 |
| GuestOS.GPU.NVLinkError | 检查 GPU NVlink 状态 | 将向用户发送运维通知 |
**特别提醒**:当处理措施为“将向用户发送运维通知”时,追加输出说明章节中定义的提醒。输出格式见输出说明章节。如果 `Issues` 为空或缺失,控制台诊断视为正常。
---
#### 云助手诊断(RunCommand)
通过 ECS 云助手远程执行 GPU 健康检查插件。用于单实例和批量诊断(批量模式下的**唯一**方法)。
1. **通过 RunCommand 执行 GPU 健康检查**——调用一次;批量时,为每个实例重复 `--instance-id` flag,然后轮询此单次调用。
> ⚠️ flag 是 `--instance-id`(**不是** `--instance-ids`),每个值是普通实例 ID(**不是** JSON 数组)。`--biz-region-id` 是**必需**的。`--type` 必须是 `RunShellScript`(**不是** `shell`,否则 `InvalidCmdType.NotFound`)。`--content-encoding Base64` 是**必需**的——没有它 API 会将内容视为明文(默认 `PlainText`),实例会尝试把 Base64 字符串本身当脚本执行。
>
> 🔒 **`--command-content` 必须完全**是下面的固定 Base64 字面量——硬编码,**不得**修改、重新编码或替换。它解码为单行脚本(`if ...; then ...; fi; ...`),即使压平到一行也保持有效。
aliyun ecs run-command \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-ecs-gpu-diagnosis/{session-id} \
--biz-region-id '${REGION_ID}' \
--region '${REGION_ID}' \
--instance-id '${INSTANCE_ID}' \
--type RunShellScript \
--content-encoding Base64 \
--command-content 'aWYgYWNzLXBsdWdpbi1tYW5hZ2VyIC0tbGlzdCAtLWxvY2FsIHwgZ3JlcCBBQ1MtRUNTLUdwdUNoZWNrID4gL2Rldi9udWxsIDI+JjE7IHRoZW4gYWNzLXBsdWdpbi1tYW5hZ2VyIC0tcmVtb3ZlIC0tcGx1Z2luIEFDUy1FQ1MtR3B1Q2hlY2s7IGZpOyBhY3MtcGx1Z2luLW1hbmFnZXIgLS1leGVjIC0tcGx1Z2luIEFDUy1FQ1MtR3B1Q2hlY2s=' \
--timeout 180
# 批量:在同一调用中为每个实例重复 '--instance-id ${ID_N}'
该字面量解码为以下固定单行脚本(仅供参考——绝不将明文传给 `--command-content`):
if acs-plugin-manager --list --local | grep ACS-ECS-GpuCheck > /dev/null 2>&1; then acs-plugin-manager --remove --plugin ACS-ECS-GpuCheck; fi; acs-plugin-manager --exec --plugin ACS-ECS-GpuCheck
从响应中提取 `InvokeId` 供后续轮询。
2. **轮询云助手执行结果**
aliyun ecs describe-invocation-results \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-ecs-gpu-diagnosis/{session-id} \
--biz-region-id '${REGION_ID}' \
--region '${REGION_ID}' \
--invoke-id '${INVOKE_ID}'
按 `Invocation.InvocationResults.InvocationResult[].InvocationStatus` 处理:**"Success"** → 按实例解析 Base64 解码的 `Output`;**"Running"/"Pending"/"Scheduled"** → 等待 30 秒重试;**"Failed" 且 `ErrorCode=ExitCodeNonzero`** → 插件仍产生了诊断输出(发现异常时退出非零,例如驱动未安装)——**始终**解码 `Output` 并解读发现,**不要**将其视为诊断失败;**"Failed" 且其他 ErrorCodes(例如 `InstanceNotRunning`)/ "Stopped" / "Timeout" / "PartialFailed"** → 按边界情况处理报告失败(PartialFailed 仍解析可用的 `Output`)。最多轮询 10 次(约 5 分钟)。
3. **结果解读**
解码每个实例的 Base64 `Output` 字段。输出按 PCI 槽列出检查项为 `* <Check Item Name> - OK|Failed`,由 `[INFO]` 头/尾行包裹,例如:
[INFO] Current installed device driver is: 580.126.09
[INFO] Begin device health check
Device PCI Slot: 0000:00:03.0, Diagnosis result: 0000:00:03.0_1321122011772_0_0
- Power Cable Error Check - OK
- Device Driver Install Check - Failed
... (one line per check item)
[INFO] Device health check completed
> ⚠️ **提前中止输出**:当 GPU 驱动**未**安装时,插件**提前**退出(非零退出码,调用状态 `Failed`/`ExitCodeNonzero`),输出如下——这是**有效**发现,必须报告为 `Device Driver Install Check – Failed`(IssueId `GuestOS.GPU.DriverNotInstalled`),**不是**诊断失败:
>
> ```
> [ERROR] nvidia driver not installed
> [ERROR] Device driver not installed
> ```
按下表将失败的检查项映射到 IssueIds:
| 检查项名称 | 映射的 IssueId | 诊断描述 | 异常处理措施 |
|-----------------|---------------|------------------------|----------------------------|
| Double Bit Error Check | GuestOS.GPU.MemoryEccCheckError | 检测 GPU 双位错误情况 | 根据错误计数提示用户重启实例 |
| Info Rom Corrupted Check | GuestOS.GPU.InfoRomCorrupted | 检测 GPU infoROM 固件信息 | 将向用户发送运维通知 |
| eRDMA Incorrect Check | —(无映射 IssueId) | 检测 GPU eRDMA 网卡状态 | 将向用户发送运维通知 |
| Kernel Upgrade Check | GuestOS.GPU.DriverVersionMismatch | 检测内核升级导致的驱动异常 | 用户需要卸载并重新安装驱动 |
| Fabricmanager running Check | GuestOS.GPU.FabricmanagerCheck | 检测 Fabricmanager 组件运行状态 | 用户需要安装或启动 Fabricmanager 组件服务 |
| Power Cable Error Check | GuestOS.GPU.PowerCableError | 检测 GPU 电源线和供电状态 | 将向用户发送运维通知 |
| Device Lost Check | GuestOS.GPU.DeviceLost | 检测 GPU 卡丢失情况 | 将向用户发送运维通知 |
| Device Physical Lost Check | GuestOS.GPU.DeviceLost | 检测 GPU 物理卡丢失情况 | 将向用户发送运维通知 |
| Device Driver Install Check | GuestOS.GPU.DriverNotInstalled | 检测 GPU 驱动安装状态 | 用户需要安装驱动 |
| Device Xid Error Check | GuestOS.GPU.NVXidError | 检测 GPU Xid 错误异常 | 根据不同的 XID 错误提示用户重启实例 |
| NVLink state Check | GuestOS.GPU.NVLinkError | 检查 GPU NVlink 状态 | 将向用户发送运维通知 |
**特别提醒**:对于处理措施为“将向用户发送运维通知”的检查项,追加输出说明章节中定义的提醒。
如果所有检查项均为 OK,则该实例的云助手诊断视为正常。
---
#### 定时诊断(仅云助手诊断)
> **定时诊断仅支持云助手诊断。** 控制台诊断不支持定时执行,**不得**使用。
>
> 创建云助手命令和周期计划(`CreateCommand` + 带 `--frequency` 的 `InvokeCommand`)。无即时诊断结果——每次定时运行后通过 `describe-invocation-results` 查询结果。全局约束(固定命令内容、不删除资源)完全适用。
1. **收集参数**
- `REGION_ID`(与前置条件相同校验)
- 实例选择——以下之一:用户提供的**显式实例 ID**;或**实例标签过滤**带标签 Key 和可选 Value(例如 `gpu` 或 `gpu=1`;无 Value = 匹配该 Key 的所有值)
- 计划时间:用户给出时间表达式或自然语言(例如“每天 10:00”、“每 2 小时”)。将其转换为**6 字段 Cron 表达式**(`seconds minutes hours day month weekday`),例如每天 10:00 → `0 0 10 * * ?`,每 6 小时 → `0 0 */6 * * ?`
- 命令名称:`gpu_diagnosis_<date>`(`<date>` = 今天,`YYYYMMDD`);如果名称存在,追加区分后缀(例如 `gpu_diagnosis_20260807_tag`)
2. **解析目标实例**
- 显式实例 ID:通过 `describe-instances` 验证存在性和操作系统类型(同前置条件步骤 4);仅 Linux 实例继续
- 标签过滤:先查询匹配实例:
aliyun ecs describe-instances \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-ecs-gpu-diagnosis/{session-id} \
--biz-region-id '${REGION_ID}' \
--region '${REGION_ID}' \
--tag Key='${TAG_KEY}' Value='${TAG_VALUE}' # 省略 Value= 以匹配该 Key 的所有值
提取 `InstanceId` 列表,仅筛选 Linux 实例。
- > ⚠️ `invoke-command` **不**支持纯标签定时(仅传 `--tag` 时返回 `MissingParam.InstanceId`)。你必须在创建计划**之前**将标签解析为显式实例 ID。注意后续新打标签的实例**不会**自动包含;如果实例集变化,需重新创建计划。
3. **创建云助手命令**
命令内容必须**完全**是云助手诊断步骤 1 使用的相同固定 Base64 字面量(它解码为固定单行脚本)。**直接**使用该字面量——不要在运行时重新编码或重新输入脚本:
aliyun ecs create-command \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-ecs-gpu-diagnosis/{session-id} \
--biz-region-id '${REGION_ID}' \
--region '${REGION_ID}' \
--name 'gpu_diagnosis_${DATE}' \
--type RunShellScript \
--command-content 'aWYgYWNzLXBsdWdpbi1tYW5hZ2VyIC0tbGlzdCAtLWxvY2FsIHwgZ3JlcCBBQ1MtRUNTLUdwdUNoZWNrID4gL2Rldi9udWxsIDI+JjE7IHRoZW4gYWNzLXBsdWdpbi1tYW5hZ2VyIC0tcmVtb3ZlIC0tcGx1Z2luIEFDUy1FQ1MtR3B1Q2hlY2s7IGZpOyBhY3MtcGx1Z2luLW1hbmFnZXIgLS1leGVjIC0tcGx1Z2luIEFDUy1FQ1MtR3B1Q2hlY2s='
> ⚠️ `create-command` **没有** `--content-encoding` flag——API **始终**期望 Base64。提交前用 `echo '<literal>' | base64 -d` 验证它**精确**解码为云助手诊断步骤 1 的固定单行脚本。将字面量直接传给 `--command-content`;不要在运行时再次编码。
从响应中提取 `CommandId`。
4. **创建 Cron 计划**
aliyun ecs invoke-command \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-ecs-gpu-diagnosis/{session-id} \
--biz-region-id '${REGION_ID}' \
--region '${REGION_ID}' \
--command-id '${COMMAND_ID}' \
--instance-id '${INSTANCE_ID_1}' \
--instance-id '${INSTANCE_ID_2}' \
--frequency '${CRON_EXPRESSION}' \
--timeout 180
> ⚠️ 注意事项:
> - 多个实例:为每个实例重复 `--instance-id` flag。不要在一个 flag 中空格分隔多个 ID(导致 `InvalidInstance.NotFound`)。
> - `--frequency` 接受 6 字段 Cron 表达式(基于时钟的调度)。`--timed` 参数已弃用——**不要**使用。
从响应中提取 `InvokeId`。
5. **验证定时任务**
aliyun ecs describe-invocations \
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-ecs-gpu-diagnosis/{session-id} \
--biz-region-id '${REGION_ID}' \
--region '${REGION_ID}' \
--invoke-id '${INVOKE_ID}'
确认:`RepeatMode = Period`、`Frequency` 匹配 Cron 表达式,且每个实例的 `InvocationStatus = Scheduled`。
6. **向用户报告**
- 输出:命令名称、`CommandId`、`InvokeId`、Cron 表达式及人类可读的计划描述、覆盖的实例列表
- 提供未来运行的结果查询命令:`aliyun ecs describe-invocation-results --user-agent AlibabaCloud-Agent-Skills/alibabacloud-ecs-gpu-diagnosis/{session-id} --biz-region-id '${REGION_ID}' --region '${REGION_ID}' --invoke-id '${INVOKE_ID}'`(`Output` 是 Base64 编码;按云助手诊断步骤 3 解码并解读)
- 提醒:实例在触发时按其状态运行;停止的实例会使该次运行失败而不影响未来计划
- 不要执行任何删除命令(见执行约束);如果用户稍后要求删除任务,通过 `stop-invocation` 停止它并引导他们在控制台手动删除(见边界情况处理)
### 输出说明
**按实例维度**输出结果,**异常实例列在前**,正常实例不单独列出。
**输出规则:**
- **直接陈述诊断结论**——不要输出任何“诊断完成!”式的横幅或前言
- 输出中使用方法名**控制台诊断**和**云助手诊断**;不要使用“通道 A”/“通道 B”/“双通道”术语,也不要显示 Report ID / Invoke ID / PCI 槽详情
- 两种方法是同级的,输出**按方法维度组织**(按方法分组):一个**控制台诊断**章节列出其异常项,接着一个**云助手诊断**章节列出其异常项。控制台诊断发现以其 IssueId 为标题(例如 `GuestOS.GPU.DriverNotInstalled`);云助手诊断发现以其检查项名称为标题(例如 `Device Driver Install Check - Failed`)。不要用控制台 IssueId 给云助手发现命名,反之亦然;如果无异常,结论陈述该实例/实例正常
- **每个异常项恰好属于一个方法章节**——绝不将两方法的发现合并为一个项,绝不写“检测方法:控制台诊断 + 云助手诊断”。任一方法的发现都**不得**丢弃——见“不得丢弃任何发现,绝不跨方法合并”约束
- **按方法分组**:每个方法章节有标题如 `控制台诊断(N 个异常)` / `云助手诊断(N 个异常)`,并各自编号([1]、[2]、…);即使两种方法报告同一底层问题,每个章节也分别列出自己的发现——绝不合并/去重。如果某方法未发现异常,其章节陈述“未检测到异常”;如果某方法不可用/被跳过(例如实例未运行),其章节陈述原因
- 仅列出有异常的实例
- 单实例模式:如上按方法分组章节
- 批量模式:仅输出云助手诊断结果
- 末尾显示摘要行,指示多少实例正常
- 如果所有实例正常,只显示结论/摘要
- **输出语言**:下面的格式示例为英文;在用户对话语言中渲染**相同的结构和标签**
- **驱动未安装**:当异常为 `GuestOS.GPU.DriverNotInstalled`(控制台诊断)或 `Device Driver Install Check – Failed`(云助手诊断)时,诊断建议必须包含**恰好**此安装指南链接(不要捏造或替换任何其他链接):https://help.aliyun.com/zh/egs/install-a-gpu-driver-on-a-gpu-accelerated-compute-optimized-linux-instance 。建议必须**止于**提供此官方文档链接——不要询问用户是否要你安装驱动,不要提出代为安装,也不要在实例上执行或尝试任何驱动安装
**单实例输出格式:**
诊断结论:实例 i-bp1xxxxxxxxx(cn-shanghai)——发现 2 个异常(控制台诊断 1 个,云助手诊断 1 个)
控制台诊断(1 个异常):
[1] GuestOS.GPU.DriverNotInstalled
Severity: Warn
Description: Detect GPU driver installation status
Action: User needs to install driver
云助手诊断(1 个异常):
[1] Device Driver Install Check - Failed
Description: Detect GPU driver installation status
Action: User needs to install driver
建议:
- 安装匹配版本的 NVIDIA GPU 驱动
- 安装指南:https://help.aliyun.com/zh/egs/install-a-gpu-driver-on-a-gpu-accelerated-compute-optimized-linux-instance
**批量输出格式(仅云助手诊断):**
诊断结论:cn-shanghai —— 共 5 个实例:2 个异常,3 个正常
========== 异常实例(2) ==========
--- 实例:i-bp1aaaaaaaaaa ---
[1] GuestOS.GPU.DriverNotInstalled — 检测 GPU 驱动安装状态。操作:安装驱动
[2] GuestOS.GPU.NVXidError — 检测 GPU Xid 错误异常。操作:根据 XID 错误重启实例
建议:安装 NVIDIA 驱动;重启实例以清除 Xid 错误
... (每个异常实例重复)
========== 正常实例(3) ==========
i-bp3ccccccccccc, i-bp4ddddddddddd, i-bp5eeeeeeeeeee — 未检测到异常
**特别提醒**:当异常处理措施为“将向用户发送运维通知”时,追加以下提醒:
⚠️ 重要提醒:
- 阿里云将向您发送运维事件通知
- 请前往 ECS 控制台查看事件详情
- 注意是否收到运维事件并按要求处理
### 边界情况处理
- **实例不存在**:CLI 将返回错误,捕获并告知用户实例 ID 可能有误
- **地域错误**:提示用户确认实例所在地域
- **非 GPU 规格**:如果实例不是 GPU 规格,诊断可能无结果,提示用户确认实例类型
- **权限不足**:如果返回权限错误,提示用户检查 AccessKey 权限
- **网络超时**:设置命令执行超时(推荐 30 秒),超时后重试或提示用户检查网络
- **云助手不可用**:如果 RunCommand 返回错误指示云助手未安装或实例未运行,告知用户:“实例 ${INSTANCE_ID} 上云助手诊断不可用。请确认实例处于 Running 状态且已安装云助手 Agent。该实例的云助手诊断已跳过。”
- **批量部分失败**:如果某些实例在云助手诊断中失败(例如云助手不可用),继续处理剩余实例并单独报告失败
- **定时:纯标签调度被拒**:如果仅传 `--tag` 时 `invoke-command` 返回 `MissingParam.InstanceId`,先通过 `describe-instances` 将标签解析为实例 ID,再用显式 `--instance-id` flags 创建计划
- **定时:命令名冲突**:如果 `create-command` 因名称重复失败,给 `gpu_diagnosis_<date>` 追加区分后缀并重试
- **定时:用户请求删除**:如果用户要求删除定时任务或命令,按“严格禁止删除资源”约束不要自行删除任何资源。改为:1) 执行 `stop-invocation`(带任务的 `InvokeId`)停止未来定时运行——停止是允许的,是 Agent 停止任务的方式;2) 告诉用户删除必须在控制台手动完成:ECS 控制台 → 云助手 → 命令执行结果 → 定时执行,定位定时任务并在那里删除
### 示例工作流
**单实例:**
用户:帮我诊断这台 GPU 服务器 i-bp1xxxxxxxxx
Agent:
- 检查 CLI 已安装
- 询问地域(用户未提供)
- 用户回复:cn-shanghai
- 检查实例操作系统类型为 Linux
- [控制台诊断] 执行 CreateDiagnosticReport,获取 ReportId: dr-xxxxxxxx
[云助手诊断] 执行 RunCommand,获取 InvokeId: t-xxxxxxxx(同时启动)
- 轮询 DescribeDiagnosticReports 和 DescribeInvocationResults
- 云助手诊断先完成——解析 Base64 输出(即使状态为 Failed/ExitCodeNonzero,也解码 Output)
- 控制台诊断完成——解析 Issues
- 按输出说明,按方法维度输出——一个控制台诊断章节列出其异常项,然后一个云助手诊断章节列出其异常项(绝不将两方法的异常合并为一个项),输出给用户
**定时诊断(标签过滤):**
用户:为标签 gpu=1 的实例创建定时 GPU 诊断任务,每天 10:00 运行
Agent:
- 检查 CLI,校验地域;通过 describe-instances 解析标签 gpu=1 → 匹配的 Linux 实例
- 将“每天 10:00”转换为 Cron:0 0 10 * * ?
- 用固定脚本(Base64 字面量,同云助手诊断步骤 1)执行 CreateCommand,名称 gpu_diagnosis_<today>
- 用重复 --instance-id flags + --frequency '0 0 10 * * ?' 执行 InvokeCommand
- 通过 describe-invocations 验证(RepeatMode=Period,Scheduled);报告 IDs + 结果查询命令
- 绝不自行删除命令或任务;如果稍后被要求删除,运行 stop-invocation 并引导用户在 ECS 控制台删除(云助手 → 命令执行结果 → 定时执行)
**批量诊断:**
用户:批量诊断这些 GPU 实例:i-bp1aaa, i-bp2bbb, i-bp3ccc,地域 cn-shanghai
Agent:
- 检查 CLI;校验所有实例 ID 和地域
- 一次调用查询所有实例的操作系统类型,仅筛选 Linux
- [仅云助手诊断] 一次 RunCommand 调用带所有实例 ID → 1 个 InvokeId
- 轮询 DescribeInvocationResults;每个实例结果就绪即输出
- 最终摘要:列出正常实例 ID
---
阿里云skills
◯ 评论 0