すべての Home Assistant 音声コマンドをカスタムエージェントにルーティングする

すべての音声コマンドを、独自のカスタムエージェントに送信したいと考えているかもしれません。それはローカルLLMであったり、MCPをサポートするアシスタントであったりするでしょう。

Home Assistant 2026.5 以降では、従来の方法ではこれが機能しません。

オートメーションで単なるワイルドカードを使用すると、HTTP 500 エラーが発生します。このエラーは、システムが存在しないリストを探そうとするために発生します。

エラーを回避できたとしても、組み込みコマンドがクエリを横取りしてしまいます。例えば、「次の引き潮はいつ?」と尋ねた際、Home Assistant が代わりに次の曲を再生しようとする可能性があります。

これら両方の問題を解決する方法を以下に示します。

問題点

  1. MissingListError: オートメーションで {text} を使用すると、Home Assistant は "text" という名前の登録済みリストを期待します。オートメーション内でリストを定義することはできないため、システムがクラッシュします。

  2. インテントの横取り (Intent Hijacking): 「turn on」や「play next」といった組み込みコマンドが、カスタムエージェントが処理する前にあなたの言葉に一致してしまいます。

解決策

キャッチオール(すべてを拾う)ロジックをオートメーションからカスタムセンテンス(custom sentences)に移動させる必要があります。これにより、実際のワイルドカードを定義でき、コマンドが最初に読み込まれることが保証されます。

ステップ 1: カスタムセンテンスを作成する

custom_sentences フォルダ内にファイルを作成します。これにより、実際のワイルドカードリストが登録されます。

language: "en"
intents:
  NaturaliQuery:
    data:
      - sentences:
          - "{text}"
lists:
  text:
    wildcard: true

ステップ 2: intent_script を使用する

オートメーションの代わりに、configuration.yamlintent_script を使用します。これにより、レスポンスが処理され、音声パイプラインがスムーズに維持されます。

intent_script:
  NaturaliQuery:
    speech:
      text: "One moment."
    action:
      - action: mqtt.publish
        data:
          topic: my/agent/ask
          payload: '{"text": "{{ text }}"}'

なぜこれで解決するのか

• ワイルドカードリストを使用することで、HTTP 500 エラーを防ぐことができます。 • カスタムセンテンスは組み込みインテントよりも先に読み込まれます。そのため、エージェントが最初にコマンドをキャッチできます。 • intent_script を使用することで、多くのハードウェアサテライトにおける音声のデッドロックを回避できます。

注意: 全てを対象とするワイルドカードは、「turn on the lights」などのコマンドまでキャッチしてしまいます。ネイティブの制御を維持したい場合は、カスタムセンテンスにプレフィックス(接頭辞)を追加し、意図したときだけトリガーされるようにしてください。

Source: https://dev.to/clarkbw--/route-all-home-assistant-voice-to-a-custom-agent-with-a-wildcard-sentence-4iee

Optional learning community: https://t.me/GyaanSetuAi