Skip to content

React から TypeScript Strands Agent への接続

Nx Plugin for AWSは、TypeScript Strands AgentとReactウェブサイトを素早く統合するためのジェネレーターを提供します。このジェネレーターは、tRPC over WebSocketを介してエージェントに接続するために必要なすべての設定を行い、AWS IAMとCognito認証のサポートを含みます。この統合により、フロントエンドとエージェントのtRPCルーター間で完全なエンドツーエンドの型安全性が提供されます。

このジェネレーターを使用する前に、以下が必要です:

  1. Reactウェブサイト(ts#react-website ジェネレーターを使用して生成)
  2. TypeScript Strands Agent(ts#strands-agent ジェネレーターを使用して生成)
  3. ts#react-website-auth ジェネレーターを介して追加されたCognito Auth
  1. インストール Nx Console VSCode Plugin まだインストールしていない場合
  2. VSCodeでNxコンソールを開く
  3. クリック Generate (UI) "Common Nx Commands"セクションで
  4. 検索 @aws/nx-plugin - connection
  5. 必須パラメータを入力
    • クリック Generate

    Reactウェブサイトをソースプロジェクトとして、Strands Agentを含むプロジェクトをターゲットプロジェクトとして選択するよう求められます。ターゲットプロジェクトに複数のコンポーネント(複数のエージェントや他のコンポーネントタイプなど)が含まれている場合は、曖昧さを解消するためにtargetComponentを指定するよう求められます。

    パラメータ デフォルト 説明
    sourceProject 必須 string - ソース プロジェクト
    targetProject 必須 string - 接続先のターゲット プロジェクト
    sourceComponent string - 接続元のソース コンポーネント (コンポーネント名、ソース プロジェクト ルートからの相対パス、またはジェネレーター ID)。プロジェクトをソースとして明示的に選択するには '.' を使用します。
    targetComponent string - 接続先のターゲット コンポーネント (コンポーネント名、ターゲット プロジェクト ルートからの相対パス、またはジェネレーター ID)。プロジェクトをターゲットとして明示的に選択するには '.' を使用します。

    ジェネレーターは、Reactアプリケーション内に以下の構造を作成します:

    • Directorysrc
      • Directorycomponents
        • <AgentName>AgentClientProvider.tsx tRPC WebSocketクライアントとエージェントのtRPCルーターへのバインディングを設定
        • QueryClientProvider.tsx TanStack React Queryクライアントプロバイダー
      • Directoryhooks
        • useSigV4.tsx SigV4でリクエストに署名するためのフック(IAMのみ)
        • use<AgentName>Agent.tsx tRPCオプションプロキシとバニラtRPCクライアントを返すフック

    さらに、必要な依存関係をインストールします:

    • @trpc/client
    • @trpc/tanstack-react-query
    • @tanstack/react-query
    • aws4fetch(IAM認証を使用する場合)

    生成されたクライアントは、tRPC over WebSocketを介してStrands Agentに接続します。エージェントは、WebSocketエンドポイント上でtRPCルーター(エージェントレスポンスをストリーミングするためのinvokeサブスクリプションを含む)を公開します。

    • デプロイ時: エージェントランタイムARNはランタイム設定から読み込まれます。ARNは、Bedrock AgentCore Runtime WebSocketプロトコルに従ってWebSocket URLに変換されます: wss://bedrock-agentcore.<region>.amazonaws.com/runtimes/<encoded-arn>/ws
    • ローカル開発: serve-localで実行する場合、ランタイム設定のオーバーライドによって値がローカルのws:// URL(例: ws://localhost:8081/ws)に設定され、クライアントは直接接続します

    生成されたコードは、エージェントの設定に応じて認証を処理します:

    • IAM(デフォルト): AWS SigV4事前署名URLを使用してWebSocket接続を認証します。認証情報は、ウェブサイトの認証で設定されたCognito Identity Poolから取得されます。serve-localモードでは、runtime-config.jsonが存在しない場合、署名は自動的にスキップされます
    • Cognito: JWTアクセストークンをSec-WebSocket-Protocolヘッダーにbase64urlエンコードされたベアラートークンとして埋め込みます。これはAgentCore WebSocket認証プロトコルに従います

    エージェントがIAM認証を使用する場合、Cognito Identity Poolの認証済みロールは、WebSocket経由でエージェントを呼び出すためにbedrock-agentcore:InvokeAgentRuntimeWithWebSocketStream権限を持つ必要があります:

    const identity = new UserIdentity(this, 'Identity');
    const myAgent = new MyAgent(this, 'MyAgent');
    identity.identityPool.authenticatedRole.addToPrincipalPolicy(
    new PolicyStatement({
    actions: ['bedrock-agentcore:InvokeAgentRuntimeWithWebSocketStream'],
    resources: [myAgent.agentCoreRuntime.agentRuntimeArn],
    }),
    );

    エージェントがCognito認証を使用する場合、ウェブサイトをエージェントに接続するために追加のインフラストラクチャを定義する必要はありません。

    最も一般的な使用例は、use<AgentName>Agentフックとinvokeサブスクリプションを使用してエージェントのレスポンスをストリーミングすることです。このフックは、TanStack Queryで使用するためのtRPCオプションプロキシを返します:

    import { useSubscription } from '@trpc/tanstack-react-query';
    import { useMyAgentAgent } from './hooks/useMyAgentAgent';
    function ChatComponent() {
    const trpc = useMyAgentAgent();
    const subscription = useSubscription(
    trpc.invoke.subscriptionOptions(
    { message: 'What can you help me with?' },
    {
    enabled: true,
    onStarted: () => {
    console.log('Agent started responding');
    },
    onData: (token) => {
    console.log('Received token:', token);
    },
    onError: (error) => {
    console.error('Agent error:', error);
    },
    },
    ),
    );
    return (
    <div>
    <p>Status: {subscription.status}</p>
    {subscription.data && <p>Latest token: {subscription.data}</p>}
    {subscription.error && <p>Error: {subscription.error.message}</p>}
    </div>
    );
    }

    use<AgentName>AgentClientフックは、サブスクリプションのライフサイクルをより細かく制御するためのバニラtRPCクライアントへのアクセスを提供します:

    import { useState } from 'react';
    import { useMyAgentAgentClient } from './hooks/useMyAgentAgent';
    function ChatComponent() {
    const client = useMyAgentAgentClient();
    const [messages, setMessages] = useState<string[]>([]);
    const sendMessage = (message: string) => {
    const subscription = client.invoke.subscribe(
    { message },
    {
    onData: (token) => {
    setMessages((prev) => [...prev, token]);
    },
    onComplete: () => {
    console.log('Agent finished');
    },
    onError: (error) => {
    console.error('Error:', error);
    },
    },
    );
    // Clean up when done
    return () => subscription.unsubscribe();
    };
    return (
    <div>
    <button onClick={() => sendMessage('Hello!')}>Send</button>
    <div>
    {messages.map((msg, i) => (
    <span key={i}>{msg}</span>
    ))}
    </div>
    </div>
    );
    }

    接続ジェネレーターは、Reactウェブサイトのserve-local統合を自動的に設定します:

    1. nx serve-local <website>を実行すると、エージェントのローカルサーバーも起動します
    2. ランタイム設定はローカルのWebSocket URL(例: ws://localhost:8081/ws)を指すようにオーバーライドされます
    3. 接続されたAPIと同様に、runtime-config.jsonが存在しない場合、serve-localモードでは認証がスキップされます

    この統合は完全なエンドツーエンドの型安全性を提供します。IDEは、すべてのエージェントプロシージャコールに対して完全な自動補完と型チェックを提供します。型はエージェントのtRPCルーター定義から自動的に推論されるため、エージェントのAPIに対する変更がフロントエンドコードに即座に反映されます。

    詳細については、以下を参照してください: