콘텐츠로 이동

React에서 TypeScript Strands Agent로 연결

Nx Plugin for AWS는 TypeScript Strands Agent를 React 웹사이트와 빠르게 통합할 수 있는 제너레이터를 제공합니다. 이는 AWS IAM 및 Cognito 인증 지원을 포함하여 tRPC over WebSocket을 통해 에이전트에 연결하는 데 필요한 모든 구성을 설정합니다. 이 통합은 프론트엔드와 에이전트의 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 - 연결을 시작할 소스 컴포넌트 (컴포넌트 이름, 소스 프로젝트 루트 기준 상대 경로, 또는 generator id). 프로젝트를 소스로 명시적으로 선택하려면 '.'을 사용하세요.
    targetComponent string - 연결할 대상 컴포넌트 (컴포넌트 이름, 대상 프로젝트 루트 기준 상대 경로, 또는 generator id). 프로젝트를 대상으로 명시적으로 선택하려면 '.'을 사용하세요.

    제너레이터는 React 애플리케이션에 다음과 같은 구조를 생성합니다:

    • 디렉터리src
      • 디렉터리components
        • <AgentName>AgentClientProvider.tsx tRPC WebSocket 클라이언트 및 에이전트의 tRPC 라우터에 대한 바인딩 설정
        • QueryClientProvider.tsx TanStack React Query 클라이언트 프로바이더
      • 디렉터리hooks
        • useSigV4.tsx SigV4로 요청에 서명하기 위한 훅 (IAM 전용)
        • use<AgentName>Agent.tsx tRPC 옵션 프록시와 vanilla 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: AgentCore WebSocket 인증 프로토콜에 따라 JWT 액세스 토큰을 base64url 인코딩된 bearer 토큰으로 Sec-WebSocket-Protocol 헤더에 포함합니다

    에이전트가 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 훅은 구독 수명 주기를 더 세밀하게 제어하기 위해 vanilla 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의 모든 변경 사항이 프론트엔드 코드에 즉시 반영됩니다.

    자세한 내용은 다음을 참조하세요: