360 Secure SkillHub
360 安全技能中心

Arkclaw Outbound Call

面向生活服务门店的AI代打电话技能:接收自然语言需求,校验并追问预约、改订、取消所需信息,调用火山引擎外呼接口提交任务,轮询任务状态并整理结果告知用户;超出生活服务外呼范围的需求会直接拒绝。

niesongyang
niesongyang
热度 16.00
最近更新 2026-03-15 18:26:46
分类:生活依赖:代码执行 / 第三方 API / 内部调用大模型应用场景:日程安排 / 工作流

安装技能

复制下面的话术发给你的 Agent,它会通过 secure-skills 检索并安装该技能。

执行命令安装此 skill: npx secure-skills-cli add arkclaw-outbound-call
Metadata
name
arkclaw-outbound-call
description
AI智能代打电话,自动办理生活服务场景的预约/改订/取消事务,无需用户手动拨打电话。支持用户通过job_id查询外呼任务状态
version
0.1.0
user-invocable
true
argument-hint
<自然语言描述需求>
emoji
📞
metadata
{"openclaw":{"requires":{"env":["OPENCLAW_SESSION_ID","OPENCLAW_CHAT_TYPE","OPENCLAW_RUNTIME_MODE","OPENCLAW_CHANNEL","OPENCLAW_SESSION_KEY","OPENCLAW_USER_ID","VOLC_ACCESS_KEY","VOLC_SECRET_KEY"],"bins":["python3"]}}}

概述

业务目标

将外呼能力接入ArkClaw,验证「AI代个人用户打电话办事」在生活服务场景的可行性与价值,后续可拓展到更多场景与商业化落地。

目标用户

希望将生活服务场景中「需要打电话」的琐事外包给AI Agent的用户,适用场景包括但不限于:餐厅/剪发/美甲/按摩/酒店等门店的预约、改订、取消、查询外呼任务状态。


核心用户故事

  1. 核心场景:作为不想自己打电话的用户,我可以直接用自然语言告诉ArkClaw要联系的门店、具体需求,AI会自动完成外呼沟通,办结后告知我结果。
  2. 分步场景:
    • 我可以直接说自然语言需求:「帮我联系A餐厅,电话13500015678,预约3月20日晚上7点的家庭聚餐,4个人」
    • 当预订需要支付押金时,我会收到二次确认提示,确认后再继续执行
    • 我能收到清晰的结果:成功时会返回完整的预订信息,失败时会告知具体原因,以及可选的替代方案

功能说明

一、前置准备(使用前需完成)

  1. 开通火山引擎账号,完成外呼号线对接与资质备案
  2. 在火山外呼平台创建3个专用Agent并配置对应的语音交互逻辑、音色、话术模板,每个场景对应固定剧本ID:
    场景 Agent名称 剧本ID
    新预约 预约Agent 123
    修改已有预约 改订Agent 456
    取消已有预约 取消Agent 789
  3. 每个Agent配置对应的任务并发数,支持多任务并行执行

二、外呼任务执行流程

阶段1:任务创建与校验

  1. 用户输入:用户用自然语言描述需求,无需固定格式
  2. 范围校验:仅接受生活服务类商户的「预约/改订/取消」类任务,其他类型任务(如商务通话、私人联系、非生活服务类需求)直接拒绝,返回拒绝原因
  3. 需求分类:自动识别用户需求是「预约/改订/取消」中的哪一类,匹配对应剧本ID
  4. 信息校验与追问:校验对应场景的必填信息,任意一项缺失时自动用自然语言追问用户,直到信息补全:
    需求类型 必填信息 对应参数名
    预约 门店名称、门店电话、预约日期、预约时间、人数、用户姓氏、用户联系电话 date/time/people_number/shop_phone_number/first_name/user_phone_number
    改订 门店名称、门店电话、新预约日期、新预约时间、新人数、用户姓氏、预订时预留的联系电话 new_date/new_time/new_people_number/shop_phone_number/first_name/user_phone_number
    取消 门店名称、门店电话、用户姓氏、预订时预留的联系电话 shop_phone_number/first_name/user_phone_number
  5. 押金二次确认:如果外呼前检测到该门店预订需要支付押金,自动向用户发送确认提示,用户确认后再继续执行
  6. 异常处理:若本阶段任何步骤出现接口异常(code非200),直接将错误信息整理为自然语言告知用户,终止外呼流程,不进入后续提交步骤。

阶段2:外呼任务提交

执行SOP

  1. 确认 OPENCLAW_SESSION* 等必须的会话级环境变量可以正常获取到值,非空或者非空格。

  2. 执行脚本:调用scripts/submit_job.py提交外呼任务,执行脚本的时候,必须将metadata里面的环境变量也传递进去。 2.1 请检查所有OPENCLAW_*开头的环境变量(OpenClaw运行时注入的会话上下文变量)是否已正确设置,包括但不限于:

    • OPENCLAW_SESSION_ID
    • OPENCLAW_CHAT_TYPE
    • OPENCLAW_RUNTIME_MODE
    • OPENCLAW_CHANNEL
    • OPENCLAW_SESSION_KEY
    • OPENCLAW_USER_ID 3调用示例,参考如下,其中request-body是一个json的字符串: env
      OPENCLAW_SESSION_ID="$OPENCLAW_SESSION_ID"
      OPENCLAW_CHAT_TYPE="$OPENCLAW_CHAT_TYPE"
      OPENCLAW_RUNTIME_MODE="$OPENCLAW_RUNTIME_MODE"
      OPENCLAW_CHANNEL="$OPENCLAW_CHANNEL"
      OPENCLAW_SESSION_KEY="$OPENCLAW_SESSION_KEY"
      OPENCLAW_USER_ID="$OPENCLAW_USER_ID"
      VOLC_ACCESS_KEY="$(openclaw config get skills.entries.arkclaw-outbound-call.config.VOLC_ACCESS_KEY)"
      VOLC_SECRET_KEY="$(openclaw config get skills.entries.arkclaw-outbound-call.config.VOLC_SECRET_KEY)"
      python3 {baseDir}/scripts/submit_job.py
      --request-body '{ "job_name": "【预约/改订/取消】+ 门店名称 + 用户需求", "job_description": "用户自然语言原始需求(可选)", "script_id": "对应场景的剧本ID:预约=123/改订=456/取消=789", "params": { "user_phone_number": "联系电话(所有场景必填)", "date": "预约日期(仅预约场景)", "time": "预约时间(仅预约场景)", "people_number": "预约人数(仅预约场景)", "shop_phone_number": "门店电话(所有场景必填)", "first_name": "用户姓氏(所有场景必填)", "new_date": "新预约日期(仅改订场景)", "new_time": "新预约时间(仅改订场景)", "new_people_number": "新预约人数(仅改订场景)" } }'
  3. 查看脚本输出,关注"SubmitJob 接口响应",响应结果参考:

{
  "ResponseMetadata": {
    "Action": "SubmitJob",
    "Region": "cn-north-1",
    "RequestId": "6cf6a5e0-45e7-440e-85cf-c700dce536a8",
    "Service": "bytebot",
    "Version": "2023-01-01",
    "Error": {
      "Code": "{ErrorCode}",
      "Message": "{ErrorMessage}"
    }
  },
  "Result": {
    "JobId": "任务唯一ID"
  }
}
  1. 处理异常处理,请检查是否有如下异常 5.1 IF 接口返回ERROR Code不为空,直接将Error.Message字段的错误信息整理为自然语言告知用户,终止流程,不进入阶段3。 5.2 ELSE IF 接口返回JobId为空,直接告知用户:"外呼任务提交失败",终止流程,不进入阶段3。
  2. 若无异常,继续执行阶段3。

阶段3:任务状态轮询与结果回传

  1. 确认 OPENCLAW_SESSION* 等必须的会话级环境变量可以正常获取到值,非空或者非空格。
  2. 调用scripts/wait_job_result.py脚本,传入上一步返回的JobId,执行脚本的时候,必须将metadata里面的环境变量也传递进去。 2.1 请检查所有OPENCLAW_*开头的环境变量(OpenClaw运行时注入的会话上下文变量)是否已正确设置,包括但不限于:
    • OPENCLAW_SESSION_ID
    • OPENCLAW_CHAT_TYPE
    • OPENCLAW_RUNTIME_MODE
    • OPENCLAW_CHANNEL
    • OPENCLAW_SESSION_KEY
    • OPENCLAW_USER_ID
  3. 调用示例,参考: env
    OPENCLAW_SESSION_ID="$OPENCLAW_SESSION_ID"
    OPENCLAW_CHAT_TYPE="$OPENCLAW_CHAT_TYPE"
    OPENCLAW_RUNTIME_MODE="$OPENCLAW_RUNTIME_MODE"
    OPENCLAW_CHANNEL="$OPENCLAW_CHANNEL"
    OPENCLAW_SESSION_KEY="$OPENCLAW_SESSION_KEY"
    OPENCLAW_USER_ID="$OPENCLAW_USER_ID"
    VOLC_ACCESS_KEY="$(openclaw config get skills.entries.arkclaw-outbound-call.config.VOLC_ACCESS_KEY)"
    VOLC_SECRET_KEY="$(openclaw config get skills.entries.arkclaw-outbound-call.config.VOLC_SECRET_KEY)"
    python3 {baseDir}/scripts/wait_job_result.py --JobId "任务唯一ID"
  4. 进入到当前阶段,就可以以比较友好的方式,把任务提交的参数和返回的JobId,整理为自然语言,告知用户任务已提交,等待外呼执行。 参考返回样式:
    • 任务提交成功返回示例:

      ✅ 已为你发起外呼任务「海底捞火锅(中关村店)」,任务完成后会通知你! 📋 任务ID:{JobId} 📅 时间:3月20日 19:00 👥 人数:4位 📝 预订人:李先生 ⏰ 保留时长:最多保留15分钟,逾期自动取消 ✨ 额外信息:可带儿童,门店提供免费宝宝椅

    • 失败返回示例:

      ❌ 预订失败:「海底捞火锅(中关村店)」3月20日晚上7点的位置已经约满 💡 可选替代方案:当天还有12:00、18:00、20:30三个时段有空位,需要我帮你预约其他时段吗?

三、查询外呼任务状态流程

阶段1:根据用户问题中的JobId,查询当前Session中的外呼任务状态

  1. 到当前阶段,就可以以比较友好的方式,从Session中查询指定的JobId关联的任务状态,整理为自然语言,告知用户。
  2. 处理异常处理,请检查是否有如下异常 2.1 IF 接口返回ERROR Code不为空,直接将Error.Message字段的错误信息整理为自然语言告知用户,终止流程,不进入阶段3。 2.2 接口返回Status是5,Status定义参考:[JobStatus 枚举说明]。 参考返回样式:
  • 任务提交成功返回示例:

✅ 已为你发起外呼任务「海底捞火锅(中关村店)」,任务完成后会通知你! 📋 任务ID:{JobId} 📅 时间:3月20日 19:00 👥 人数:4位 📝 预订人:李先生 ⏰ 保留时长:最多保留15分钟,逾期自动取消 ✨ 额外信息:可带儿童,门店提供免费宝宝椅

  • 失败返回示例:

❌ 预订失败:「海底捞火锅(中关村店)」3月20日晚上7点的位置已经约满 💡 可选替代方案:当天还有12:00、18:00、20:30三个时段有空位,需要我帮你预约其他时段吗?


配置说明

使用前需要配置以下环境变量,可通过openclaw config set skills.entries.arkclaw-outbound-call.config.XXX "值"命令配置:

环境变量名 说明 示例值
VOLC_ACCESS_KEY 火山引擎Access Key AKLTAxxxxxxxxxxxxxxxx
VOLC_SECRET_KEY 火山引擎Secret Key xxxxxxxxxxxxxxxxxxxxxxxx

使用示例

示例1:完整信息直接执行

用户输入:帮我预约明天晚上7点的木北造型剪发,他们电话是13800138000,3个人,我姓王,联系电话13512345678

技能响应:好的,马上帮你联系木北造型预约,完成后第一时间告诉你结果~

最终返回:✅ 预约成功!已为你预约木北造型明天19:00的剪发服务,3位,预订人王先生,到店报手机号13512345678即可。

示例2:缺失信息自动追问

用户输入:帮我取消明天的海底捞预订

技能响应:请问海底捞的门店电话是多少?预订时预留的姓氏和联系电话是什么呢?

用户补全:电话是13500015678,我姓李,预留电话是13512345678

技能响应:好的,马上帮你取消~

最终返回:✅ 已成功取消你3月20日在海底捞的预订。

示例3:超出范围拒绝

用户输入:帮我给领导打个电话请假

技能响应:抱歉哦,我目前只支持生活服务类门店的预约、改订、取消类外呼任务,其他类型的通话需求暂时无法帮你处理~


错误处理

错误场景 处理逻辑 返回示例
商户电话无效/空号 直接返回失败,提示用户核对号码 ❌ 拨打失败,你提供的门店电话135xxxxxxx是空号,请核对后重新提交
多次拨打未接通/无人接听 最多重试2次,仍未接通则返回失败 ❌ 连续3次拨打门店电话无人接听,请稍后再尝试,或者你可以手动拨打确认
外呼接口调用失败 提取接口返回的msg信息整理后返回 ❌ 外呼服务暂时不可用:接口返回「余额不足」,请充值后再试
非工作时间外呼 默认仅在9:00-21:00发起外呼,其他时间提示用户 当前为非商户营业高峰时段,为避免打扰商户,我将在明天9:00自动帮你拨打,可以吗?
任务提交异常 直接返回接口错误信息 ❌ 任务提交失败:接口返回「剧本ID不存在」,请检查配置是否正确

注意事项

  1. 外呼默认仅在每日9:00-21:00发起,避免打扰商户正常营业
  2. 请确保提供的门店电话真实有效,否则会导致外呼失败
  3. 涉及押金支付的场景会先经过用户二次确认,不会自动扣款
  4. 外呼通话录音会自动保存7天,可在火山引擎后台查看回放
  5. 任务执行全程异步,用户无需等待,完成后会主动推送结果
  6. {baseDir}变量是当前SKILL的根目录

JobStatus 枚举说明

枚举值 含义 说明
1 Waiting 等待呼叫。Job 已提交,正在排队等待系统发起呼叫。
2 Running 呼叫中或等待重呼。系统正在进行呼叫,或者当前轮次呼叫失败后,正在等待下一个重呼周期的到来。
3 CallFinished 呼叫结束。所有预定的呼叫(包括重呼)均已执行完毕,但 Job 的最终数据仍在处理中。
4 JobFinished Job 结束。Job 已彻底完成,此时可以通过 QueryJobDetail 接口查询到完整的呼叫结果,如通话详情、定级信息等。
5 NoExist Job 不存在