React에서 AG-UI 에이전트로
Nx Plugin for AWS는 AG-UI 프로토콜을 노출하는 Strands Agent에 React 웹사이트를 연결하는 생성기를 제공합니다. 이는 AWS IAM 및 Cognito 인증 지원과 함께 웹사이트의 @ag-ui/client HttpAgent로 CopilotKit을 연결합니다.
사전 요구 사항
섹션 제목: “사전 요구 사항”이 생성기를 사용하기 전에 다음을 준비해야 합니다:
- React 웹사이트 (
ts#react-website생성기를 사용하여 생성) protocol=AG-UI를 사용하는 Python Strands Agent (py#strands-agent생성기를 사용하여 생성)- 배포된 에이전트의 경우,
ts#react-website-auth생성기를 통해 추가된 Cognito Auth
사용법
섹션 제목: “사용법”생성기 실행
섹션 제목: “생성기 실행”- 설치 Nx Console VSCode Plugin 아직 설치하지 않았다면
- VSCode에서 Nx 콘솔 열기
- 클릭
Generate (UI)"Common Nx Commands" 섹션에서 - 검색
@aws/nx-plugin - connection - 필수 매개변수 입력
- 클릭
Generate
pnpm nx g @aws/nx-plugin:connectionyarn nx g @aws/nx-plugin:connectionnpx nx g @aws/nx-plugin:connectionbunx nx g @aws/nx-plugin:connection소스 프로젝트로 React 웹사이트를, 타겟 프로젝트로 AG-UI Strands Agent가 포함된 프로젝트를 선택하라는 메시지가 표시됩니다. 타겟 프로젝트에 여러 컴포넌트(여러 에이전트 또는 다른 컴포넌트 유형 등)가 포함된 경우, 명확히 구분하기 위해 targetComponent를 지정하라는 메시지가 표시됩니다.
| 매개변수 | 타입 | 기본값 | 설명 |
|---|---|---|---|
| sourceProject 필수 | string | - | 소스 프로젝트 |
| targetProject 필수 | string | - | 연결할 대상 프로젝트 |
| sourceComponent | string | - | 연결을 시작할 소스 컴포넌트 (컴포넌트 이름, 소스 프로젝트 루트 기준 상대 경로, 또는 generator id). 프로젝트를 소스로 명시적으로 선택하려면 '.'을 사용하세요. |
| targetComponent | string | - | 연결할 대상 컴포넌트 (컴포넌트 이름, 대상 프로젝트 루트 기준 상대 경로, 또는 generator id). 프로젝트를 대상으로 명시적으로 선택하려면 '.'을 사용하세요. |
생성기 출력
섹션 제목: “생성기 출력”생성기는 단일 공유 AguiProvider 컴포넌트와 연결된 에이전트당 하나의 훅을 생성합니다:
디렉터리src
디렉터리components
- AguiProvider.tsx 모든 AG-UI 에이전트를 위한 단일
CopilotKitProvider. 첫 번째connection실행 시 생성되고 후속 실행 시 각 새 에이전트를 등록하도록 업데이트됩니다.
- AguiProvider.tsx 모든 AG-UI 에이전트를 위한 단일
디렉터리hooks
- useAgui<AgentName>.tsx 하나의 AG-UI 에이전트를 등록합니다.
connection실행당 하나의 파일. - useSigV4.tsx SigV4 서명 (IAM 전용)
- useAgui<AgentName>.tsx 하나의 AG-UI 에이전트를 등록합니다.
다른 에이전트에 대해 connection을 두 번째로 실행하면 새로운 useAgui<AgentName>.tsx 훅이 추가되고 AguiProvider.tsx가 두 훅을 모두 등록하도록 업데이트됩니다 — 프로바이더에 대한 사용자 정의 편집 내용은 보존됩니다. main.tsx는 단일 <AguiProvider> 래퍼를 유지하므로 중첩된 프로바이더가 생기지 않습니다.
다음 종속성이 루트 package.json에 추가됩니다:
@copilotkit/react-core—CopilotKitProvider와 채팅 컴포넌트(CopilotChat,CopilotSidebar,CopilotPopup)를 제공합니다@ag-ui/client— 생성된 훅에서 사용하는HttpAgentaws4fetch,oidc-client-ts,react-oidc-context,@aws-sdk/credential-providers— IAM 인증 전용react-oidc-context— Cognito 인증
작동 방식
섹션 제목: “작동 방식”AG-UI 연결
섹션 제목: “AG-UI 연결”각 useAgui<AgentName> 훅은 런타임 구성에서 에이전트의 런타임 값을 읽고 @ag-ui/client HttpAgent를 인스턴스화합니다:
- 배포됨: 런타임 값은 Bedrock AgentCore Runtime ARN이며, AgentCore HTTPS 엔드포인트로 변환됩니다:
https://bedrock-agentcore.<region>.amazonaws.com/runtimes/<encoded-arn>/invocations?qualifier=DEFAULT - 로컬 개발:
serve-local이 값을 에이전트의 로컬 URL(예:http://localhost:8081)로 재정의합니다
공유 AguiProvider는 생성된 모든 훅을 호출하고 각각을 단일 CopilotKitProvider의 selfManagedAgents에 전개하여 모든 에이전트를 CopilotKit 컴포넌트에 노출합니다.
CopilotKit 통합
섹션 제목: “CopilotKit 통합”CopilotKit은 AG-UI 프로토콜을 위한 1차 참조 React 클라이언트이며 즉시 사용 가능한 채팅 컴포넌트를 제공합니다:
<CopilotChat />— 전체 채팅 인터페이스<CopilotSidebar />— 고정 사이드 패널 채팅<CopilotPopup />— 플로팅 채팅 팝업
이들 중 하나를 <AguiProvider> 래퍼 내부 어디에나 배치하세요(이미 main.tsx에 연결되어 있습니다).
생성된 코드는 에이전트의 구성에 따라 인증을 처리합니다:
- IAM (기본값): AWS SigV4 서명된 HTTP 요청을 사용합니다. 자격 증명은 웹사이트의 인증과 함께 구성된 Cognito Identity Pool에서 가져옵니다.
- Cognito: JWT 액세스 토큰을 Bearer 토큰으로
Authorization헤더에 포함합니다.
인프라
섹션 제목: “인프라”에이전트가 IAM 인증을 사용하는 경우, Cognito Identity Pool의 인증된 역할에 에이전트를 호출할 수 있는 권한을 부여해야 합니다.
const identity = new UserIdentity(this, 'Identity');const myAgent = new MyAgent(this, 'MyAgent');
// Grant the authenticated Cognito role permission to invoke the agentmyAgent.grantInvokeAccess(identity.identityPool.authenticatedRole);grantInvokeAccess는 에이전트의 런타임 ARN에 대한 모든 AgentCore 호출 작업(InvokeAgentRuntime, InvokeAgentRuntimeWithWebSocketStream)을 연결합니다.
module "identity" { source = "../../common/terraform/src/core/user-identity"}
module "my_agent" { source = "../../common/terraform/src/app/agents/my-agent"}
# Grant the authenticated Cognito role permission to invoke the agentresource "aws_iam_policy" "invoke_my_agent" { name = "InvokeMyAgentPolicy" policy = jsonencode({ Version = "2012-10-17" Statement = [{ Effect = "Allow" Action = [ "bedrock-agentcore:InvokeAgentRuntime", "bedrock-agentcore:InvokeAgentRuntimeWithWebSocketStream", ] Resource = [ module.my_agent.agent_core_runtime_arn, "${module.my_agent.agent_core_runtime_arn}/*", ] }] })}
resource "aws_iam_role_policy_attachment" "invoke_my_agent" { role = module.identity.authenticated_role_name policy_arn = aws_iam_policy.invoke_my_agent.arn}에이전트가 Cognito 인증을 사용하는 경우, 웹사이트를 에이전트에 연결하기 위해 추가 인프라를 정의할 필요가 없습니다.
생성된 코드 사용
섹션 제목: “생성된 코드 사용”채팅 인터페이스 추가
섹션 제목: “채팅 인터페이스 추가”agentId와 함께 CopilotKit 컴포넌트를 인스턴스화하여 사용할 에이전트를 선택합니다. id는 에이전트의 이름입니다 — py#strands-agent 생성기를 실행할 때 선택한 것과 동일하며 — 생성된 훅 파일에서도 찾을 수 있습니다(예: packages/web/src/hooks/useAgui<AgentName>.tsx에서 반환된 키):
import { CopilotChat } from '@copilotkit/react-core/v2';
function ChatPage() { return ( <CopilotChat agentId="agent" labels={{ welcomeMessageText: 'How can I help you today?', chatInputPlaceholder: 'Ask me anything...', }} /> );}여러 AG-UI 에이전트 연결
섹션 제목: “여러 AG-UI 에이전트 연결”에이전트당 한 번씩 connection 생성기를 실행합니다. 공유 AguiProvider를 통해 등록된 모든 에이전트는 앱의 어디에서나 볼 수 있습니다 — 다른 agentId로 CopilotKit 컴포넌트를 인스턴스화하여 각 채팅을 원하는 에이전트로 라우팅합니다:
<CopilotChat agentId="story" /> {/* talks to StoryAgent */}<CopilotChat agentId="research" /> {/* talks to ResearchAgent */}모양과 느낌 사용자 정의
섹션 제목: “모양과 느낌 사용자 정의”<CopilotChat /> (그리고 <CopilotSidebar />, <CopilotPopup />)는 재귀적 슬롯 시스템을 사용합니다 — Tailwind 클래스 문자열, prop 객체 또는 사용자 정의 React 컴포넌트로 하위 컴포넌트를 재정의할 수 있습니다. 전체 슬롯 트리는 CopilotKit 슬롯 가이드를 참조하세요.
슬롯을 통한 Tailwind 스타일링
섹션 제목: “슬롯을 통한 Tailwind 스타일링”<CopilotChat agentId="agent" // style the input and its children input={{ textArea: 'text-blue-600', sendButton: 'bg-blue-600 hover:bg-blue-700', }} // style nested message slots messageView={{ assistantMessage: 'bg-blue-50 rounded-xl p-2', userMessage: 'bg-blue-100 rounded-xl', }}/>사용자 정의 컴포넌트로 슬롯 교체
섹션 제목: “사용자 정의 컴포넌트로 슬롯 교체”모든 슬롯은 className 대신 React 컴포넌트를 받을 수 있으므로 기본값을 완전히 교체할 수 있습니다:
import { CopilotChat } from '@copilotkit/react-core/v2';
const MySendButton: React.FC<{ onClick: () => void }> = ({ onClick }) => ( <button onClick={onClick} className="my-send-btn"> ✨ Send </button>);
<CopilotChat agentId="agent" input={{ sendButton: MySendButton }}/>;더 깊은 재정의도 동일한 형태를 따릅니다 — 예를 들어 어시스턴트 메시지의 복사 버튼만 교체:
<CopilotChat agentId="agent" messageView={{ assistantMessage: { copyButton: ({ onClick }) => <button onClick={onClick}>Copy</button>, }, }}/>로컬 개발
섹션 제목: “로컬 개발”연결 생성기는 자동으로 serve-local 통합을 구성합니다:
nx serve-local <website>를 실행하면 에이전트의 로컬 서버도 시작됩니다- 런타임 구성이 로컬 AG-UI URL(예:
http://localhost:8081)을 가리키도록 재정의됩니다 - 웹사이트와 에이전트가 함께 핫 리로드됩니다
pnpm nx serve-local <WebsiteProject>yarn nx serve-local <WebsiteProject>npx nx serve-local <WebsiteProject>bunx nx serve-local <WebsiteProject>