PAI-EAS 服务部署

⚠️ 顶部规则(先读)

1. 🔴 不允许重复服务名 🔴

如果目标名称的服务已存在:停止并告知用户。不要删除后重建。也不要复用。

2. 强制 API 调用 —— 按顺序执行以下所有:

#APICLI用途
1ListImagesaliyun aiworkspace list-images验证镜像
2describe-machine-specaliyun eas describe-machine-spec验证 GPU 类型
3create-servicealiyun eas create-service创建服务
4describe-servicealiyun eas describe-service检查状态(一次)
5describe-service-endpointsaliyun eas describe-service-endpoints获取 endpoint

始终执行 #1 和 #2,即使用户已提供信息。

describe-machine-speclist-resourcesdescribe-serviceListServices

3. 禁止 —— ❌ 复用现有服务

❌ 编写 bash 脚本(直接运行 CLI)

❌ CPU + vLLM/SGLang ❌ 在 create-service 中使用 file://

❌ 跳过强制 API ❌ 更改用户指定的服务名

❌ 循环轮询 describe-service(只调用一次)

❌ 写完/验证 service.json 后停止——写 JSON 不是完成任务。你必须运行 create-service(Step 6)然后 describe-service(Step 7)。如果找到了资源,就部署它们。

4. 自主执行 —— 不要向用户询问可通过 API 发现的信息。不要问“我可以继续吗?”直接执行。

超时?用 --read-timeout 60 重试。错误?告知用户并继续

缺少参数?选择合理默认值。

如果任何预检查或资源发现步骤失败,记录失败并继续下一步。仅在自验证检查点中列出的特定条件下停止(重复服务名、缺少 NLB/GW/专用资源组)。

5. 自验证检查点:

Step 2 之前:Step 1.5 是否确认无重复服务名?
  如果重复 → 停止,告知用户,不要继续。
Step 5 之前:我是否已运行 list-images 和 describe-machine-spec?
  如果否 → 停止并立即运行它们。
Step 6 之前:Step 1.5 是否确认无重复服务名?
  如果存在重复 → 停止,告知用户,不要继续。
Step 4 资源:如果 NLB/GW/资源组未找到 → 告知用户并停止。
  不要阻塞或尝试变通。
Step 7 之后:我是否调用了一次 describe-service 并报告了状态?

6. 直接运行 CLI 命令 —— 使用 execute_shell_command 一次一个地运行每条 aliyun CLI 命令。不要编写 bash 脚本、部署脚本或 shell 文件。不要使用 retry_command() 或任何包装函数。每条命令 = 一次直接执行。

预检查

安装或升级 Aliyun CLI 到 >= 3.3.3(所需基线),然后验证。

curl -fsSL https://aliyuncli.alicdn.com/install.sh | bash

aliyun version # 必须报告 >= 3.3.3;如果更低,重新运行 install.sh 升级

每会话生成一次追踪 ID(见可观测性章节)并构建

统一 user-agent。在每条 CLI 命令上通过 --user-agent 传入。

SESSION_ID=$(openssl rand -hex 16)

UA="AlibabaCloud-Agent-Skills/alibabacloud-pai-eas-service-deploy/${SESSION_ID}"

aliyun plugin update

aliyun configure set --auto-plugin-install true


**⚠️ 强制:在继续之前安装并更新所需插件:**

aliyun plugin update

aliyun plugin install aiworkspace --force

aliyun plugin install eas --force


**验证插件已安装:**

aliyun plugin list 2>/dev/null | grep -E "aiworkspace|eas"


如果安装后任一插件缺失,用以下命令重试:

aliyun plugin install <plugin-name> --force


见 [CLI 指南](references/cli-installation-guide.md)。
绝不读取/回显 AK/SK。超时?用 `--read-timeout 60` 重试。

**⚠️ 强制检查点:预检查后,无论插件安装期间有任何警告,
你都必须继续 Step 1。插件安装失败是非阻塞的——插件可能
已经安装。绝不在预检查阶段停止执行。**

---

可观测性

所有 CLI、SDK 和 Terraform 调用都必须携带统一 user-agent(UA),使

请求可追溯到此 Skill 和单一会话。

UA 模板声明(占位符形式):

--user-agent AlibabaCloud-Agent-Skills/{SKILL_NAME}/{session-id}
  • {SKILL_NAME} —— 固定标识符:alibabacloud-pai-eas-service-deploy
  • {session-id} —— 32 位小写十六进制(128 位),每会话生成一次

session-id 规则: 在任何调用之前通过

SESSION_ID=$(openssl rand -hex 16) 生成一次;为每次

CLI(--user-agent)、SDK(client UA)和 Terraform(ALIBABACLOUDSTACK_UA /

provider ua)调用复用同一个值,使所有请求共享一个追踪 ID。不要在步骤之间重新生成或硬编码。

SESSION_ID=$(openssl rand -hex 16)
UA="AlibabaCloud-Agent-Skills/alibabacloud-pai-eas-service-deploy/${SESSION_ID}"

在每条命令上传入,例如:

aliyun eas describe-service --cluster-id <region> --service-name <service> --user-agent "$UA"


---

Step 1:收集参数

参数必填默认
RegionId-
Service Name-
Workspace ID自动选择
Image URI-
Instance Type-
Replicas1
Port8000
OSS Path-

服务名:仅小写字母/数字/下划线。不允许连字符。3-63 字符。

重要:使用用户指定的确切服务名。不要重命名。

如果用户指定前缀(例如“以 skill_qwen_ 开头”),生成 6 位随机后缀(例如 skill_qwen_482917)。

设置 profile 地域 —— 将 CLI profile 地域设置为匹配

部署地域。这避免了当 --cluster-id 与 profile 默认地域不同时的

“Region mismatch”错误:

aliyun configure set --region <region>

Workspace ID:在 metadata.workspace_id 中必填。如果用户未

指定 workspace,查询可用 workspace 并选一个:

aliyun aiworkspace list-workspaces --region <region> \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-pai-eas-service-deploy | \
  jq '.Workspaces[] | select(.Status == "ENABLED") | {WorkspaceId, WorkspaceName}'

如果存在多个 workspace,列出它们让用户选择。

如果只有一个,直接使用。

Step 1.5:检查重复服务名

aliyun eas list-services --region <region> --cluster-id <region> \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-pai-eas-service-deploy | \
  jq '.ServiceList[] | select(.ServiceName == "<name>") | {ServiceName, Status}'

**如果同名服务已存在 → 停止并告知

用户:“名为 <name> 的服务已存在(Status: <status>)。

请选择不同的名称。”不要删除或复用它。**

如果无重复 → 进入 Step 2。

Step 2:ListImages(🚧 阻塞门禁——绝不跳过)

即使用户提供了镜像 URI 也执行。目的 = 验证。

**⚠️ 如果看到“parse error”或“Exit Code 4”,说明插件

安装失败。你必须用显式安装重试:**

aliyun plugin install aiworkspace --force

然后重试 list-images 命令。不要跳过此步骤。

aliyun aiworkspace list-images --region <region> --verbose true \
  --labels 'system.official=true,system.supported.eas=true' \
  --page-size 50 --user-agent AlibabaCloud-Agent-Skills/alibabacloud-pai-eas-service-deploy | \
  jq '.Images[] | {ImageId, ImageUri, ImageCategory}' > /tmp/eas_images.json
echo "Saved $(jq length /tmp/eas_images.json) images"

如果插件重装后仍失败,用超时重试:

aliyun aiworkspace list-images --region <region> --verbose true \
  --labels 'system.official=true,system.supported.eas=true' \
  --page-size 50 --read-timeout 60 \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-pai-eas-service-deploy | \
  jq '.Images[] | {ImageId, ImageUri, ImageCategory}' > /tmp/eas_images.json
echo "Saved $(jq length /tmp/eas_images.json) images"

Model-Image

此输出是 Step 5 所必需的。不要跳过。

❌ 绝不要说“用户已提供镜像”而跳过此步骤。

Step 3:describe-machine-spec(🚧 阻塞门禁——绝不跳过)

即使用户指定了实例类型也执行。不是 list-resources

**⚠️ 如果此命令失败,用 --read-timeout 60 重试。

绝不在 /tmp/eas_specs.json 不存在时进入 Step 5。**

aliyun eas describe-machine-spec --region <region> \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-pai-eas-service-deploy | \
  jq '.InstanceTypes[] | select(.GPU > 0) | {InstanceType, CPU, GPU, Memory}' \
  > /tmp/eas_specs.json
echo "Available GPU specs:"; cat /tmp/eas_specs.json

CPU→GPU 自动切换:如果 vLLM/SGLang + CPU,静默选择 GPU。不要询问。

此输出是 Step 5 所必需的。不要跳过。

Step 4:网络与资源配置

类型VPC配置
共享(默认,无网络字段)
专用 GWnetworking.gateway + cloud.networking
NLBnetworking.nlb + cloud.networking

**⚠️ 如果所需资源不存在 → 停止并告知用户。

不要阻塞或尝试变通。这是一个有效结果。**

专用网关 —— 调用 list-gateway。如果无网关存在 →

告知用户并停止。否则调用 describe-gateway 获取

VPC/VSwitch,然后查询该 VPC 下的安全组。

如果未找到安全组 → 告知用户并停止。

aliyun eas list-gateway --region <region> \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-pai-eas-service-deploy

如果找到网关,获取详情:

aliyun eas describe-gateway --region <region> --cluster-id <region> \
  --gateway-id <gateway_id> \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-pai-eas-service-deploy

提取 VPC 和逗号分隔的 VSwitch ID:

aliyun eas describe-gateway --region <region> --cluster-id <region> \
  --gateway-id <gateway_id> \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-pai-eas-service-deploy | \
  jq '{vpc_id: .LoadBalancerList[0].VpcId, vswitch_id: (.LoadBalancerList[0].VSwitchIds | join(","))}'

NLB —— 需要 VPC/VSwitch/SecurityGroup。如果用户未提供

它们,通过 API 查询。如果任何所需资源未找到 → 告知

用户并停止。

⚠️ NLB 需要跨不同可用区的 ≥2 个 VSwitch。

使用逗号分隔格式:"vswitch_id": "vsw-zone-a,vsw-zone-b"

⚠️ NLB 插件 Bug(aliyun-cli-eas v0.2.0): 如果带

NLB 配置的 create-service 返回 400 且报 'vswitch can not be null'

'vpcId, vswId and securityGroupId are required',这是已知

CLI 插件 bug(非资源问题)。回退策略:

  1. 再重试一次带 NLB 配置的 create-service(最多 2 次尝试)。
  2. 如果都失败 → 从 service.json 移除 networking.nlbcloud.networking

用共享网关重新部署。

  1. 告知用户:“由于 CLI 插件限制,NLB 配置失败。

已改用共享网关部署。”

EAS 专用资源组 —— 调用 list-resources

筛选 ResourceType == "Dedicated"Status == "ResourceReady"

aliyun eas list-resources --region <region> \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-pai-eas-service-deploy | \
  jq '.Resources[] | select(.ResourceType == "Dedicated" and .Status == "ResourceReady") | {ResourceId, ResourceType, Status}'
  • 如果存在 → 设置 "metadata": {"resource": "&lt;ResourceId&gt;"}

不要设置 cloud.computing

  • 如果不存在 → 告知用户并停止。

不要回退到公共资源组。

Step 5:构建 Service JSON

⚠️ 构建 JSON 之前,你必须阅读这些参考文件:

  • references/config-patterns.md —— 所有 8 种模式的完整 JSON 模板
  • references/config-schema.md —— 字段描述和验证规则
  • references/storage-mount.md —— OSS/NAS 挂载配置详情
  • references/network-config.md —— NLB/网关网络配置详情

**⚠️ 硬门禁:写 service.json 之前,验证这些文件

存在且有内容。如果任一缺失 → 停止并立即运行

该步骤。**

test -s /tmp/eas_images.json || echo "MISSING: Run Step 2 NOW"
test -s /tmp/eas_specs.json || echo "MISSING: Run Step 3 NOW"

⚠️ JSON 格式规则:

  • 允许的顶层键:metadatacontainersstoragecloudautoscalernetworking
  • ❌ 绝不使用作为顶层键:specServiceNameImageCpuMemoryGpuprocessor_pathresourceGroupIdinstanceportcommandaccess
  • ❌ 禁止字段:processor_pathresourceGroupIdspecaccess
  • metadata.name = 服务名,metadata.workspace_id = workspace(必填)
  • containers[].image = 镜像 URI,containers[].command = 启动命令,containers[].port = 端口
  • cloud.computing.instance_type = 实例类型(共享网关必需)

快速参考 —— JSON 骨架

以下是最小骨架。**阅读 references/config-patterns.md 获取

包含所有字段和示例的完整模板。**

基础(共享网关):

{"metadata":{"name":"<name>","instance":1,"workspace_id":"<ws>"},
 "containers":[{"image":"<img>","port":<p>,"command":"<cmd>"}],
 "cloud":{"computing":{"instance_type":"<type>"}}}

+ OSS → 添加 "storage":[{"mount_path":"/dir","oss":{"path":"oss://&lt;b&gt;/&lt;p&gt;/","readOnly":true}}]

+ 自动扩缩容 → 添加 "autoscaler":{"min":1,"max":4,"scaleStrategies":[{"metricName":"qps","threshold":20}]}

+ 健康检查 → 向 containers[] 添加 startup_check(见 config-patterns.md Pattern 4)

NLB —— 完整模板(阅读 references/network-config.md 获取详情):

{"metadata":{"name":"<name>","instance":1,"workspace_id":"<ws>"},
 "containers":[{"image":"<img>","port":<p>,"command":"<cmd>"}],
 "cloud":{"computing":{"instance_type":"<type>"},
          "networking":{"vpc_id":"<vpc>","vswitch_id":"<vsw1>,<vsw2>","security_group_id":"<sg>"}},
 "networking":{"nlb":[{"id":"default","listener_port":<p>,"netType":"intranet"}]}}

⚠️ vswitch_id 必须跨不同可用区 ≥2 个 VSwitch 逗号分隔

专用资源组 —— "metadata.resource" 而非 cloud.computing

{"metadata":{"name":"<name>","instance":1,"resource":"<res_id>","workspace_id":"<ws>"},
 "containers":[{"image":"<img>","port":<p>,"command":"<cmd>"}]}

专用网关 —— networking.gateway + cloud.networking

{"metadata":{"name":"<name>","instance":1,"workspace_id":"<ws>"},
 "containers":[{"image":"<img>","port":<p>,"command":"<cmd>"}],
 "networking":{"gateway":"<gw_id>"},
 "cloud":{"computing":{"instance_type":"<type>"},
          "networking":{"vpc_id":"<vpc>","vswitch_id":"<vsw1>,<vsw2>","security_group_id":"<sg>"}}}

⚠️ 如果网关返回多个 VSwitch,vswitch_id 逗号分隔

写前验证

jq -r '.[] | select(.ImageUri | contains("vllm")) | .ImageUri' /tmp/eas_images.json
jq -r '.[] | select(.InstanceType == "<type>") | .InstanceType' /tmp/eas_specs.json

➡️ service.json 验证通过后,立即进入 Step 6——验证通过的 JSON 不是部署。

Step 6:创建服务(强制)

**🔴 确认:Step 1.5 是否确认无重复服务名?

如果此名称的服务已存在 → 停止。告知用户

且不要继续 create-service。**

使用 $(cat service.json) 而非 file://service.json

通过 execute_shell_command 直接运行,不要写 bash 脚本。

aliyun eas create-service --region <region> \
  --body "$(cat service.json)" \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-pai-eas-service-deploy

409 Conflict → 服务已存在。告知用户并停止。

400 BadRequest 且报 'vswitch can not be null'

'vpcId, vswId and securityGroupId are required' → NLB CLI 插件

bug(见 Step 4 回退)。从 service.json 移除 networking.nlb

cloud.networking 并重试。

Step 7:验证部署

**调用 describe-service 一次检查当前状态。不要轮询。

不要循环。不要等待 Running。**

aliyun eas describe-service --region <region> --cluster-id <region> \
  --service-name <name> \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-pai-eas-service-deploy | \
  jq '{Status, ServiceName, ServiceId}'

**报告你得到的任何状态(Running、Waiting、Creating 等)

并立即进入 Step 8。create-service 返回 200 = 成功。**

Step 8:报告结果(强制)

通过 DescribeServiceEndpoint 获取 endpoint 信息:

aliyun eas describe-service-endpoints --region <region> --cluster-id <region> \
  --service-name <name> --user-agent AlibabaCloud-Agent-Skills/alibabacloud-pai-eas-service-deploy | \
  jq '{AccessToken, Endpoints: [.Endpoints[] | {
    Type: .EndpointType, Port: .Port,
    InternetEndpoints: .InternetEndpoints,
    IntranetEndpoints: .IntranetEndpoints
  }]}'

使用 Step 7 的状态和上述 endpoint 报告。

将完整输出复制到你的最终响应中。格式:

部署摘要
==================
服务名:<name>
状态:<from Step 7>

Endpoints:
- <EndpointType>:
    InternetEndpoint: <url or null>
    IntranetEndpoint: <url or null>
    Port: <port or 0>

服务调用示例:
  curl <internet-endpoint>/api/predict/<name> \
    -H "Authorization: <AccessToken>"
  curl <intranet-endpoint>/api/predict/<name> \
    -H "Authorization: <AccessToken>"
  curl <nlb-domain>:<listener_port>/api/predict/<name> \
    -H "Authorization: <AccessToken>"

**InternetEndpointIntranetEndpoint 必须出现在你的

响应中,即使为 null。** 如果为 null:(此网络类型不可用)

**始终包含使用 AccessToken

和 endpoint URL 的服务调用示例。**

**成功标准:create-service 返回 200 且带 ServiceId =

成功。任何状态(Running、Waiting、Creating)都可接受。**

参考(按需阅读)

文档何时阅读
Config PatternsStep 5 —— 所有 8 种模式的完整 JSON 模板
Config SchemaStep 5 —— 字段描述和验证规则
Storage MountStep 5 —— OSS/NAS 挂载详情
Network ConfigStep 4/5 —— NLB/网关配置详情
Model-ImageStep 2 —— 镜像选择指南
Related APIs任何步骤 —— CLI 命令参考
Workflow概览 —— 完整部署流程
CLI Guide预检查 —— 插件安装
RAM Policies预检查 —— 所需权限
Service FeaturesStep 5 —— 高级功能

文档 5 / 6:alibabacloud-dts-task-manager