1. はじめに
この記事は 構築編 の続編で、システムの技術的な背景と設計上の判断をまとめている。環境構築の手順については構築編を参照してほしい。
扱う内容は以下のとおり。
- 2. 構成要素の解説 — 技術スタック・リクエストフロー・ファイル構成・主要な設計ポイント
- 3. 比較検討したこと — Cloudflare Workers を採用した理由・実装言語の選定・セキュリティ手法の比較
- 4. 参考 — 参考リンク
2. 構成要素の解説
2-1. 技術スタック
| コンポーネント | 技術・サービス | 役割 |
|---|---|---|
| 音声 I/F | Amazon Echo / Alexa Skills Kit | 音声入出力・カスタムスキル管理 |
| バックエンド | Cloudflare Workers | Alexa からのリクエストを受ける HTTPS エンドポイント |
| 実装言語 | TypeScript | Workers のコード記述(V8 ネイティブ実行) |
| 開発・デプロイ | Wrangler CLI | ローカル開発・デプロイ・シークレット管理 |
| AI | Anthropic API (Claude Haiku) | 自然言語での質問応答を生成 |
2-2. リクエストフロー
図中の TTS Conversion (Text-to-Speech) は、Alexa Skills Kit がテキスト形式のレスポンスを受け取り、Echo デバイスが再生できる音声データに変換するステップ。ユーザーが Echo から聞く読み上げ音声はここで生成される。
2-3. ファイル構成
alexa-claude/
└── worker/
└── alexa-claude-worker/
├── src/
│ └── index.ts ← Worker のメインコード
├── wrangler.jsonc ← Wrangler 設定(ALEXA_APP_ID を記入する)
├── tsconfig.json
├── worker-configuration.d.ts
├── package.json
├── .dev.vars ← ローカル用シークレット(git 除外)
└── .gitignore
2-4. 主要な設計ポイント
Alexa の 8 秒タイムアウト対策
Alexa はエンドポイントから 8 秒以内にレスポンスが返らない場合、タイムアウトエラーをユーザーに返す。Anthropic API の応答は通常 2〜5 秒だが、余裕を持たせるために 6 秒でキャンセルし、残り 2 秒でエラーメッセージを返す設計にしている。
Alexa Skills Kit のドキュメントには「8 秒以内に応答しなければならない」と明記されているが、なぜ 8 秒なのかという設計根拠を Amazon が公式に説明した資料は見当たらない。
断片的な情報として、Amazon 自身の開発者向けドキュメントには「ユーザーは 2 秒未満のレスポンスを期待している」という記述がある(参考)。8 秒はあくまで上限であって、Amazon にとっても目標値ではないようだ。
UX 分野では「応答が 10 秒を超えるとユーザーの集中が途切れる」という知見(NN/g)が古くから知られており、8 秒はそのギリギリ内側に収まる数字ではある。しかしこれが Alexa の設計に影響したかどうかは確認できていない。
公式な根拠は見つけられなかったが、現場の開発者からは「IoT 用途では 8 秒では足りない」という要望が継続的に上がっており(UserVoice)、この制限が開発上の実質的な壁になっていることは確かだ。
Cloudflare Workers 無料枠と CPU 時間
Workers の無料枠は 1 リクエストあたり CPU 時間 10ms という制限があるが、fetch() による外部 API 呼び出しの待機時間(I/O)は CPU 時間にカウントされない。このシステムの実質的な CPU 使用は JSON の解析と組み立てのみで、1 リクエストあたり約 1ms 以下に収まる。
セキュリティ
開発者モード(自分のみ利用)かつ URL を公開しない前提で、以下の 2 層を実装している。
| 検証 | 内容 |
|---|---|
| アプリケーション ID 検証 | ALEXA_APP_ID と一致するか確認 |
| タイムスタンプ検証 | 150 秒以内のリクエストのみ受け付ける |
会話履歴の保持
直近 5 往復(10 メッセージ)を Alexa セッションの属性(SessionAttributes)に保持し、Anthropic API へのリクエストに含めて渡す。セッションを終了すると履歴はリセットされる。
3. 比較検討したこと
3-1. Alexa-hosted ではなく Cloudflare Workers を採用した理由
Alexa カスタムスキルのバックエンドは、Amazon が管理する Alexa-hosted (Node.js) と、自分で用意する カスタムエンドポイント(Lambda・Cloudflare Workers など)の2種類から選べる。Alexa Developer Console では Alexa-hosted の導入が手軽だが、今回はコールドスタートの問題から採用しなかった。以下に比較をまとめる。
| Alexa-hosted (Node.js) | Cloudflare Workers | |
|---|---|---|
| 動作環境 | Amazon 管理の AWS Lambda | V8 アイソレート |
| セットアップ | 不要(Console のみ) | Wrangler + アカウント設定が必要 |
| コールドスタート | 1〜3 秒 | 約 5ms(概念なし) |
| 個人利用時の起動頻度 | 低頻度 → アイドル状態になりやすい | 常時ウォーム |
| Claude API 応答(2〜5 秒)との合算 | 8 秒制限を超えるリスクあり | 余裕あり |
| 結果 | 不採用 | 採用 |
3-2. Cloudflare Workers の実装言語の選定
Cloudflare Workers は複数の言語をサポートしているが、TypeScript(JavaScript)を採用した。
| 言語 | 実行方式 | コールドスタート | I/O 処理 | 評価 |
|---|---|---|---|---|
| TypeScript | V8 ネイティブ | 約 5ms | 最小 | 採用 |
| Rust / Go / C | WASM | 5〜50ms | 中(マーシャリング) | 不適 |
| Python (Pyodide) | WASM | 1 秒以上 | 高 | 不適 |
Python は Pyodide の初期化だけで 1 秒以上かかり、Alexa の 8 秒制限に対して現実的でない。Rust・Go などの WASM 言語は V8 環境とのメモリ空間が分離されているため、マーシャリングが発生し、今回のような I/O 中心のワークロードでは逆に遅くなる。
3-3. セキュリティ手法の比較
今回のスキルの実装では Cloudflare Workers の *.workers.dev ドメインにデプロイしている。
<スクリプト名>.<アカウント名>.workers.dev という形式の URL が自動で割り当てられる。独自ドメインを持っていなくても即座に HTTPS エンドポイントとして使うことができる。ただし、Cloudflare の一部機能は独自ドメインでしか使えない。今回はドメイン取得・維持費用を発生させずに動作させることを目標としているため、独自ドメインの取得が前提となる手法は除外している。その条件のもとで適用できる追加のセキュリティ手法を検討した。
| 手法 | 効果 | 欠点 | 結果 |
|---|---|---|---|
| Cloudflare WAF(ASN フィルター) | URL 漏洩を実質無効化 | 独自ドメインが必要。*.workers.dev には不可 |
不採用 |
| Cloudflare Rate Limiting | クレジット過剰消費を防止 | 独自ドメインが必要。*.workers.dev には不可 |
不採用 |
| Alexa リクエスト署名検証 | Amazon からのリクエストを暗号学的に証明 | 実装コスト高・レイテンシへの影響あり | 不採用 |
いずれも今回の環境・用途には合わず不採用とした。個人・非公開利用であれば、2-4 節で実装したアプリケーション ID + タイムスタンプ検証の2層で十分な防御が得られる。
独自ドメインを Cloudflare で管理している場合は、WAF・Rate Limiting をダッシュボードから追加してセキュリティをさらに強化できる。