
ウェブはあまりにも長い間、静的なままでした。シングルページアプリケーション(SPA)や複雑なフロントエンドフレームワークが登場しても、私たちは根本的に20年前と同じ方法でアプリを構築しています。静的なナビゲーションパス、厳格なフォーム、ハードコードされたダッシュボードビューを設計し、ユーザーに私たちの思考モデルを学ばせて目標を達成させているのです。
もしUIがユーザーが実際に達成したいことに動的に適応したらどうでしょうか?データセットをフィルタリングしてチャートをエクスポートするために5つのネストされた画面をクリックする代わりに、ユーザーが自分の意図を表現し、クライアントアプリケーションが彼らが必要とする正確なインタラクティブなワークスペースを動的に組み立てるのです。
インテントベースUI開発(Generative UIとも呼ばれる)というアーキテクチャパラダイムへようこそ。
インテントベースUIとは、ファンクションコールLLMと厳密に型付けされたコンポーネントレジストリによって、ユーザーの即時の目標を自然言語または文脈理解に基づいて動的に解決し、フロントエンドコンポーネントをレンダリングするインターフェースです。
従来のクライアントエンジニアリングでは、アプリケーションはURLパスを静的なビューテンプレートに直接マッピングしていました。
// Traditional Route Mapping
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/analytics/reports/new" element={<CreateReport />} />
<Route path="/settings/billing" element={<BillingSettings />} />
シンプルなCRUDアプリケーションにはクリーンですが、このパターンはシステムがスケールするにつれて深刻な摩擦を引き起こします。
インテントベースUIは、固定されたページナビゲーションをインテント解決パイプラインに置き換えます。クライアントは自然言語または文脈的なジェスチャーを受け取り、LLMを介してそれらを構造化されたインテントペイロードに変換し、検証済みのコンポーネントレジストリに対してそれらのペイロードを解決します。
ユーザーはコマンドパレット(Cmd+K)、会話型入力、または文脈トリガーを通じて目標を表現します。「今月期限切れになるEUのエンタープライズ更新を表示し、延長見積もりを作成できるようにしてほしい。」
軽量な言語モデル(Claude 3.5 HaikuやGPT-4o-miniなど)がプロンプトを解析し、アクション、パラメーター、推奨されるUIウィジェットを含む検証済みのJSONスキーマに変換します。
フロントエンドランタイムは、インテントのアクショントークンを、厳密なコンポーネントマニフェストで宣言された遅延ロードされるReactコンポーネントにマッピングします。
アプリケーションは、組み立てられたウィジェットを柔軟なグリッドワークスペース内にマウントし、異なるコンポーネント間でフィルターステートを同期させます。
システムの信頼性を確保するため、LLMとフロントエンド間の通信は、決定論的で型安全なコントラクトに従う必要があります。これをTypeScriptとZodを使用して定義します。
// intent-contract.ts
import { z } from 'zod';
export const IntentActionSchema = z.enum([
'VIEW_ANALYTICS',
'GENERATE_REPORT',
'TRIGGER_WORKFLOW',
'MODIFY_SETTINGS'
]);
export const IntentPayloadSchema = z.object({
action: IntentActionSchema,
confidence: z.number().min(0).max(1),
parameters: z.object({
timeRange: z.enum(['7d', '30d', '90d', '1y']).optional(),
region: z.string().optional(),
segment: z.string().optional(),
metrics: z.array(z.string()).default([])
}),
layout: z.enum(['single-card', 'split-view', 'dashboard-grid']),
componentManifest: z.array(z.string())
});
export type IntentPayload = z.infer<typeof IntentPayloadSchema>;
構造化されたツール呼び出しを利用することで、LLMがマークダウン解析の異常なしに有効なスキーマオブジェクトを返すことを保証します。
// api/intent/route.ts
import { NextResponse } from 'next/server';
import { IntentPayloadSchema } from '@/lib/intent-contract';
export async function POST(req: Request) {
const { prompt, userContext } = await req.json();
const response = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'x-api-key': process.env.ANTHROPIC_API_KEY!,
'anthropic-version': '2023-06-01',
'content-type': 'application/json'
},
body: JSON.stringify({
model: 'claude-3-5-haiku-20241022',
max_tokens: 1024,
system: `You are an intent parser for an enterprise analytics dashboard.
Translate user requests into the UI Intent Schema. Available components:
[RevenueTrendChart, RegionalBreakdownTable, RenewalActionBar, ChurnRiskHeatmap].`,
tools: [
{
name: 'render_intent_ui',
description: 'Renders dynamic UI widgets matching user intent',
input_schema: {
type: 'object',
properties: {
action: { type: 'string', enum: ['VIEW_ANALYTICS', 'GENERATE_REPORT', 'TRIGGER_WORKFLOW'] },
confidence: { type: 'number' },
parameters: { type: 'object' },
layout: { type: 'string', enum: ['single-card', 'split-view', 'dashboard-grid'] },
componentManifest: { type: 'array', items: { type: 'string' } }
},
required: ['action', 'confidence', 'layout', 'componentManifest']
}
}
],
tool_choice: { type: 'tool', name: 'render_intent_ui' },
messages: [{ role: 'user', content: prompt }]
})
});
const data = await response.json();
const toolCall = data.content.find((c: any) => c.type === 'tool_use');
const parsed = IntentPayloadSchema.parse(toolCall.input);
return NextResponse.json(parsed);
}
クライアント側では、コンポーネントは中央レジストリに登録されます。肥大化を防ぐために、Reactの動的インポートを使用してそれらを動的にレンダリングします。
// components/intent/IntentWorkspace.tsx
'use client';
import React, { Suspense } from 'react';
import dynamic from 'next/dynamic';
import type { IntentPayload } from '@/lib/intent-contract';
const ComponentRegistry: Record<string, React.ComponentType<any>> = {
RevenueTrendChart: dynamic(() => import('@/components/charts/RevenueTrendChart')),
RegionalBreakdownTable: dynamic(() => import('@/components/tables/RegionalBreakdownTable')),
RenewalActionBar: dynamic(() => import('@/components/actions/RenewalActionBar')),
ChurnRiskHeatmap: dynamic(() => import('@/components/charts/ChurnRiskHeatmap'))
};
export function IntentWorkspace({ intent }: { intent: IntentPayload }) {
if (intent.confidence < 0.75) {
return (
<div className="p-6 border border-amber-300 bg-amber-50 rounded-lg">
<p className="font-semibold text-amber-900">Intent Unclear</p>
<p className="text-amber-700 text-sm">Did you mean to view regional revenue or renewal actions?</p>
</div>
);
}
const gridStyles = {
'single-card': 'grid grid-cols-1',
'split-view': 'grid grid-cols-1 lg:grid-cols-2 gap-6',
'dashboard-grid': 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6'
};
return (
<div className={`intent-canvas ${gridStyles[intent.layout]}`}>
{intent.componentManifest.map((componentName) => {
const Widget = ComponentRegistry[componentName];
if (!Widget) return null;
return (
<Suspense fallback={<div className="h-64 animate-pulse bg-slate-100 rounded-lg" />} key={componentName}>
<Widget params={intent.parameters} />
</Suspense>
);
})}
</div>
);
}
| アーキテクチャの側面 | 従来の静的ルーティング | インテントベースUI(Generative) |
|---|---|---|
| ナビゲーションパラダイム | 階層型URL(/a/b/c) | 宣言型インテント記述子 |
| コンポーネントアセンブリ | ハードコードされたページツリー | ランタイムで動的にアセンブル |
| 学習曲線 | 高い(ユーザーがアプリケーションのレイアウトを学習) | 低い(アプリケーションがユーザーの意図に適応) |
| レイテンシ | 瞬時のクライアントルーティング(10ms未満) | モデル推論レイテンシ(150~400ms) |
| 障害モード | 壊れたルート(404) | 曖昧なインテント / 低信頼度フォールバック |
| 状態共有 | URLクエリパラメーターとグローバルストア | コンテキストアウェアなセッションパラメーター渡し |
| 最適な用途 | 静的マーケティングページ、シンプルなCRUD | エンタープライズBI、分析、複雑なSaaS |
DELETE /customersやPOST /refundなど)を自動的に実行することを決して許可しないでください。ミューテーションを実行する前に、明示的なユーザー確認ダイアログを要求します。Intent-Based UIアーキテクチャにおいて、「Structured Intent Resolution」ステップのために、大規模で高性能なLLM(例:GPT-4)と、より小さく高速なLLM(例:Claude 3.5 Haiku)のどちらを選択するかという点で、本番環境における重要なトレードオフは何ですか?
いいえ。最適なアーキテクチャはハイブリッドルーティングを使用します。高レベルのワークスペース(/workspace、/settings)には標準URLを使用し、それらのワークスペース内でビューを動的に配置するインテント駆動のコマンドパレットを使用します。
厳密なスキーマ検証(Zod経由)を強制し、LLMの出力を登録されたコンポーネント識別子の明示的なホワイトリストに制限することで防ぎます。モデルが未登録のコンポーネントを返した場合、ランタイムはそれを無視します。
超高速の軽量モデル(Claude 3.5 HaikuまたはGPT-4o-mini)を使用し、初期レイアウトシェルをストリーミングし、セマンティック埋め込み類似性を使用して頻繁なユーザークエリをRedisにキャッシュします。
厳格で事前に決定されたルートツリーから、適応性のあるインテント駆動型インターフェースへの移行は、ウェブエンジニアリングにおける次の大きなフロンティアを示しています。厳密に型付けされたスキーマ、高速な推論モデル、モジュール化されたコンポーネントレジストリを統合することで、ユーザーに適応するソフトウェアを構築し、認知負荷を排除し、開発者の生産性を再定義することができます。
AI CLIログの整形、Cron式の作成、JWTの解析、chmod権限の計算をオフラインで実行。

vLLMにおける投機的デコーディングを解説し、EagleとMedusaでLLM推論スループットを3倍にする方法を、実証済みの本番環境での例を交えて詳しく解説するアーキテクチャガイドです。
続きを読む
LLM推論における連続動的バッチ処理について、Orca、vLLM、TGIのレイテンシベンチマークを、本番環境レベルのアーキテクチャとコード例で網羅的に解説する総合ガイドです。
続きを読む
sglangとvllmの高スループットLLM推論、RadixAttention、構造化デコーディングを、本番環境レベルのアーキテクチャとコード例で網羅的に解説するガイド。
続きを読む