HyperGen

エージェント作成ガイドライン

AIエージェントがHyperGen互換HTMLフラグメントを生成するためのベストプラクティス: HTMX属性、CSSテーマ、自己完結性、アクセシビリティ。

本セクションでは、HyperGen用のHTMLフラグメントを生成するAIエージェント(または任意のシステム)向けのガイドラインを提供します。サンドボックス化されたiframeで正しくレンダリングされ、ホストアプリケーションとうまく統合されるHTMLを生成するための推奨事項です。

フラグメントの自己完結性

SSE経由で配信される各HTMLフラグメントは自己完結すべきです (SHOULD) — 以前に配信されたフラグメントに依存せず、正しくレンダリングするために必要なすべてのマークアップ、スタイル、動作を含むべきです。

自己完結性が重要な理由

  • SSEイベントは再接続後に順序が入れ替わる可能性がある。
  • HTMXのスワップ戦略(innerHTMLouterHTML)はサブツリー全体を置換する可能性がある。
  • 新しいフラグメントのストリーミング中にユーザーがUIを操作する可能性がある。

実際に自己完結が意味すること

  • フラグメントが新しいCSSクラスを導入する場合、フラグメント内またはその隣に<style>ブロックを含める。
  • スコープされたクラス名を使用(.cardではなく.hg-weather-cardなど)して、他のフラグメントとの衝突を回避。
  • フラグメントが特定のDOM構造に依存する場合、フラグメント自身が作成するIDを持つhx-targetを使用。
<!-- 独自のスタイルを持つ自己完結フラグメント -->
<style>
  .hg-weather-card {
    background: var(--hg-surface-elevated, #f9fafb);
    border: 1px solid var(--hg-border, #e5e7eb);
    border-radius: var(--hg-radius, 8px);
    padding: var(--hg-space-4, 16px);
  }
</style>
<div class="hg-weather-card">
  <h2>Weather in Tokyo</h2>
  <p>18°C, partly cloudy</p>
  <div id="weather-detail"></div>
  <button hx-get="/api/agent/weather/detail"
          hx-target="#weather-detail"
          hx-swap="innerHTML">
    Show Forecast
  </button>
</div>

HTMX属性の使用

エージェントはHTML内に標準HTMX属性を含めることでインタラクティビティを生成します。カスタム属性や拡張は不要です(ADR-005参照)。

よく使用される属性

属性用途
hx-getユーザーアクションでコンテンツを取得hx-get="/api/agent/detail"
hx-postエージェントにデータを送信hx-post="/api/agent/action"
hx-targetレスポンスの配置先hx-target="#result"
hx-swapレスポンスの挿入方法hx-swap="innerHTML"またはhx-swap="outerHTML"
hx-triggerリクエスト送信のタイミングhx-trigger="click"またはhx-trigger="submit"
hx-vals含める追加データhx-vals='{"action":"approve","id":42}'
hx-indicatorローディング要素を表示hx-indicator="#spinner"
hx-confirm確認を要求hx-confirm="Delete this item?"

スワップ戦略

インタラクションパターンに基づいてスワップ戦略を選択:

戦略使用タイミング
innerHTMLターゲット内のコンテンツを置換し、ターゲット要素自体は保持。ほとんどの場合のデフォルト。
outerHTMLターゲット要素全体を置換。レスポンスが現在のコンポーネントの完全な置換の場合に使用。
beforeendターゲットに追加。チャットメッセージ、ログエントリ、リストアイテムに使用。
afterendターゲット要素の後に挿入。兄弟コンテンツの追加に使用。
noneスワップしない。リクエストが可視UIを変更せずに副作用(例: hg:dataイベント)をトリガーする場合に使用。

ターゲティングパターン

<!-- IDでターゲット -->
<button hx-get="/api/data" hx-target="#output">Load</button>
<div id="output"></div>

<!-- トリガー要素からの相対ターゲット -->
<div class="card">
  <button hx-post="/api/update"
          hx-target="closest .card"
          hx-swap="outerHTML">
    Update Card
  </button>
</div>

<!-- 要素自体をターゲット(デフォルト動作) -->
<div hx-get="/api/refresh" hx-trigger="every 30s" hx-swap="innerHTML">
  Auto-refreshing content
</div>

コンテキストデータの送信

hx-valsを使用してエージェントサーバーにコンテキストを渡す:

<button hx-post="/api/agent/action"
        hx-vals='{"action":"analyze","dataset":"sales_q4","format":"chart"}'
        hx-target="#result"
        hx-swap="innerHTML">
  Analyze Sales Data
</button>

フォームの場合、HTMXは自動的にすべてのフォームフィールド値を含めます。標準フォーム送信にhx-valsは不要です:

<form hx-post="/api/agent/query" hx-target="#result" hx-swap="innerHTML">
  <input type="text" name="query" placeholder="Ask anything..." />
  <select name="model">
    <option value="fast">Fast</option>
    <option value="thorough">Thorough</option>
  </select>
  <button type="submit">Ask</button>
</form>
<div id="result"></div>

CSSスタイリングのベストプラクティス

--hg-*変数を使用

ホストのデザインシステムに合わせるべきすべての視覚プロパティは、フォールバック値付きの--hg-*変数を参照しなければなりません (MUST)。完全な変数リストはCSS変数テーマを参照。

/* 良い例: フォールバック付きテーマ変数を使用 */
.my-component {
  background: var(--hg-surface, #ffffff);
  color: var(--hg-text, #111827);
  border: 1px solid var(--hg-border, #e5e7eb);
}

/* 悪い例: ホストテーマに合わないハードコードされた色 */
.my-component {
  background: #ffffff;
  color: #333333;
  border: 1px solid #ccc;
}

固定寸法を避ける

フラグメントは任意の幅のiframe内にレンダリングされます。レスポンシブ手法を使用:

/* 良い例: レスポンシブ */
.chart-container {
  width: 100%;
  max-width: 600px;
  aspect-ratio: 16 / 9;
}

/* 悪い例: 固定幅はオーバーフローする可能性 */
.chart-container {
  width: 600px;
  height: 400px;
}

クラス名にプレフィックスを付ける

フラグメント間の衝突を避けるため、CSSクラス名にプレフィックスを付けます。コンポーネントの目的に関連する短いプレフィックスで十分です:

/* このフラグメントにスコープ */
.hg-weather-card { ... }
.hg-weather-temp { ... }
.hg-weather-icon { ... }

インラインスタイルとスタイルブロック

  • 複数のスタイル付き要素を持つフラグメントには<style>ブロックを使用。
  • 単一要素へのワンオフスタイリングにはインラインstyle属性を使用。
  • 外部スタイルシートのロードに<link>を使用すべきではない (SHOULD NOT)(レイテンシが増加し、CSPにブロックされる可能性あり)。

インラインスクリプト

エージェント生成HTMLは、サーバーへのラウンドトリップを必要としないクライアントローカルの動作のためにインライン<script>ブロックを含めてもよいです (MAY)。

インラインスクリプトを使用する場合

  • ローカル計算(スライダー値の表示、ライブ文字数カウントなど)
  • クライアントサイドレンダリング(ブートストラップに読み込まれたチャートライブラリによるチャートなど)
  • アニメーションとビジュアルエフェクト
  • ホストへのhg:dataイベント送信
  • ホストレベルナビゲーション用のhg:navigateトリガー

インラインスクリプトを使用しない場合

  • サーバー通信 — 代わりにHTMX属性(hx-gethx-post)を使用
  • フラグメント間で永続化すべき状態管理 — エージェントサーバーを使用
  • 外部スクリプトの読み込み — CSPがブロックする可能性あり

SSEフラグメント内のスクリプト実行

HTMXが<script>タグを含むHTMLをスワップすると、スクリプトは自動的に実行されます(HTMXがこれを処理します)。エージェントはSSEフラグメントに含まれるスクリプトのこの動作に依存できます。

<div id="chart-container" style="width:100%; height:300px;"></div>
<script>
  // This script runs when HTMX swaps this fragment into the DOM
  var container = document.getElementById('chart-container');
  // ... render a chart using a library loaded in the bootstrap
</script>

ホストへのデータ送信

<button onclick="document.dispatchEvent(new CustomEvent('hg:data', {
  detail: { action: 'selected', itemId: 42 }
}))">
  Select Item
</button>

ホストナビゲーションのトリガー

<a data-hg-navigate="/dashboard" href="#">Go to Dashboard</a>

またはスクリプト経由:

<button onclick="window.parent.postMessage({
  type: 'hg:navigate', url: '/settings'
}, '*')">
  Open Settings
</button>

ローディングインジケーター

HTMXの組み込みインジケーターメカニズムを使用して、エージェントインタラクション中のローディング状態を表示:

<button hx-post="/api/agent/analyze"
        hx-target="#result"
        hx-indicator="#spinner">
  Analyze
</button>
<span id="spinner" class="hg-indicator">Loading...</span>
<div id="result"></div>

ブートストラップドキュメントには、デフォルトで.hg-indicatorを非表示にし、保留中のリクエスト時にHTMXが.htmx-requestクラスを追加した際に表示するCSSが含まれています。

エラーハンドリング

エージェントはHTTPエラーコードに依存するのではなく、ユーザーフレンドリーなエラー状態をHTMLとして生成すべきです (SHOULD):

<div class="hg-error" style="
  background: var(--hg-surface-elevated, #f9fafb);
  border: 1px solid #ef4444;
  border-radius: var(--hg-radius, 8px);
  padding: var(--hg-space-4, 16px);
  color: var(--hg-text, #111827);
">
  <strong>Something went wrong</strong>
  <p style="color: var(--hg-text-muted, #6b7280);">
    Unable to retrieve weather data. Please try again.
  </p>
  <button hx-get="/api/agent/weather"
          hx-target="closest .hg-error"
          hx-swap="outerHTML">
    Retry
  </button>
</div>

SSEストリームエラーの場合、ブートストラップドキュメントの接続状態CSSクラス(hg-connected / hg-disconnected)が自動的な視覚フィードバックを提供します。

アクセシビリティに関する考慮事項

エージェント生成HTMLはWebアクセシビリティのベストプラクティスに従うべきです (SHOULD):

セマンティックHTML

適切なHTML要素をその意図された目的に使用:

<!-- 良い例: セマンティック -->
<nav aria-label="Results navigation">
  <button hx-get="/api/page/1" hx-target="#results">Page 1</button>
  <button hx-get="/api/page/2" hx-target="#results">Page 2</button>
</nav>

<!-- 悪い例: divだらけ -->
<div>
  <div onclick="...">Page 1</div>
  <div onclick="...">Page 2</div>
</div>

ARIA属性

セマンティックHTMLだけでは不十分な場合にARIA属性を追加:

<div role="alert" aria-live="polite">
  Analysis complete: 3 anomalies found.
</div>

<button hx-post="/api/agent/action"
        aria-label="Delete report for Q4 2025"
        hx-confirm="Delete this report?">
  Delete
</button>

キーボードナビゲーション

すべてのインタラクティブ要素がキーボードアクセス可能であることを確認:

  • クリック可能なアクションには<button>を使用(<div onclick>ではなく)。
  • ナビゲーションには<a>を使用(ホストナビゲーションにはdata-hg-navigate付き)。
  • カスタムウィジェットには適切なtabindexrole、キーボードイベントハンドラーを設定。

カラーコントラスト

--hg-*テーマ変数を使用する場合、コントラスト比はホストのテーマに依存します。エージェントは以下をすべきです (SHOULD):

  • --hg-text / --hg-surfaceペアに依存する(ホストが適切なコントラストを担保する責任がある)。
  • --hg-surface背景上のテキスト色として--hg-accentを使用しない(アクセントカラーはサーフェスカラーと十分なコントラストを持たない可能性がある)。
  • --hg-accent背景上のテキストには--hg-accent-fgを使用する。

ライブリージョン

動的に更新されるコンテンツ(ストリーミング結果など)には、ARIAライブリージョンを使用:

<div aria-live="polite" aria-atomic="false">
  <div id="result" hx-swap="innerHTML">
    <!-- ストリーミングコンテンツがここに表示、スクリーンリーダーが更新をアナウンス -->
  </div>
</div>

やるべきこと・やるべきでないことのまとめ

やるべきことやるべきでないこと
テーマ依存のすべてのスタイルに--hg-*変数を使用色、フォント、スペーシングをハードコード
var()フォールバック値を含めるテーマ変数が常に設定されていると仮定
サーバー通信にhx-post/hx-getを使用エージェント通信にfetch()XMLHttpRequestを使用
フラグメントを自己完結させる以前のフラグメントのCSS/JSに依存
セマンティックHTML要素を使用すべてに<div><span>を使用
CSSクラス名にプレフィックスを付ける衝突する可能性のある汎用クラス名を使用
レスポンシブレイアウト(%max-width)を使用固定ピクセル寸法を使用
アクセシビリティのためのARIA属性を含めるキーボードナビゲーションとスクリーンリーダーを無視
エラー状態をHTMLとして生成HTTPステータスコードだけに依存

目次