TypeScript Strands 에이전트
도구를 사용하여 AI 에이전트를 구축하기 위한 TypeScript Strands Agent를 생성하고, 선택적으로 Amazon Bedrock AgentCore Runtime에 배포합니다. 이 생성기는 WebSocket을 통한 tRPC를 사용하여 AgentCore의 양방향 스트리밍 지원을 활용하여 실시간 타입 안전 통신을 제공합니다.
Strands란 무엇인가요?
섹션 제목: “Strands란 무엇인가요?”Strands는 AI 에이전트를 구축하기 위한 경량 프레임워크입니다. 주요 기능은 다음과 같습니다:
- 경량 및 커스터마이징 가능: 방해받지 않는 간단한 에이전트 루프
- 프로덕션 준비 완료: 확장을 위한 완전한 관찰성, 추적 및 배포 옵션
- 모델 및 제공업체 독립적: 다양한 제공업체의 여러 모델 지원
- 커뮤니티 기반 도구: 커뮤니티가 기여한 강력한 도구 세트
- 다중 에이전트 지원: 에이전트 팀 및 자율 에이전트와 같은 고급 기술
- 유연한 상호작용 모드: 대화형, 스트리밍 및 비스트리밍 지원
사용법
섹션 제목: “사용법”Strands Agent 생성
섹션 제목: “Strands Agent 생성”두 가지 방법으로 TypeScript Strands Agent를 생성할 수 있습니다:
- 설치 Nx Console VSCode Plugin 아직 설치하지 않았다면
- VSCode에서 Nx 콘솔 열기
- 클릭
Generate (UI)"Common Nx Commands" 섹션에서 - 검색
@aws/nx-plugin - ts#strands-agent - 필수 매개변수 입력
- 클릭
Generate
pnpm nx g @aws/nx-plugin:ts#strands-agentyarn nx g @aws/nx-plugin:ts#strands-agentnpx nx g @aws/nx-plugin:ts#strands-agentbunx nx g @aws/nx-plugin:ts#strands-agent어떤 파일이 변경될지 확인하기 위해 드라이 런을 수행할 수도 있습니다
pnpm nx g @aws/nx-plugin:ts#strands-agent --dry-runyarn nx g @aws/nx-plugin:ts#strands-agent --dry-runnpx nx g @aws/nx-plugin:ts#strands-agent --dry-runbunx nx g @aws/nx-plugin:ts#strands-agent --dry-run| 매개변수 | 타입 | 기본값 | 설명 |
|---|---|---|---|
| project 필수 | string | - | The project to add the Strands Agent to |
| computeType | string | BedrockAgentCoreRuntime | The type of compute to host your Strands Agent. |
| name | string | - | The name of your Strands Agent (default: agent) |
| iacProvider | string | Inherit | The preferred IaC provider. By default this is inherited from your initial selection. |
생성기 출력
섹션 제목: “생성기 출력”생성기는 기존 TypeScript 프로젝트에 다음 파일을 추가합니다:
디렉터리your-project/
디렉터리src/
디렉터리agent/ (또는 지정된 경우 사용자 정의 이름)
- index.ts Bedrock AgentCore Runtime의 진입점
- init.ts tRPC 초기화
- router.ts 에이전트 프로시저가 포함된 tRPC 라우터
- agent.ts 샘플 도구가 포함된 메인 에이전트 정의
- client.ts 에이전트를 호출하기 위한 제공된 클라이언트
- agent-core-trpc-client.ts AgentCore Runtime의 에이전트에 연결하기 위한 클라이언트 팩토리
- agent-core-mcp-client.ts AgentCore Runtime의 MCP 서버에 연결하기 위한 클라이언트 팩토리
- Dockerfile 에이전트 호스팅을 위한 진입점 (
computeType이None으로 설정된 경우 제외)
- package.json Strands 종속성으로 업데이트됨
- project.json 에이전트 서브 타겟으로 업데이트됨
인프라
섹션 제목: “인프라”이 생성기는 선택한 iacProvider 기반으로 인프라를 코드 형태로 제공하므로, packages/common 디렉터리에 관련 CDK 구축 요소 또는 Terraform 모듈을 포함하는 프로젝트를 생성합니다.
공통 인프라스트럭처 코드 프로젝트의 구조는 다음과 같습니다:
디렉터리packages/common/constructs
디렉터리src
디렉터리app/ 특정 프로젝트/생성기에 종속적인 인프라를 위한 구축 요소
- …
디렉터리core/
app내 구축 요소에서 재사용되는 일반적 구축 요소- …
- index.ts
app의 구축 요소를 익스포트하는 진입점
- project.json 프로젝트 빌드 대상 및 구성
디렉터리packages/common/terraform
디렉터리src
디렉터리app/ 특정 프로젝트/생성기 전용 Terraform 모듈
- …
디렉터리core/
app내 모듈에서 재사용되는 일반적 모듈- …
- project.json 프로젝트 빌드 대상 및 구성
Strands Agent 배포를 위해 다음 파일이 생성됩니다:
디렉터리packages/common/constructs/src
디렉터리app
디렉터리agents
디렉터리<project-name>
- <project-name>.ts 에이전트 배포를 위한 CDK 구성
- Dockerfile CDK 구성에서 사용하는 패스스루 도커 파일
디렉터리packages/common/terraform/src
디렉터리app
디렉터리agents
디렉터리<project-name>
- <project-name>.tf 에이전트 배포를 위한 모듈
디렉터리core
디렉터리agent-core
- runtime.tf Bedrock AgentCore Runtime에 배포하기 위한 일반 모듈
Strands Agent 작업하기
섹션 제목: “Strands Agent 작업하기”WebSocket을 통한 tRPC
섹션 제목: “WebSocket을 통한 tRPC”TypeScript Strands Agent는 WebSocket을 통한 tRPC를 사용하여 AgentCore의 양방향 스트리밍 지원을 활용하여 클라이언트와 에이전트 간의 실시간 타입 안전 통신을 가능하게 합니다.
tRPC는 WebSocket을 통한 Query, Mutation 및 Subscription 프로시저를 지원하므로 원하는 수의 프로시저를 정의할 수 있습니다. 기본적으로 router.ts에 invoke라는 단일 구독 프로시저가 정의되어 있습니다.
도구 추가
섹션 제목: “도구 추가”도구는 AI 에이전트가 작업을 수행하기 위해 호출할 수 있는 함수입니다. agent.ts 파일에 새 도구를 추가할 수 있습니다:
import { Agent, tool } from '@strands-agents/sdk';import z from 'zod';
const letterCounter = tool({ name: 'letter_counter', description: 'Count occurrences of a specific letter in a word', inputSchema: z.object({ word: z.string().describe('The input word to search in'), letter: z.string().length(1).describe('The specific letter to count'), }), callback: (input) => { const { word, letter } = input; const count = word.toLowerCase().split(letter.toLowerCase()).length - 1; return `The letter '${letter}' appears ${count} time(s) in '${word}'`; },});
// Add tools to your agentexport const agent = new Agent({ systemPrompt: 'You are a helpful assistant with access to various tools.', tools: [letterCounter],});Strands 프레임워크는 다음을 자동으로 처리합니다:
- Zod 스키마를 사용한 입력 검증
- 도구 호출을 위한 JSON 스키마 생성
- 오류 처리 및 응답 포맷팅
모델 구성
섹션 제목: “모델 구성”기본적으로 Strands 에이전트는 Claude 4 Sonnet을 사용하지만, 모델 제공업체 간에 쉽게 전환할 수 있습니다:
import { Agent } from '@strands-agents/sdk';import { BedrockModel } from '@strands-agents/sdk/models/bedrock';import { OpenAIModel } from '@strands-agents/sdk/models/openai';
// Use Bedrockconst bedrockModel = new BedrockModel({ modelId: 'anthropic.claude-sonnet-4-20250514-v1:0',});let agent = new Agent({ model: bedrockModel });let response = await agent.invoke('What can you help me with?');
// Alternatively, use OpenAI by just switching model providerconst openaiModel = new OpenAIModel({ apiKey: process.env.OPENAI_API_KEY, modelId: 'gpt-4o',});agent = new Agent({ model: openaiModel });response = await agent.invoke('What can you help me with?');더 많은 구성 옵션은 모델 제공업체에 대한 Strands 문서를 참조하세요.
MCP 서버 사용
섹션 제목: “MCP 서버 사용”Strands 에이전트에 MCP 서버의 도구를 추가할 수 있습니다.
py#mcp-server 또는 ts#mcp-server 생성기를 사용하여 생성한 MCP 서버(또는 Bedrock AgentCore Runtime에 호스팅된 다른 서버)를 사용하려면 agent-core-mcp-client.ts에 클라이언트 팩토리가 생성됩니다.
agent.ts에서 에이전트 초기화를 업데이트하여 MCP 클라이언트를 생성하고 도구를 추가할 수 있습니다. 다음 예제는 IAM (SigV4) 인증으로 이를 수행하는 방법을 보여줍니다:
import { Agent } from '@strands-agents/sdk';import { AgentCoreMcpClient } from './agent-core-mcp-client.js';
const mcpClient = AgentCoreMcpClient.withIamAuth({ agentRuntimeArn: process.env.MCP_AGENTCORE_RUNTIME_ARN!, region: process.env.AWS_REGION || 'us-west-2', sessionId: 'my-session-id',});
export const agent = new Agent({ systemPrompt: '...', tools: [mcpClient],});위의 IAM 인증 예제에서는 인프라에서 두 가지를 구성해야 합니다. 첫째, MCP 서버의 AgentCore Runtime ARN에 대해 에이전트가 사용하는 환경 변수를 추가해야 하고, 둘째 에이전트에 MCP 서버를 호출할 수 있는 권한을 부여해야 합니다. 이는 다음과 같이 수행할 수 있습니다:
import { MyProjectAgent, MyProjectMcpServer } from ':my-scope/common-constructs';
export class ExampleStack extends Stack { constructor(scope: Construct, id: string) { const mcpServer = new MyProjectMcpServer(this, 'MyProjectMcpServer');
const agent = new MyProjectAgent(this, 'MyProjectAgent', { environmentVariables: { MCP_AGENTCORE_RUNTIME_ARN: mcpServer.agentCoreRuntime.agentRuntimeArn, }, });
mcpServer.agentCoreRuntime.grantInvoke(agent.agentCoreRuntime); }}# MCP Servermodule "my_project_mcp_server" { source = "../../common/terraform/src/app/mcp-servers/my-project-mcp-server"}
# Agentmodule "my_project_agent" { source = "../../common/terraform/src/app/agents/my-project-agent"
env = { MCP_AGENTCORE_RUNTIME_ARN = module.my_project_mcp_server.agent_core_runtime_arn }
additional_iam_policy_statements = [ { Effect = "Allow" Action = [ "bedrock-agentcore:InvokeAgentRuntime" ] Resource = [ module.my_project_mcp_server.agent_core_runtime_arn, "${module.my_project_mcp_server.agent_core_runtime_arn}/*" ] } ]}더 보기
섹션 제목: “더 보기”Strands 에이전트 작성에 대한 더 심층적인 가이드는 Strands 문서를 참조하세요.
Strands Agent 실행
섹션 제목: “Strands Agent 실행”로컬 개발
섹션 제목: “로컬 개발”생성기는 <your-agent-name>-serve라는 타겟을 구성하여 개발 및 테스트를 위해 Strands Agent를 로컬에서 시작합니다.
pnpm nx run your-project:agent-serveyarn nx run your-project:agent-servenpx nx run your-project:agent-servebunx nx run your-project:agent-serve이 명령은 tsx --watch를 사용하여 파일이 변경될 때 서버를 자동으로 재시작합니다. 에이전트는 http://localhost:8081(또는 여러 에이전트가 있는 경우 할당된 포트)에서 사용할 수 있습니다.
Strands Agent를 Bedrock AgentCore Runtime에 배포
섹션 제목: “Strands Agent를 Bedrock AgentCore Runtime에 배포”Infrastructure as Code
섹션 제목: “Infrastructure as Code”computeType에 대해 BedrockAgentCoreRuntime을 선택한 경우, Strands Agent를 Amazon Bedrock AgentCore Runtime에 배포하는 데 사용할 수 있는 관련 CDK 또는 Terraform 인프라가 생성됩니다.
에이전트에 대한 CDK 구성이 생성되며, 생성기를 실행할 때 선택한 name을 기반으로 이름이 지정되거나 기본적으로 <ProjectName>Agent로 지정됩니다.
CDK 애플리케이션에서 이 CDK 구성을 사용할 수 있습니다:
import { MyProjectAgent } from ':my-scope/common-constructs';
export class ExampleStack extends Stack { constructor(scope: Construct, id: string) { // Add the agent to your stack const agent = new MyProjectAgent(this, 'MyProjectAgent');
// Grant permissions to invoke the relevant models in bedrock agent.agentCoreRuntime.addToRolePolicy( new PolicyStatement({ actions: [ 'bedrock:InvokeModel', 'bedrock:InvokeModelWithResponseStream', ], // You can scope the below down to the specific models you use resources: [ 'arn:aws:bedrock:*:*:foundation-model/*', 'arn:aws:bedrock:*:*:inference-profile/*', ], }), ); }}Terraform 모듈이 생성되며, 생성기를 실행할 때 선택한 name을 기반으로 이름이 지정되거나 기본적으로 <ProjectName>-agent로 지정됩니다.
Terraform 프로젝트에서 이 terraform 모듈을 사용할 수 있습니다:
# Agentmodule "my_project_agent" { # Relative path to the generated module in the common/terraform project source = "../../common/terraform/src/app/agents/my-project-agent"
# Grant permissions to invoke the relevant models in bedrock additional_iam_policy_statements = [ { Effect = "Allow" Action = [ "bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream" ] # You can scope the below down to the specific models you use Resource = [ "arn:aws:bedrock:*:*:foundation-model/*", "arn:aws:bedrock:*:*:inference-profile/*" ] } ]}IAM
섹션 제목: “IAM”기본적으로 Strands Agent는 IAM 인증을 사용하여 보호되며, 인수 없이 간단히 배포할 수 있습니다:
import { MyProjectAgent } from ':my-scope/common-constructs';
export class ExampleStack extends Stack { constructor(scope: Construct, id: string) { new MyProjectAgent(this, 'MyProjectAgent'); }}grantInvoke 메서드를 사용하여 Bedrock AgentCore Runtime에서 에이전트를 호출할 수 있는 액세스 권한을 부여할 수 있습니다. 예를 들어:
import { MyProjectAgent } from ':my-scope/common-constructs';
export class ExampleStack extends Stack { constructor(scope: Construct, id: string) { const agent = new MyProjectAgent(this, 'MyProjectAgent'); const lambdaFunction = new Function(this, ...);
agent.agentCoreRuntime.grantInvoke(lambdaFunction); }}# Agentmodule "my_project_agent" { # Relative path to the generated module in the common/terraform project source = "../../common/terraform/src/app/agents/my-project-agent"}에이전트를 호출할 수 있는 액세스 권한을 부여하려면 module.my_project_agent.agent_core_runtime_arn 출력을 참조하여 다음과 같은 정책을 추가해야 합니다:
{ Effect = "Allow" Action = [ "bedrock-agentcore:InvokeAgentRuntime" ] Resource = [ module.my_project_agent.agent_core_runtime_arn, "${module.my_project_agent.agent_core_runtime_arn}/*" ]}Cognito JWT 인증
섹션 제목: “Cognito JWT 인증”다음은 에이전트에 대한 Cognito 인증을 구성하는 방법을 보여줍니다.
Cognito를 사용하여 JWT 인증을 구성하려면 RuntimeAuthorizerConfiguration.usingCognito() 팩토리 메서드를 사용하세요:
import { MyProjectAgent } from ':my-scope/common-constructs';import { RuntimeAuthorizerConfiguration } from '@aws-cdk/aws-bedrock-agentcore-alpha';
export class ExampleStack extends Stack { constructor(scope: Construct, id: string) { const userPool = new UserPool(this, 'UserPool'); const client = userPool.addClient('Client', { authFlows: { userPassword: true, }, });
new MyProjectAgent(this, 'MyProjectAgent', { authorizerConfiguration: RuntimeAuthorizerConfiguration.usingCognito( userPool, [client], ), }); }}또는 자체 OIDC 공급자를 사용하는 사용자 지정 JWT 인증의 경우 RuntimeAuthorizerConfiguration.usingJWT()를 사용하세요:
import { MyProjectAgent } from ':my-scope/common-constructs';import { RuntimeAuthorizerConfiguration } from '@aws-cdk/aws-bedrock-agentcore-alpha';
export class ExampleStack extends Stack { constructor(scope: Construct, id: string) { new MyProjectAgent(this, 'MyProjectAgent', { authorizerConfiguration: RuntimeAuthorizerConfiguration.usingJWT( 'https://example.com/.well-known/openid-configuration', ['client1', 'client2'], // Allowed Client IDs (optional) ['audience1'], // Allowed Audiences (optional) ), }); }}JWT 인증을 구성하려면 다음과 같이 authorizer_configuration 변수를 구성하도록 에이전트 모듈을 편집할 수 있습니다:
data "aws_region" "current" {}
locals { aws_region = data.aws_region.current.id
# Replace with your user pool and client ids or expose as variables user_pool_id = "xxx" user_pool_client_ids = ["yyy"]}
module "agent_core_runtime" { source = "../../../core/agent-core" agent_runtime_name = "MyProjectAgent" docker_image_tag = "my-scope-my-project-agent:latest" server_protocol = "HTTP" authorizer_configuration = { custom_jwt_authorizer = { discovery_url = "https://cognito-idp.${local.aws_region}.amazonaws.com/${local.user_pool_id}/.well-known/openid-configuration" allowed_clients = local.user_pool_client_ids } } env = var.env additional_iam_policy_statements = var.additional_iam_policy_statements tags = var.tags}번들 타겟
섹션 제목: “번들 타겟”제너레이터는 Rolldown을 사용하여 배포 패키지를 생성하는 bundle 타겟을 자동으로 구성합니다:
pnpm nx run <project-name>:bundleyarn nx run <project-name>:bundlenpx nx run <project-name>:bundlebunx nx run <project-name>:bundleRolldown 구성은 rolldown.config.ts에서 확인할 수 있으며, 생성할 각 번들별로 엔트리가 존재합니다. 정의된 경우 Rolldown은 여러 번들을 병렬로 생성하는 작업을 관리합니다.
번들 타겟은 Bedrock AgentCore Runtime에서 호스팅할 WebSocket 서버의 진입점으로 index.ts를 사용합니다.
Docker 타겟
섹션 제목: “Docker 타겟”생성기는 AgentCore 런타임 계약에 따라 포트 8080에서 번들된 WebSocket 서버를 실행하는 <your-agent-name>-docker 타겟을 구성합니다.
여러 에이전트가 정의된 경우 모든 에이전트에 대한 도커 빌드를 실행하는 docker 타겟도 생성됩니다.
관찰성
섹션 제목: “관찰성”에이전트는 Dockerfile에서 자동 계측을 구성하여 AWS Distro for Open Telemetry (ADOT)를 사용한 관찰성으로 자동 구성됩니다.
CloudWatch AWS 콘솔에서 메뉴의 “GenAI Observability”를 선택하여 추적을 찾을 수 있습니다. 추적이 채워지려면 Transaction Search를 활성화해야 합니다.
자세한 내용은 관찰성에 대한 AgentCore 문서를 참조하세요.
Strands Agent 호출
섹션 제목: “Strands Agent 호출”에이전트 통신은 WebSocket을 통한 tRPC를 통해 전송됩니다. 따라서 client.ts에 생성된 타입 안전 클라이언트 팩토리를 사용하는 것이 좋습니다.
로컬 서버 호출
섹션 제목: “로컬 서버 호출”클라이언트 팩토리의 .local 팩토리 메서드를 사용하여 로컬에서 실행 중인 에이전트를 호출할 수 있습니다.
예를 들어 워크스페이스에 클라이언트를 가져오는 scripts/test.ts라는 파일을 생성할 수 있습니다:
import { AgentClient } from '../packages/<project>/src/agent/client.js';
const client = AgentClient.local({ url: 'http://localhost:8081/ws' });
client.invoke.subscribe({ message: 'what is 1 plus 1?' }, { onData: console.log });배포된 에이전트 호출
섹션 제목: “배포된 에이전트 호출”Bedrock AgentCore Runtime에 배포된 Agent를 호출하려면, URL 인코딩된 런타임 ARN과 함께 Bedrock AgentCore Runtime 데이터플레인 엔드포인트로 POST 요청을 보낼 수 있습니다.
다음과 같이 인프라에서 런타임 ARN을 얻을 수 있습니다:
import { CfnOutput } from 'aws-cdk-lib';import { MyProjectAgent } from ':my-scope/common-constructs';
export class ExampleStack extends Stack { constructor(scope: Construct, id: string) { const agent = new MyProjectAgent(this, 'MyProjectAgent');
new CfnOutput(this, 'AgentArn', { value: agent.agentCoreRuntime.agentRuntimeArn, }); }}# Agentmodule "my_project_agent" { # Relative path to the generated module in the common/terraform project source = "../../common/terraform/src/app/agents/my-project-agent"}
output "agent_arn" { value = module.my_project_agent.agent_core_runtime_arn}ARN은 다음 형식을 가집니다: arn:aws:bedrock-agentcore:<region>:<account>:runtime/<agent-runtime-id>.
그런 다음 :를 %3A로, /를 %2F로 바꿔서 ARN을 URL 인코딩할 수 있습니다.
에이전트를 호출하기 위한 Bedrock AgentCore Runtime 데이터플레인 URL은 다음과 같습니다:
https://bedrock-agentcore.<region>.amazonaws.com/runtimes/<url-encoded-arn>/invocations이 URL을 호출하는 정확한 방법은 사용된 인증 방법에 따라 다릅니다.
NodeJS
섹션 제목: “NodeJS”생성된 client.ts 파일에는 배포된 에이전트를 호출하는 데 사용할 수 있는 타입 안전 클라이언트 팩토리가 포함되어 있습니다.
IAM 인증
섹션 제목: “IAM 인증”withIamAuth 팩토리 메서드에 ARN을 전달하여 배포된 에이전트를 호출할 수 있습니다:
import { AgentClient } from './agent/client.js';
const client = AgentClient.withIamAuth({ agentRuntimeArn: 'arn:aws:bedrock-agentcore:us-west-2:123456789012:runtime/my-agent',});
client.invoke.subscribe({ message: 'what is 1 plus 1?' }, { onData: (message) => console.log(message), onError: (error) => console.error(error), onComplete: () => console.log('Done'),});JWT / Cognito 인증
섹션 제목: “JWT / Cognito 인증”JWT / Cognito 액세스 토큰으로 인증하려면 withJwtAuth 팩토리 메서드를 사용하세요.
const client = AgentClient.withJwtAuth({ agentRuntimeArn: 'arn:aws:bedrock-agentcore:us-west-2:123456789012:runtime/my-agent', accessTokenProvider: async () => `<access-token>`,});
client.invoke.subscribe({ message: 'what is 1 plus 1?' }, { onData: console.log,});accessTokenProvider는 요청을 인증하는 데 사용되는 토큰을 반환해야 합니다. 예를 들어 이 메서드 내에서 토큰을 가져와 tRPC가 WebSocket 연결을 재시작할 때 새로운 자격 증명이 재사용되도록 할 수 있습니다. 아래는 AWS SDK를 사용하여 Cognito에서 토큰을 가져오는 방법을 보여줍니다:
import { CognitoIdentityProvider } from "@aws-sdk/client-cognito-identity-provider";
const cognito = new CognitoIdentityProvider();
const jwtClient = AgentClient.withJwtAuth({ agentRuntimeArn: 'arn:aws:bedrock-agentcore:us-west-2:123456789012:runtime/my-agent', accessTokenProvider: async () => { const response = await cognito.adminInitiateAuth({ UserPoolId: '<user-pool-id>', ClientId: '<user-pool-client-id>', AuthFlow: 'ADMIN_NO_SRP_AUTH', AuthParameters: { USERNAME: '<username>', PASSWORD: '<password>', }, }); return response.AuthenticationResult!.AccessToken!; },});브라우저
섹션 제목: “브라우저”브라우저의 WebSocket은 헤더 지정을 지원하지 않으므로(Sec-WebSocket-Protocol 제외), client.ts에 생성된 클라이언트 팩토리는 브라우저에서 사용할 수 없습니다(실제로 WebSocket 생성자가 NodeJS에서처럼 헤더를 허용하지 않으므로 컴파일 오류가 발생합니다).
JWT / Cognito 인증
섹션 제목: “JWT / Cognito 인증”IAM 인증
섹션 제목: “IAM 인증”브라우저에서 에이전트를 호출하려면 AWS SigV4를 사용하여 사전 서명된 WebSocket URL을 생성해야 합니다.
아래 예제는 자격 증명 가져오기, 사전 서명된 URL 생성 및 에이전트 호출의 엔드 투 엔드 흐름을 보여줍니다:
import { createTRPCClient, createWSClient, wsLink } from '@trpc/client';import { AwsClient } from 'aws4fetch';import { CognitoIdentityClient } from '@aws-sdk/client-cognito-identity';import { fromCognitoIdentityPool } from '@aws-sdk/credential-provider-cognito-identity';import type { AppRouter } from './your-agent/router';
// Build a presigned WebSocket URLasync function buildSignedUrl( agentRuntimeArn: string, idToken: string, region: string = 'us-west-2'): Promise<string> { // Get credentials from a Cognito Identity Pool (or other source) const credentials = fromCognitoIdentityPool({ client: new CognitoIdentityClient({ region }), identityPoolId: 'us-west-2:xxxxx', logins: { [`cognito-idp.${region}.amazonaws.com/us-west-2_xxxxx`]: idToken, }, });
const cognitoIdentity = new CognitoIdentityClient({ credentials }); const credential = await cognitoIdentity.config.credentials();
// Create AWS SigV4 client const awsClient = new AwsClient({ ...credential, service: 'bedrock-agentcore', });
// Build WebSocket URL from ARN const wsUrl = `wss://bedrock-agentcore.${region}.amazonaws.com/runtimes/${agentRuntimeArn.replace(/:/g, '%3A').replace(/\//g, '%2F')}/ws`;
// Create presigned URL const signedRequest = await awsClient.sign(wsUrl, { method: 'GET', aws: { signQuery: true }, });
return signedRequest.url;}
// Create tRPC client with presigned WebSocket URLconst agentRuntimeArn = 'arn:aws:bedrock-agentcore:us-west-2:123456789012:runtime/my-agent';const idToken = '<your-id-token>';
const wsClient = createWSClient({ url: async () => buildSignedUrl(agentRuntimeArn, idToken),});
const trpcClient = createTRPCClient<AppRouter>({ links: [wsLink({ client: wsClient })],});
// Invoke the agenttrpcClient.invoke.subscribe({ message: 'what is 1 plus 1?' }, { onData: (message) => console.log(message),});