mcpField
A
alibabacloud-vms-smart-call-by-tts

alibabacloud-vms-smart-call-by-tts

github.com/aliyun生产力28142 次安装1 天前更新
代码仓库

关于 alibabacloud-vms-smart-call-by-tts

这是一个通过 Alibaba Cloud Voice Messaging Service 发起智能语音呼叫的技能,面向需要发送合规通知的用户。它用 LLM 生成通话内容,并从通讯录匹配单个联系人;也可按通话 ID 查询详情。

主要功能

  1. 01按自然语言意图发起语音呼叫
  2. 02由 LLM 生成播报内容
  3. 03从通讯录匹配单个联系人
  4. 04按通话 ID 查询通话详情

适用场景

  1. 01向联系人发送合规语音通知
  2. 02根据自然语言描述安排单人呼叫
  3. 03查询已发起呼叫的详情

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/aliyun/alibabacloud-aiops-skills --skill alibabacloud-vms-smart-call-by-tts

安装后在 Claude Code 中输入/alibabacloud-vms-smart-call-by-tts确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
acceptance-criteria.md
cli-installation-guide.md
external-network-fallback.md
plugin-troubleshooting.md
ram-policies.md
related-commands.md
verification-method.md
scripts/
dyvmsapi_rpc.py
install_aliyun_cli.sh
run_with_aliyun_creds.py

详细介绍

Alibaba Cloud VMS 智能语音通话

通过自然语言描述通话意图,即可通过 Alibaba Cloud Voice Messaging Service(dyvmsapi)发起 AI 生成的语音通话。系统会自动从用户的通讯录中匹配收话人,并使用大模型生成语音内容。

架构:Alibaba Cloud VMS (dyvmsapi) + SubmitIntent API + LLM Content Generation + Contact Book Matching

⚠️ 路径选择规则(必须严格按照以下顺序执行):

  1. 始终先尝试内网主路径:进入 §1,并完整执行内网插件安装流程(cli.aliyun-inc.com)。不得仅仅因为“看起来像外网”就跳过 §1。
  2. 仅当 §1.3 报告 lookup cli.aliyun-inc.com: no such host 或 connection timeout 时,才切换到 §1.alt。对于其他任何错误,必须通过 references/plugin-troubleshooting.md 进行排查,不得将其视为网络故障。
  3. 外网回退方案仅替代 SubmitIntent:它通过脚本 scripts/dyvmsapi_rpc.py 直接调用公网网关(SubmitIntent 仍为私有接口,且没有 SLA)。QueryCallDetailByCallId 是 public 接口,公开版 dyvmsapi CLI 插件已包含该子命令(aliyun plugin install --names dyvmsapi,无需 --source-base)。在外网模式下,通话详情查询仍通过公开版 CLI 插件进行;脚本仅处理 SubmitIntent。
  4. ⚠️ 公开版插件和内网在线版插件同名(aliyun-cli-dyvmsapi),且二者互斥——一次只能安装一个,后续安装会覆盖先前安装的版本。优先级:只要条件允许,就安装内网在线版(它同时包含 SubmitIntent 和 QueryCallDetailByCallId);仅在内网安装失败时才回退到公开版(这会导致 SubmitIntent 不可用,届时由脚本补足)。内网在线版可用时,绝不要安装公开版——否则会失去 submit-intent 子命令。
  5. 完整的外网回退执行手册位于 references/external-network-fallback.md。
  6. **内网连接恢复后,应立即切回主路径。**不要长期停留在回退方案上。切回方法:执行 aliyun plugin uninstall --name dyvmsapi(注意是单数形式的 --name),然后从 §1.3 重新运行 aliyun plugin install ... --source-base ...,以重新安装内网在线版。

与旧版 SingleCallByTts 相比,此功能:

  • ❌ 不要求企业实名认证
  • ❌ 不要求开通服务实例或绑定真实外呼号码
  • ❌ 不要求创建或审核语音模板
  • ✅ 只需配置通讯录,并用自然语言说明意图

能力边界:此 Skill 封装两项能力——发起智能通话(SubmitIntent)和查询通话详情(QueryCallDetailByCallId)。通讯录的增删改查操作以及电话号码归属验证不在范围内;用户必须在 Alibaba Cloud Voice Service 控制台中自行完成。


运行限制

  • 内容合规:语音内容完全由大模型生成,并经过服务端敏感词筛查和大模型安全审查的双重把关。用户无法直接指定实际播放文本。
  • 仅限合规用途:仅限合法、正当的通知场景。严格禁止用于催收、通信诈骗、骚扰或任何其他非法用途。
  • 每次调用仅拨打一个号码:每次通话恰好匹配 一个 联系人。不支持群呼。通知多个收件人时,请分别调用。
  • 电话号码安全:电话号码绝不会传递给大模型。号码查询和外呼由服务端执行。
  • 单个号码的频率限制:同一号码每分钟 1 次、每小时 5 次、每 24 小时 20 次。
  • 通讯录规模限制:每位用户最多 200 位联系人。

1. 安装

[必须] 按严格顺序执行步骤 1.1 → 1.2 → 1.3 → 1.4。不得跳过任何步骤。若任何步骤失败,请参阅 references/plugin-troubleshooting.md。

1.1 [必须] 确认已安装版本 ≥ 3.3.8 的 Aliyun CLI
# Note on --user-agent scope:
# Aliyun CLI system / tooling commands (`version`, `configure`, `plugin`,
# `upgrade`, `oss`, `auto-completion`, `mcp-proxy`, `go-migrate`, `otsutil`,
# and any subcommand invoked with `--help`) DO NOT accept `--user-agent` and
# MUST NOT carry it (passing it raises `unknown flag: --user-agent`).
# The ONLY exception is `aliyun configure ai-mode set-user-agent`, which is
# the dedicated command for declaring the AI-Mode global User-Agent (see §1.1.1).
# Only BUSINESS calls (e.g. `aliyun dyvmsapi submit-intent ...`,
# `aliyun dyvmsapi query-call-detail-by-call-id ...`) accept and MUST carry
#   --user-agent "AlibabaCloud-Agent-Skills/alibabacloud-vms-smart-call-by-tts/1.0.0"
# so the call can be attributed to this Skill.
aliyun version
  • ✅ 输出 3.3.15 或任何 ≥ 3.3.8 的版本 → 继续执行 1.1.1

  • ❌ 找不到命令 / 版本 < 3.3.8 → 运行此 Skill 附带的环境感知型安装程序。它会选择与运行环境相匹配的首个安装策略(Homebrew → 位于 $HOME/.local/bin 的用户级签名二进制 tarball),支持幂等执行,会自行验证,且绝不会通过 shell 管道执行远程脚本:

    bash scripts/install_aliyun_cli.sh
    

    注意:

    • 不要运行 curl -fsSL https://aliyuncli.alicdn.com/setup.sh | bash 安装 CLI:将远程脚本通过管道直接传给 shell 会绕过完整性验证,静态扫描器会将其视为安全违规;该脚本还会写入 /usr/local/bin/aliyun 并静默重试使用 sudo,而在无法输入密码的非交互式 shell(Agent 沙箱、CI 运行器)中会失败。
    • 在 Apple Silicon Mac 上,安装程序会下载 aliyun-cli-macosx-latest-arm64.tgz;在 arm64 硬件上绝不要安装 amd64 构建版本——它需要 Rosetta 2,且容易出现问题。
    • 继续前请先验证:如果最终的 aliyun version 低于 3.3.8,安装程序会以非零状态码退出。如果安装失败,请改用 references/cli-installation-guide.md 中的手动安装方案(涵盖 macOS amd64/arm64、Linux amd64/arm64 和 Windows,每种系统均提供无需 sudo 的方案)。

为什么最低版本是 3.3.8?§1.3 使用了 plugin install --source-base,该标志首次引入于 aliyun CLI v3.3.7(2026-04-16)(PR #1299)。为稳妥起见,最低版本设为 3.3.8。低于 3.3.8 的版本在执行 §1.3 时会报错 ERROR: invalid flag source-base——这是工具版本问题,不是网络问题;请升级 CLI。

1.1.1 [MUST] 启用 AI-Mode(在 CLI 验证通过后立即执行)

在 §1.1 确认 CLI 可用后,立即启用 AI-Mode,并且在本 Skill 中调用任何其他 aliyun ... 命令之前完成。

仅在业务调用中按命令声明 User-Agent。 SKILL.md 和 references/*.md 中的每次业务 aliyun ... 调用(例如 aliyun dyvmsapi submit-intent、aliyun dyvmsapi query-call-detail-by-call-id)都必须显式传入本 Skill 专属的 UA "AlibabaCloud-Agent-Skills/alibabacloud-vms-smart-call-by-tts/1.0.0",以便将调用归因于本 Skill。系统/工具命令(§1.1 范围注释中列出的类别)不接受此 UA 标志,且不得携带该标志——传入后会报错 unknown flag: --user-agent 并中止命令。唯一例外是下方用于声明 AI-Mode 默认 UA 的 aliyun configure ai-mode set-user-agent。

# 1) Enable AI-Mode for this Skill session.
aliyun configure ai-mode enable

# 2) Declare the AI-Mode default UA so the gateway attributes every business
#    call below to this Skill. `ai-mode set-user-agent` is the ONLY
#    system/tooling command that legitimately accepts the UA flag.
aliyun configure ai-mode set-user-agent \
  --user-agent "AlibabaCloud-Agent-Skills/alibabacloud-vms-smart-call-by-tts"

[MUST] 在本 Skill 的每个退出点(成功、失败或提前 STOP)都必须运行 aliyun configure ai-mode disable 以禁用 AI-Mode——参见 §6 步骤 2/步骤 4 和 §9 最佳实践 #5。

1.2 [MUST] 检查 submit-intent 子命令是否已存在
aliyun dyvmsapi submit-intent --help 2>&1

根据输出判断:

输出模式结论后续步骤
包含 API 版本: 2017-05-25 且包含 --user-message插件已就绪跳过 1.3,转到 §2
unknown command "submit-intent" / command not found未安装插件转到 1.3
aliyun: command not found未安装 CLI返回 1.1
其他异常查阅 references/plugin-troubleshooting.md
1.3 [MUST] 安装内网在线版 dyvmsapi 插件

SubmitIntent 仅通过 Alibaba 内网在线版 CLI 插件分发。公开发布的 aliyun-cli-dyvmsapi 不包含此子命令。

按原样运行以下命令(不得省略或修改任何参数):

aliyun plugin install --names dyvmsapi \
  --version 0.1.0 \
  --source-base https://cli.aliyun-inc.com/registry_id/2/env/online/plugins

[MUST] 硬性要求(任何一项不符都会导致安装失败或拉取错误的构建版本):

参数正确值常见错误
CLI 版本≥ 3.3.8< 3.3.8 → ERROR: invalid flag source-base — 按 §1.1 升级,不得切换到外部备用方案
--names复数,带 s--name(安装会因 invalid flag 失败;单数形式仅用于 uninstall)
--version0.1.0(必填)省略后会获取最新的公开版构建
--source-base上方的 URL(必填)省略后会从公开镜像拉取,该镜像不包含 submit-intent
URL 路径env/online/pluginsenv/pre/plugins 已弃用
URL 主机cli.aliyun-inc.com只能从 Alibaba 内网解析

预期输出:

Downloading aliyun-cli-dyvmsapi 0.1.0...
Plugin aliyun-cli-dyvmsapi 0.1.0 installed successfully!

如果输出为 plugin "aliyun-cli-dyvmsapi" is already installed (version X.Y.Z); continuing will replace it with version 0.1.0 → 符合预期(覆盖安装)。等待安装完成。

如果输出为 ERROR: invalid flag source-base → CLI 版本低于 3.3.8,无法识别此标志。重新运行 §1.1 中适配环境的备用升级流程(会自动选择 brew/系统级/用户级升级)进行升级,然后重试 §1.3。[FORBIDDEN] 严禁因该错误切换到 §1.alt——这是工具版本问题,不是网络问题。仅在出现 no such host/connection timeout 时才允许使用外部备用方案。

如果输出为 lookup cli.aliyun-inc.com: no such host/connection timeout → 当前运行环境不在 Alibaba 内网。切换到 §1.alt 并继续(功能等效;无需安装插件)。

其他错误 → 查阅 references/plugin-troubleshooting.md。

1.4 [MUST] 安装后重新验证
# `--help` is a help-mode invocation: it MUST NOT carry `--user-agent`
# (passing it raises `unknown flag: --user-agent` and aborts the command).
# See §1.1.1 for the full system-vs-business UA scope rule.
aliyun dyvmsapi submit-intent --help

验证标准(继续操作前必须全部满足):

  • 输出包含 API 版本: 2017-05-25
  • 输出包含参数 --user-message
  • 输出包含描述 提交文本意图… 或等效内容

如果任何一项不满足 → 请参阅 references/plugin-troubleshooting.md。


1.alt 外部备用路径(仅在主路径不可用时进入)

触发条件:§1.3 报告 lookup cli.aliyun-inc.com: no such host,或已确认运行环境位于无法访问阿里巴巴内网/VPN 的公网。 主插件正常工作时,不要进入此路径。

先决条件(不得缺少任何一项):

  • Python 3.6+(macOS/Linux 上预装;使用 python3 --version 验证)——第 2 步(基于脚本的 SubmitIntent)所需
  • 本仓库随附的脚本 scripts/dyvmsapi_rpc.py(无第三方依赖)——仅处理 SubmitIntent
  • Aliyun CLI + 公网发布版 dyvmsapi 插件——第 4 步(基于 CLI 的 QueryCallDetailByCallId)所需:
    # Refresh the public plugin index so the latest public-release dyvmsapi metadata is used.
    aliyun plugin update
    
    # Install the public-release dyvmsapi plugin (default source = public mirror; no --source-base).
    aliyun plugin install --names dyvmsapi
    
    ⚠️ 与内网在线插件互斥:如果 §1.3 已成功安装内网在线版本(0.1.0),则此处不要安装公网发布版——内网在线版本已包含 query-call-detail-by-call-id。仅当 §1.3 因 no such host 失败时,才安装公网发布版。
  • 可从公网访问 dyvmsapi.aliyuncs.com

验证脚本已就位:

python3 scripts/dyvmsapi_rpc.py --help

如果输出包含 dyvmsapi public RPC direct-call script (zero dependencies),则继续进行 §2 凭据验证。(在外部脚本路径下,凭据由辅助程序 scripts/run_with_aliyun_creds.py 从当前 aliyun configure 配置文件自动注入——详见 §2。)

重要限制:

  • 切换到外部路径后,必须将 §6 第 2 步中的 aliyun dyvmsapi submit-intent 调用替换为脚本调用;第 4 步(aliyun dyvmsapi query-call-detail-by-call-id)仍使用 CLI,并安装上文所述的公网发布版插件。详情:§6.alt 和 references/external-network-fallback.md。
  • AI-Mode:在 §1.1.1 中启用一次,并且无论第 2 步通过脚本运行还是第 4 步通过 CLI 运行,均必须在此 Skill 的每个退出点将其禁用。§1.1.1 中的逐命令 UA 规则仍然适用:业务 aliyun ... 调用(例如 aliyun dyvmsapi query-call-detail-by-call-id)必须携带此 Skill 的 UA;系统/工具命令不得携带——详见 §1.1.1。
  • 不要交错使用两条路径。

2. 凭证验证

预检查:需要阿里云凭证

安全规则:

  • 绝不读取、回显或打印 AK/SK 值(例如,禁止执行 echo $ALIBABA_CLOUD_ACCESS_KEY_ID)
  • 绝不要求用户在对话或命令行中直接输入 AK/SK
  • 绝不使用 aliyun configure set 和明文凭证值
  • 只能使用 aliyun configure list 检查凭证状态
aliyun configure list

检查输出中是否有有效配置(AK、STS 或 OAuth 身份)。

注意:Valid 仅表示本地配置字段格式正确,并不代表 AK 在服务端仍然有效。如果下游调用返回 InvalidAccessKeyId.NotFound / SignatureDoesNotMatch,则凭证语法正确,但已被禁用或轮换——请在 AK 管理控制台 中交叉核实状态。

如果没有有效配置,请在此处停止。

  1. 从 阿里云控制台 获取凭证
  2. 在本次会话之外配置凭证:在用户自己的终端中运行 aliyun configure(或在 shell 配置文件中导出环境变量)。交互流程会要求输入多个值,包括 AK ID、AK Secret 和默认 Region ID。通常只有 Region 提示会让用户不知所措(CLI 不会显示候选项),因此 Agent 必须主动告知用户:建议使用 cn-hangzhou——dyvmsapi 是集中式服务,不受 Region 限制,因此任何有效的 Region 都可使用;如果用户的其他阿里云资源已位于其他 Region(例如 cn-shanghai、cn-beijing、cn-shenzhen、cn-hongkong、ap-southeast-1),也可以选择该 Region。完整候选列表:references/cli-installation-guide.md。
  3. 等 aliyun configure list 显示有效配置后,返回并重新运行

2.1 主要路径(CLI)——凭证

在主要路径中,aliyun dyvmsapi submit-intent / query-call-detail-by-call-id 会自动从当前配置中读取凭证。Agent 无需执行任何额外操作。

2.2 §1.alt 外部回退(脚本)——自动注入默认凭据

设计:外部回退脚本路径不再要求用户手动 export AK/SK,而是复用用户已配置的 aliyun configure 当前配置文件,并由辅助脚本 scripts/run_with_aliyun_creds.py 自动将凭据注入子进程环境。此设计基于三个原因:① 用户体验与主要路径一致;② 跨进程的 Shell export 无法将凭据传递给 Agent 的子进程(技术上不可行);③ 用户已为此配置文件提供凭据,再次询问属于重复输入。

[MUST] 标准调用模式:Agent 始终通过辅助脚本调用。不要手动从 ~/.aliyun/config.json 提取凭据。

# 1) 预检查:确认当前配置文件符合自动注入要求
python3 scripts/run_with_aliyun_creds.py --check
# 预期结果:`OK profile=default mode=AK ready for auto-injection` → 可以开始

# 2) 告知用户将使用哪个配置文件(保持透明;不显示凭据值)
python3 scripts/run_with_aliyun_creds.py --print-profile
# 输出示例:`profile=default mode=AK region=cn-hangzhou`
# Agent 必须明确告知用户:“我将使用 profile=<name> mode=<mode> 调用 SubmitIntent”——让用户有机会拒绝。

# 3) 发起实际调用(辅助脚本注入环境变量;脚本从环境变量读取;不持久化任何值)
python3 scripts/run_with_aliyun_creds.py -- \
  python3 scripts/dyvmsapi_rpc.py SubmitIntent -P UserMessage="<the user's intent>"

支持的模式:AK / StsToken。StsToken 还会注入 ALIBABA_CLOUD_SECURITY_TOKEN,之后脚本会将其作为公共参数纳入签名。

不支持的模式(RamRoleArn / EcsRamRole / OAuth / External / CredentialsURI …):辅助脚本会以状态码 3 退出,并提示用户手动获取临时 AK/SK/STS。此时,回退到主要路径(CLI 原生支持所有模式),或让用户新建一个 AK 配置文件。

[FORBIDDEN] 禁止的行为:

  • 在 Agent 代码中绕过辅助脚本,直接读取 ~/.aliyun/config.json / 使用 json.load(...),严格禁止——这会导致以下三种常见故障:硬编码 profiles[0] 而非 current(配置文件错误)、遗漏 StsToken 的 sts_token,以及凭据意外泄露到调试输出或脚本日志中。
  • 将 AK/SK/SecurityToken 写入 ran_scripts/*.sh / outputs/*.md / 任何日志 / 任何可在 Git 中查看的文件,严格禁止(占位符注释,例如 # AK=<from-config>,也不允许——这会误导读者)。
  • 通过 -P SecurityToken=... 将 SecurityToken 作为业务参数传递,严格禁止——它是公共参数,必须参与签名;辅助脚本会自动处理。
  • 使用 echo / print / --debug 输出凭据值,严格禁止。
  • 恢复使用旧版 read -s ... && export ... 模式,严格禁止——跨进程的 Shell 环境无法传递到子进程;这在技术上不可行。

3. RAM 权限

必须向 RAM 子账号授予 dyvms:SubmitIntent 和 dyvms:QueryCallDetailByCallId 权限。根账号无需额外设置。完整策略请参阅 references/ram-policies.md。

**[MUST] 权限失败处理:**执行期间,任何命令或 API 调用在任何时候因权限错误而失败时,都应遵循以下流程:

  1. 阅读 references/ram-policies.md,获取此 SKILL 所需权限的完整列表
  2. 使用 ram-permission-diagnose 技能指导用户申请所需权限
  3. 暂停操作并等待用户确认已授予所需权限

4. 前置条件:配置通讯录

通讯录管理不在此 Skill 的范围内。发起智能呼叫前,用户必须在阿里云语音服务控制台完成以下操作:

  1. 验证号码所有权:为要添加的每个电话号码完成所有权验证(默认有效期约为 6 个月)
  2. 添加联系人:为每个已验证的号码分配一个易于识别的标签,例如“妈妈”“张经理”“老吴”
  3. (可选)更新或移除现有联系人

通讯录限制:

  • Tag 和 PhoneNumber 严格一一对应
  • 标签是大模型匹配联系人时使用的唯一信号,请使用清晰、易区分的名称

5. 参数确认

重要:参数确认——执行 API 调用前, 确认用户的意图(呼叫谁 + 传达什么)。如果用户的消息已经清楚说明这两点,则无需确认,直接继续。 不要反复斟酌措辞或起草口播文本——UserMessage 是对意图的描述, 而非最终播放脚本;实际口播内容由服务端大模型生成(Model.CallContent)。

参数必填描述默认值
UserMessage是对呼叫意图的自然语言描述(不是要逐字播报的文本)无(用户必须提供)

UserMessage 示例:

  • “提醒妈妈我今晚不回家吃饭”
  • “给张经理打电话,告诉他明天上午 10 点开会”
  • “告诉老吴今天下午把合同带来”

这些都是意图描述。如果用户的原始消息已经清楚说明了呼叫对象和要传达的内容,直接继续——不要复述确认或请求批准。不要问“要不要这样说:X?”或反复斟酌措辞——口播内容由服务端生成。


6. 核心工作流

AI-Mode 和 User-Agent:AI-Mode 已在 §1.1.1 中启用(CLI 验证完成后立即执行)。除非之前已禁用(参见步骤 3 下方的说明),否则不要在此处重新启用。以下每次业务类 aliyun ... 调用(例如 aliyun dyvmsapi submit-intent、aliyun dyvmsapi query-call-detail-by-call-id)都必须显式传入此 Skill 专用的 UA "AlibabaCloud-Agent-Skills/alibabacloud-vms-smart-call-by-tts/1.0.0"。系统/工具命令不接受此标志,且不得携带此标志——参见 §1.1.1。

[MUST] 在此 Skill 的每个退出点禁用 AI-Mode——成功、失败、提前 STOP,以及所有其他退出情况。禁用命令为:

aliyun configure ai-mode disable
步骤 1:提取用户意图

从用户的消息中提取要联系谁以及要传达什么。使用自然语言指称即可(例如“我爸”“Mom”“张经理”)——无需与通讯录中存储的 Tag 字面值完全一致;服务端 LLM 会与用户的联系人列表进行语义匹配。

  • 意图已明确(联系人和内容都毫无歧义)→ 跳过确认,立即进入步骤 2。例如:“给我爸打电话,告诉他去买菜”——联系人=爸爸,内容=去买菜,直接发起。
  • 意图部分不明确(缺少联系人,或内容过于模糊,无法执行)→ 只问一次,澄清缺失部分,然后发起。例如:“打个电话”——联系人=?内容=?问一次。

[MUST] 最多一轮,然后发起 — UserMessage 不是实际要说出的逐字稿;它是提供给服务端 LLM 的意图描述,服务端 LLM 会据此生成实际口述内容。一旦联系人和内容明确(无论是从原始消息中得知,还是通过一次澄清得知),立即进入步骤 2。禁止以下行为:

  • 起草“通知话术”并让用户审核措辞
  • 询问“这样说可以吗?”或提供多种措辞供选择
  • 询问用户通讯录中确切的 Tag 字面值(例如“你爸在通讯录里的 Tag 叫什么?”)——服务端会进行语义匹配;使用自然语言指称即可
  • 在联系人身份已明确时再次确认(“爸”/“老爸”/“爸爸”都是同一称谓——不要问“是哪一个?”)
  • 除非用户主动表示意图有误,否则不得再次确认

[MUST] 绝不因无法验证 Tag 而中止 — Agent 没有本地 API 可列出或验证通讯录条目(参见 §4:CRUD 不在范围内)。如果 Agent 无法确认用户提供的 Tag 是否存在,仍必须继续进入步骤 2,由服务端进行验证。禁止中止流程、让用户“先去检查控制台”,或以 Tag“可能不存在”为由拒绝呼叫——正确做法是调用 API,并如实转达服务端返回的内容(成功或错误)。

步骤 2:发起智能呼叫
aliyun dyvmsapi submit-intent \
  --user-message "<user-confirmed natural-language intent>" \
  --user-agent "AlibabaCloud-Agent-Skills/alibabacloud-vms-smart-call-by-tts/1.0.0"

§6.alt 外部回退 — 如果运行时进入了 §1.alt(脚本路径),请将此步骤替换为由辅助脚本驱动的调用(凭据必须通过辅助脚本自动注入,参见 §2.2):

python3 scripts/run_with_aliyun_creds.py -- \
  python3 scripts/dyvmsapi_rpc.py SubmitIntent \
    -P UserMessage="<user-confirmed natural-language intent>"
  • Key 必须使用帕斯卡命名法(UserMessage,而不是 user-message)。响应结构与 CLI 相同;步骤 3 的解析逻辑通用。
  • 严禁不经辅助脚本直接调用 python3 scripts/dyvmsapi_rpc.py ... ——脚本本身不会读取 ~/.aliyun/config.json;缺少环境变量会导致 [ERROR] AK/SK not provided。
  • 调用前,运行 §2.2 [MUST] 规定的 3 步流程(--check → --print-profile 并告知用户 → 实际调用)。
  • 详情参见 references/external-network-fallback.md。
步骤 3:解析响应
  • Code == "OK" 且 Success == true:呼叫已发起
    • 向用户显示 Model.Tag(匹配的联系人)、Model.CallContent(播报文本)和 Model.CallId
    • 出于电话号码安全考虑,响应中不包含拨出的号码
  • 错误处理请参阅 references/related-commands.md 中的错误代码表
  • Code != "OK" 是有效的执行结果——例如,未找到联系人、超出配额、参数无效。解析错误,如实向用户报告,并将 Skill 运行视为已完成(结果为错误)。除非用户明确要求,否则不要自动重试或返回步骤 1。

步骤 3 后的 AI-Mode 生命周期:

  • 如果 Code != "OK",或者用户不需要步骤 4 → 这是退出点 → 立即禁用 AI-Mode。
  • 如果 Code == "OK" 且可能继续执行步骤 4(用户想查看呼叫结果)→ 暂时不要禁用。保持 AI-Mode 启用,直到步骤 4 完成。
  • 如果 Skill 会话中断(例如 Agent 在步骤 3 后已禁用 AI-Mode,随后用户又请求执行步骤 4)→ 在步骤 4 前重新启用 AI-Mode,然后在结束时再次禁用。这是唯一允许重新启用的情况。

[FORBIDDEN] 严禁伪造响应或安排模拟投递——当步骤 2 遇到基础设施故障(缺少或过期的凭据、网络不可达、脚本以非零退出代码结束且没有 JSON 正文、InvalidAccessKeyId、SignatureDoesNotMatch)时:

  • 停止前,务必先运行 aliyun configure ai-mode disable(AI-Mode 已在 §1.1.1 中启用;每个退出点都必须禁用,包括故障路径)。
  • 立即停止,如实、逐字向用户报告错误,并要求用户修复问题后重试。
  • 严禁伪造 Code: OK、虚假的 CallId、虚假的 Model.Tag 或虚假的 Model.CallContent。
  • 严禁编写伪造的 call_result.json、task_summary.md 或 executed_actions.sh 来冒充成功投递。
  • 严禁使用“模拟”“mock”“假设用户已经……”或“由于这是模拟环境”等措辞来绕过真实调用。
  • 以上任何行为均视为欺诈性投递。
步骤 4(可选):查询呼叫结果

SubmitIntent 返回的 Model.CallId 仅表示呼叫已受理,不表示被叫方已接听。如果用户想确认呼叫是否接通,请调用 query-call-detail-by-call-id。

# Take the CallId returned by SubmitIntent (format: <ms-timestamp>^<call-sequence>, e.g. "1779785134472^9876543210").
CALL_ID="<Model.CallId from step 2 response>"
# The first segment of CallId is already a Unix-millisecond timestamp; reuse it as query-date.
# `--query-date` is an int (Unix-millisecond timestamp), NOT a yyyyMMdd string — do NOT call any datetime conversion.
QUERY_DATE="${CALL_ID%%^*}"

aliyun dyvmsapi query-call-detail-by-call-id \
  --call-id "$CALL_ID" \
  --prod-id 11000000300006 \
  --query-date "$QUERY_DATE" \
  --user-agent "AlibabaCloud-Agent-Skills/alibabacloud-vms-smart-call-by-tts/1.0.0"

硬性要求:

  • --prod-id 必须为 11000000300006(语音通知产品 ID)。SubmitIntent 通过此产品分发;任何其他 prod-id 都会返回 Code: OK,但没有 Data。
  • --query-date 必须与 CallId(毫秒时间戳)在同一天。
  • CDR 写入延迟:对于通知类呼叫(通常持续 10–30 秒),CDR 通常在呼叫结束后约 40 秒可用。如果 Code: OK 返回时没有 Data,请在再等待 30–60 秒后重试一次。不要盲目硬等 1–2 分钟。

§6.alt 外部路径——步骤 4 仍使用 CLI。QueryCallDetailByCallId 的可见性为 public;公开发布版的 aliyun-cli-dyvmsapi 插件已包含该命令:

aliyun plugin update
aliyun plugin install --names dyvmsapi   # 公开发布版;无需 --source-base

§1.alt 中应已安装公开发布版插件。如果由于任何原因尚未安装,请先运行上述两条命令。安装后,上方的 aliyun dyvmsapi query-call-detail-by-call-id ... 命令即可正常使用。在外部路径中,脚本只替换 SubmitIntent;CDR 查询仍通过 CLI 执行。详情请参阅 references/external-network-fallback.md。

响应解析:

Data 是一个 JSON 字符串(需要再次解析),其中包含:

字段含义
stateDesc本地化状态描述,例如 用户接听(用户已接听)/ 未接听(无人接听)/ 呼叫中(正在呼叫)
state状态码(200000 = 已接听)
duration通话时长,单位为秒
bRingTime / bStartTime / bEndTime振铃 / 接听 / 挂断时间戳
callee拨打的号码(此 CDR API 会返回完整号码——只有账户所有者才能查看自己的 CDR;这与 SubmitIntent 规则并不冲突,电话号码不会传递给 LLM)
gmtCreate平台受理通话请求的时间
calleeShowNumber来电显示号码

[MUST] 清晰呈现 — 严禁直接向用户输出原始 Data JSON 字符串。解析后,将结果呈现为三个实际的 Markdown 表格(不得使用围栏代码块,也不得使用 ───── 之类的 ASCII 分隔线——Markdown 渲染器会将其识别为 <hr>,并将其余内容重新排版为单行):

通话结果

✅ 状态<stateDesc>(state=<state>)
👤 被叫号码<callee_masked>
📲 显示号码<calleeShowNumber>
⏰ 时长<duration> 秒

时间线

🕐 受理时间<gmtCreate>
🔔 振铃时间<bRingTime>(+<offset_after_accepted> 秒)
📞 接听时间<bStartTime>(振铃后 +<offset_after_ringing> 秒)
🔚 挂断时间<bEndTime>(通话 <duration> 秒)
👋 挂断方<callee-initiated|caller-initiated>(hangupDirection=<0|1>)

参考信息

🆔 CallId<callId>

规则:

  • 使用实际的 Markdown 表格。不得将此布局放入围栏代码块,也不得使用 ASCII 分隔符(─────、===、单元格内的 --- 等)——Markdown 渲染器会将其识别为 <hr>,并将其余文本重新排版为单行。
  • 在数字状态 state 旁显示本地化的 stateDesc。不要只显示原始数字。
  • 必须对被叫号码进行掩码处理:前三位、接着 ****、最后四位——这就是表格中的 <callee_masked>。绝不可输出完整号码。
  • 时间字段必须包含相对时间间隔(受理 → 振铃、振铃 → 接听),让用户能够了解时间线。
  • hangupDirection:0 = 被叫方挂断,1 = 主叫方挂断。
  • 对于未接听的情况(state ≠ 200000),省略时间线中的接听和挂断行,并使用一行摘要,例如:“✗ 被叫方未接听(振铃 X 秒后挂断)”。

完整的参数参考和响应示例请参阅 references/related-commands.md。

[MUST] 在每个退出点禁用 AI-Mode — 无论出于何种原因,在发送最终回复之前,务必先运行 aliyun configure ai-mode disable。


7. 成功验证

请参阅 references/verification-method.md。

快速检查:响应中的 Code == "OK" 且 Model.CallId 非空,表示通话已成功发起。


8. 命令参考

请参阅 references/related-commands.md。


9. 最佳实践

  1. UserMessage 必须明确提及联系人:使用用户认为在其通讯录中可识别的称呼(例如“妈妈”“张经理”);避免使用代词(“他”“那个人”)。
  2. 遵守速率限制:每个号码每分钟 1 次、每小时 5 次、每 24 小时 20 次;批量通知时,每次调用至少间隔 60 秒。
  3. 调用前配置通讯录:确保已在控制台添加联系人,并完成有效的号码所有权验证。
  4. 仅用于合规场景:仅用于合法通知场景;禁止用于催收债务、欺诈、骚扰等用途。
  5. 每次 Skill 执行结束时(无论成功或失败)都必须禁用 AI-Mode:运行 aliyun configure ai-mode disable。

10. 参考链接

文件内容
references/cli-installation-guide.md阿里云 CLI 安装指南
references/plugin-troubleshooting.mddyvmsapi 插件安装故障排查(§1 发生任何故障时都必须查阅)
references/ram-policies.mdRAM 策略(最小 Action 权限)
references/related-commands.mdCLI 命令参考、参数、错误代码
references/verification-method.md验证方法
references/acceptance-criteria.md验收标准
references/external-network-fallback.md外部回退执行手册(仅在主路径不可用时使用)
scripts/dyvmsapi_rpc.py零依赖 Python 脚本,可直接调用公开的 dyvmsapi 网关
scripts/run_with_aliyun_creds.py凭据注入辅助脚本:从 aliyun configure 的当前配置自动注入环境变量,然后执行子命令(外部回退路径的必需入口)
scripts/install_aliyun_cli.sh适配环境的阿里云 CLI 安装程序/升级程序(Homebrew → 用户级签名二进制 tarball;可幂等运行并自行验证)。当 CLI 缺失或版本低于 3.3.8 时,从 §1.1 调用。
related_apis.yaml依赖 API 清单

评论

支持 Markdown