在 Assist 卫星上提问并匹配语音回答:Home Assistantassist_satellite.ask_question动作完全指南
【免费下载链接】home-assistant.io:blue_book: Home Assistant User documentation项目地址: https://gitcode.com/GitHub_Trending/ho/home-assistant.io
assist_satellite.ask_question是 Home Assistant 面向 Assist 卫星(satellite)提供的一个问答式语音动作:它让卫星用文本转语音(TTS)把一个问题读出来,随后用语音转文本(STT)把用户的回答转录成文字,再与预设的候选答案进行句子模板匹配,最终把匹配结果通过响应变量交回自动化或脚本继续处理。本篇指南以仓库中的动作文档 source/_actions/assist_satellite.ask_question.markdown 为主体,结合 assist_satellite 集成文档、本地语音助手配置指南 以及相邻动作/触发器文档,完整讲解该动作的 UI 配置、YAML 参数、句子模板语法、响应数据结构与实战组合用法。
动作定位:一问一答的语音交互原语
assist_satellite.ask_question属于assist_satellite集成(集成文档)。该集成是 Home Assistant 中“远程卫星(remote satellites)”的统一表示层,让其他集成(如 ESPHome、Wyoming 语音设备)以一致的实体形态呈现卫星,并在自动化体系中提供动作(actions)、触发器(triggers)与条件(conditions)。根据集成文档,它属于内部质量等级的实体类集成(ha_integration_type: entity、ha_quality_scale: internal),核心职责是“让卫星通过 Assist 控制并与 Home Assistant 交互”。
在assist_satellite的三个动作中,ask_question是唯一具备双向交互语义的动作:
| 动作 | 核心语义 | 目标方式 |
|---|---|---|
assist_satellite.announce | 单向播报消息(文档) | 支持 targets |
assist_satellite.start_conversation | 播报开场白后持续监听多条语音指令(文档) | 支持 targets |
assist_satellite.ask_question | 提出一个问题、监听一次回答并匹配候选答案 | 仅接受entity_id(不支持 targets) |
一句话概括使用场景:自动化或脚本需要“主动向用户提问,并根据用户的语音回答决定下一步动作”时,使用本动作。例如询问“今天想听什么音乐?”,根据用户回答的“爵士”或“摇滚”播放对应歌单。
工作原理:从文本问题到答案匹配的完整链路
根据动作文档,ask_question的完整链路如下:
- 提问:将
question文本交给卫星所配置 pipeline 中的**文本转语音(TTS)**系统(如本地 Piper)合成音频并播放;也可以改用question_media_id直接播放自定义音频,完全绕开 TTS。 - 播报提示音:默认在提问前播放一声提示音(chime),提示用户即将有提问;可通过
preannounce关闭或通过preannounce_media_id换用自定义音效。 - 监听回答:卫星打开麦克风,采集用户的语音回答。
- 转录:回答的语音经由同一 pipeline 中的**语音转文本(STT)**系统(如本地 Whisper 或 Speech-to-Phrase)转录为文本。
- 匹配:将转录文本与
answers中定义的候选答案句子模板逐一匹配;命中后返回对应的id,未命中则id为空。 - 返回:匹配结果(
id、转录文本sentence、通配符捕获的slots)写入response_variable指定的响应变量,供自动化/脚本后续引用。
因此,该动作实际同时依赖 STT 与 TTS 两大能力。在 本地语音助手配置指南 中可以看到完整 pipeline 的组成方式:STT 可选 Speech-to-Phrase(闭集、极快,适合纯家居控制)或 Whisper(开放集、较慢但覆盖面广),TTS 官方推荐本地 Piper;三者均通过 Wyoming 集成 自动发现并接入。
前置条件
使用本动作前需要满足:
- 存在一个可用的Assist 卫星实体(如
assist_satellite.kitchen),来源可以是 ESPHome 卫星、Wyoming 设备或支持该集成的其他硬件; - 该卫星已关联一个配置完整的 Assist pipeline,其中至少包含 STT 与 TTS 组件(否则“读问题”或“听回答”环节无法工作);
- 卫星处于可用状态(
Unavailable/Unknown状态的卫星在触发器与条件的多目标评估中会被跳过,见 assist_satellite.started_responding 触发器文档 的说明)。
通过 UI 使用该动作
如果习惯在界面中可视化搭建,可按以下步骤操作(对应动作文档中的 UI 步骤):
- 进入Settings(设置) > Automations & scenes(自动化与场景);
- 打开一个现有自动化或脚本,或选择Create automation > Create new automation;
- 新建自动化时,在When(当…时)区域添加触发器;脚本无需触发器,由其他调用方触发;
- 在Then do(然后执行)区域选择Add action(添加动作);
- 搜索并选择Ask question on satellite(在卫星上提问);
- 在Entity(实体)字段选择要提问的卫星,设置Question(问题),并添加可能的Answers(答案);
- 点击Save(保存)。
需要特别注意的是:该动作不支持 targets。在 UI 中必须在Entity字段中显式选定卫星,这与assist_satellite.announce、assist_satellite.start_conversation(两者都通过“按目标选择”的方式工作)不同。
UI 中的可配置选项包括:
| UI 选项 | 说明 | 必填 |
|---|---|---|
| Entity | 接受提问的 Assist 卫星 | 是 |
| Question | 要提出的问题,卫星通过 TTS 朗读 | 否 |
| Question media ID | 代替 TTS 文本问题的媒体 ID | 否 |
| Answers | 用于匹配回答的候选答案,每个答案含一个 ID 与一组句子模板 | 否 |
| Preannounce | 提问前播放提示音,默认开启 | 否 |
| Preannounce media ID | 提问前播放自定义音频,代替默认提示音 | 否 |
YAML 中的完整用法
在 YAML 中直接调用该动作时,动作名为assist_satellite.ask_question,卫星以entity_id传入,结果存入响应变量。动作文档给出的标准示例:
action: assist_satellite.ask_question data: entity_id: assist_satellite.kitchen question: What kind of music would you like to listen to? answers: - id: jazz sentences: - "[some] jazz [music] [please]" - something spicy - id: rock sentences: - "[some] rock [music] [please]" - something with a beat response_variable: answer该示例在assist_satellite.kitchen上提问,并把匹配到的答案写入answer响应变量。可以看到:
answers是列表,每个条目由id(唯一标识,匹配成功时原样返回)与sentences(候选句子模板列表)构成;- 句子模板支持可选项语法,如
[some]表示“some”可出现可不出现,[please]同理,因此“some jazz music please”“jazz”“jazz music”等说法都能命中jazz这个答案。
参数速查表(YAML)
依据动作文档中的 YAML 选项定义:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
entity_id | string | 是 | — | 接受提问的 Assist 卫星实体 |
question | string | 否 | — | 要提问的文本,卫星用 TTS 朗读 |
question_media_id | string | 否 | — | 代替 TTS 文本的媒体 ID |
answers | list | 否 | — | 候选答案列表,每项含id与sentences |
preannounce | boolean | 否 | true | 提问前是否播放提示音 |
preannounce_media_id | string | 否 | — | 播放自定义提示音,代替默认 chime |
完整自动化示例:根据语音回答播放音乐
将上述动作嵌入自动化,即可实现完整的“提问 → 分支决策”流程(字段均来自动作文档,这里给出可直接落地的骨架):
automation: alias: "Ask what music to play in the kitchen" triggers: - trigger: state entity_id: binary_sensor.kitchen_motion to: "on" actions: - action: assist_satellite.ask_question data: entity_id: assist_satellite.kitchen question: What kind of music would you like to listen to? answers: - id: jazz sentences: - "[some] jazz [music] [please]" - something spicy - id: rock sentences: - "[some] rock [music] [please]" - something with a beat response_variable: answer - if: - condition: template value_template: "{{ answer.id == 'jazz' }}" then: - action: media_player.play_media target: entity_id: media_player.kitchen_speaker data: media_content_id: "spotify:playlist:37i9dQZF1DX1vNYllC7M7v" media_content_type: playlist else: - action: media_player.play_media target: entity_id: media_player.kitchen_speaker data: media_content_id: "spotify:playlist:37i9dQZF1DXcBWIGoYBM5M" media_content_type: playlist当用户没有回答、或回答无法匹配任何候选答案时,answer.id为空字符串,此时将走else分支。
answers结构与句子模板语法
答案条目结构
answers列表中的每个条目包含两个字段:
id:答案的唯一标识;当用户的回答与对应句子模板匹配时,该id会出现在响应变量中;sentences:用于匹配回答的句子模板列表,任意一条命中即视为该答案被选中。
句子模板语法
句子模板使用与 Home Assistant 意图识别(intent recognition)一致的模板句法,支持两类关键语法:
- 方括号可选词
[word]:表示该词可以出现也可以不出现。例如"[some] jazz [music] [please]"可以同时匹配 “jazz”“some jazz”“jazz music please” 等说法; - 花括号通配符
{slot}:捕获回答中的任意片段,捕获值会存入响应变量的slots字段。动作文档给出的例子:模板play {album} by {artist}可以匹配 “play the white album by the beatles”,并把slots.album设为the white album、slots.artist设为the beatles。
这一语法在仓库的 自定义句子配置文档 中有更系统的体现——自定义意图同样通过sentences模板定义,并在lists中声明{slot}的取值来源(in为语音输入说法、out为映射输出值):
# 示例:config/custom_sentences/en/media.yaml language: "en" intents: SetVolume: data: - sentences: - "(set|change) {media_player} volume to {volume} [percent]" lists: media_player: values: - in: "living room" out: "media_player.living_room" volume: range: from: 0 to: 100这说明ask_question的句子模板与整个 Home Assistant 语音生态(自定义句子、句子触发器、意图脚本)共用同一套模板语法,熟悉其一即可触类旁通。
响应数据:如何在自动化中消费结果
动作执行后,匹配结果写入response_variable指定的变量,包含三个字段:
id:命中的答案 ID;没有任何答案匹配时为空字符串;sentence:用户回答的转录文本(STT 输出),无论是否匹配成功都会返回;slots:被匹配句子中通配符{slot}捕获的值。
特别地,动作文档明确指出:如果省略answers,动作不会尝试任何匹配,转录文本直接通过sentence字段返回。这意味着该动作也可以单纯当作“语音输入采集器”使用——例如让用户口述一段自由文本,而无需预设候选答案。
基于slots的消费示例(使用模板句法捕获具体内容):
action: assist_satellite.ask_question data: entity_id: assist_satellite.kitchen question: Which room should I clean? answers: - id: room sentences: - "the {room}" response_variable: answer # 之后可通过 {{ answer.slots.room }} 拿到用户说出的房间名Good to know:默认行为与常见坑
动作文档在结尾给出了两条关键注意事项:
- 默认提示音:提问前默认会播放一声 chime。若想使用自己的提示音,设置
preannounce_media_id;若想完全静默,将preannounce设为false。这一行为与assist_satellite.announce、assist_satellite.start_conversation保持一致。 - 目标是
entity_id而非 targets:绝大多数动作通过target指定目标实体,而本动作必须把卫星放在entity_id字段中(UI 中即 Entity 字段)。编写 YAML 时不要把卫星误写到target下。
与触发器、条件的组合实战
ask_question适合与assist_satellite域的触发器和条件搭配,构建更精细的语音交互体验:
- 触发器
assist_satellite.started_responding(文档):卫星开始播放 TTS 回答时触发。可以在提问被朗读时自动调暗灯光、暂停背景音乐,或点亮 LED 环提示“助手正在说话”; - 触发器
assist_satellite.started_listening/started_processing/idle(文档目录 等):分别对应卫星开始聆听、开始处理、恢复空闲的时机; - 条件
assist_satellite.is_listening(文档):判断卫星当前是否正在捕捉语音。例如“媒体开始播放时,仅当同房间卫星正在聆听才暂停媒体”,避免打断用户与语音助手的交互。
示例:卫星回答期间降低音乐音量
从 started_responding 触发器文档 中可以直接看到这类组合的标准写法——卫星开始播放回答时把同房间扬声器音量降至 20%,避免 TTS 需要提高音量与背景音乐“抢话”:
automation: alias: "Lower music volume while satellite responds" triggers: - trigger: assist_satellite.started_responding target: entity_id: assist_satellite.living_room actions: - action: media_player.volume_set target: entity_id: media_player.living_room_speaker data: volume_level: 0.2相关动作速览
ask_question与另外两个assist_satellite动作互补(前文已有对比表,此处给出 YAML 骨架以便对照):
Announce on satellite(
assist_satellite.announce):单向播报,支持 targets,可播文本(TTS)或媒体 ID。适合“晚饭好了”“洗衣完成”这类无需用户回应的通知场景:action: assist_satellite.announce target: entity_id: assist_satellite.kitchen data: message: Dinner is ready!Start conversation on satellite(
assist_satellite.start_conversation):播报开场白后持续监听多条语音指令,可将上下文(extra_system_prompt)传给对话代理(如 OpenAI、Google Generative AI)。适合“卧室灯还亮着,要关掉吗?”这类需要连续多轮交流的场景(注意内置 Assist 对话代理暂不支持多轮对话):action: assist_satellite.start_conversation target: entity_id: assist_satellite.living_room data: start_message: You left the lights on in the living room. Turn them off? extra_system_prompt: >- The user left the lights on in the living room and is being asked whether to turn them off.
三者的选型原则可以概括为:只需告知就announce;只需一个问题的答案是ask_question;需要用户连续下达指令则start_conversation。
故障排查与进一步帮助
若动作未按预期工作,建议按以下顺序排查:
- 确认卫星实体存在且可用(查看Settings > Devices & services中
assist_satellite集成下的实体状态); - 确认卫星关联的 pipeline 中 STT 与 TTS 均已配置且工作正常(可先在语音助手界面手动测试一轮对话);
- 检查
entity_id是否正确写入(该动作不使用target); - 检查
answers的句子模板是否覆盖了用户可能的实际说法——模板过窄是“匹配不到答案”最常见的原因; - 借助
sentence字段查看实际转录文本,确认 STT 转写是否准确。
仓库中的动作文档还在 source/_includes/actions/stuck.md 中提示:遇到问题可加入 Home Assistant 社区(Discord、官方论坛或 Reddit),发帖时附上正在调用的动作与预期行为,能更快获得帮助;也可以向 AI 助手用自然语言描述需求,由它帮助解释或推荐合适的动作。
【免费下载链接】home-assistant.io:blue_book: Home Assistant User documentation项目地址: https://gitcode.com/GitHub_Trending/ho/home-assistant.io
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考