You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将自定义间隔计数Python脚本集成到Alexa技能代码库

Alexa间隔计数技能Python集成方案

核心前提说明

你原本写的time.sleep()阻塞循环写法完全无法直接在Alexa Lambda环境运行:Alexa单次Lambda请求最长超时仅8秒,不可能挂起进程等几十秒逐个数数;且Alexa不会读取控制台print()内容作为语音输出,所有语音反馈都需要通过符合规范的响应结构返回。

第一步:先配置技能交互模型

  • 新建自定义Alexa技能,调用名设置为「间隔计数器」即可
  • 新建自定义意图CountIntent,绑定两个必填槽位:
    • 槽位endNumber:类型选AMAZON.NUMBER,对应用户要数到的目标值,比如示例指令里的30
    • 槽位intervalSeconds:类型选AMAZON.NUMBER,对应用户要求的计数间隔秒数,比如示例指令里的2
  • 为CountIntent配置样本语句,填入你的示例指令:count to {endNumber} in intervals of {intervalSeconds} seconds
  • 为两个必填槽位配置追问话术,比如没拿到目标值时问「请问你要数到多少?」,没拿到间隔时问「请问每隔几秒数一个数?」,配置后Alexa会自动补全缺失参数,不需要额外写代码
  • 技能权限页开启SSML长内容播报权限,测试阶段不需要额外开其他付费服务

第二步:集成代码到lambda_function.py

Lambda运行环境先配置官方Python SDK依赖ask-sdk-core,直接把下面的核心代码替换默认的lambda_function.py内容即可,已经把计数逻辑和Alexa基础框架做了整合:

import ask_sdk_core.utils as ask_utils
from ask_sdk_core.skill_builder import SkillBuilder
from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_model import Response

# 测试阶段用全局变量存用户计数状态,正式上线建议替换成DynamoDB存储,避免Lambda热启动导致状态串号
user_count_state = {}

class LaunchRequestHandler(AbstractRequestHandler):
    """处理技能启动请求"""
    def can_handle(self, handler_input):
        return ask_utils.is_request_type("LaunchRequest")(handler_input)
    def handle(self, handler_input):
        welcome_text = "欢迎使用间隔计数器,你可以说类似指令:数到30,间隔2秒"
        return (
            handler_input.response_builder
                .speak(welcome_text)
                .ask(welcome_text)
                .response
        )

class CountIntentHandler(AbstractRequestHandler):
    """处理计数启动请求"""
    def can_handle(self, handler_input):
        return ask_utils.is_intent_name("CountIntent")(handler_input)
    def handle(self, handler_input):
        slots = handler_input.request_envelope.request.intent.slots
        # 读取用户传入的两个参数
        target_num = int(slots["endNumber"].value)
        interval_sec = int(slots["intervalSeconds"].value)
        # 基础参数校验,避免用户输入超出合理范围的数值
        if target_num < 1 or target_num > 100:
            return handler_input.response_builder.speak("目标数值请设置在1到100之间").response
        if interval_sec < 1 or interval_sec > 10:
            return handler_input.response_builder.speak("间隔秒数请设置在1到10秒之间").response
        # 初始化当前用户的计数状态
        user_id = handler_input.request_envelope.context.system.user.user_id
        user_count_state[user_id] = {
            "current": 1,
            "target": target_num,
            "interval": interval_sec
        }
        # 用SSML的break标签实现间隔停顿,不需要sleep阻塞进程
        def build_count_ssml():
            state = user_count_state[user_id]
            if state["current"] > state["target"]:
                return "计数完成。"
            cur_num = state["current"]
            state["current"] += 1
            # 每播报一个数字,停顿对应间隔秒数,再接下一个数字的播报
            return f"{cur_num}<break time='{state['interval']}s'/>{build_count_ssml()}"
        
        return (
            handler_input.response_builder
                .speak(f"<speak>{build_count_ssml()}</speak>")
                .response
        )

class CancelOrStopIntentHandler(AbstractRequestHandler):
    """处理停止、取消指令"""
    def can_handle(self, handler_input):
        return (ask_utils.is_intent_name("AMAZON.CancelIntent")(handler_input) or
                ask_utils.is_intent_name("AMAZON.StopIntent")(handler_input))
    def handle(self, handler_input):
        # 清空当前用户的计数状态
        user_id = handler_input.request_envelope.context.system.user.user_id
        if user_id in user_count_state:
            del user_count_state[user_id]
        return handler_input.response_builder.speak("已停止计数。").response

# 注册所有处理器,生成Lambda入口函数
sb = SkillBuilder()
sb.add_request_handler(LaunchRequestHandler())
sb.add_request_handler(CountIntentHandler())
sb.add_request_handler(CancelOrStopIntentHandler())
lambda_handler = sb.lambda_handler()

关键注意事项

  • 不要用time.sleep()实现间隔:SSML的<break>标签是Alexa原生支持的停顿能力,停顿计时在Alexa端完成,完全不占用Lambda运行时长,不会触发8秒超时
  • 不要用print()输出语音内容:所有要播报的内容都要通过response_builder的speak方法传入,支持纯文本和SSML格式
  • 单次SSML播报总时长不能超过240秒,如果要实现更长时间的计数,可以把长内容拆成多段,用AudioPlayer接口逐段推入播放队列即可,普通测试场景上面的递归生成SSML的方案完全够用
  • 正式上线前把全局变量存储的用户状态替换成DynamoDB存储,避免Lambda热启动时多个用户的计数状态串号

内容的提问来源于stack exchange,提问作者thentangler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 05:09:15