WebSocket을 사용하여 양방향 스트리밍 시작하기
Amazon Bedrock AgentCore 런타임을 사용하면 실시간 양방향 통신을 위해 WebSocket 스트리밍을 지원하는 에이전트를 배포할 수 있습니다. 이 가이드에서는 WebSocket을 사용하여 첫 번째 양방향 스트리밍 에이전트를 생성, 테스트 및 배포하는 방법을 안내합니다.
이 섹션에서는 다음을 배웁니다.
-
AgentCore 런타임이 WebSocket 연결을 지원하는 방법
-
양방향 스트리밍 기능을 사용하여 에이전트 애플리케이션을 생성하는 방법
-
에이전트를 로컬에서 테스트하는 방법
-
에 에이전트를 배포하는 방법 AWS
-
배포된 에이전트를 호출하는 방법
-
WebSocket 연결과 함께 세션을 사용하는 방법
WebSocket 프로토콜에 대한 자세한 내용은 WebSocket RFC 6455
AgentCore 런타임이 WebSocket 연결을 지원하는 방법
AgentCore 런타임의 WebSocket 지원을 통해 클라이언트와 에이전트 간에 지속적인 양방향 스트리밍 연결을 사용할 수 있습니다. AgentCore 런타임은 컨테이너가 /ws 경로의 포트에 WebSocket 엔드포인트8080를 구현할 것으로 예상하며, 이는 표준 WebSocket 서버 관행에 부합합니다.
AgentCore 런타임의 WebSocket 지원은 InvokeAgentRuntime와 동일한 서버리스, 세션 격리, 자격 증명 및 관찰 기능을 제공합니다. 또한 SigV4 또는 OAuth 2.0 인증을 사용하여 WebSocket 연결을 통해 지연 시간이 짧은 실시간 양방향 메시지 스트리밍을 지원하므로 실시간 대화형 음성 에이전트와 같은 애플리케이션에 적합합니다.
지원되는 WebSocket 라이브러리
AgentCore 런타임에서 WebSockets을 사용한 양방향 스트리밍은 모든 WebSocket 언어 라이브러리를 사용하는 애플리케이션을 지원합니다. 유일한 요구 사항은 클라이언트가 WebSocket 프로토콜 연결을 사용하여 서비스 엔드포인트에 연결하는 것입니다.
wss://bedrock-agentcore.<region>.amazonaws.com/runtimes/<agentRuntimeArn>/ws
지원되는 인증 방법(SigV4 헤더, SigV4 미리 서명된 URL 또는 OAuth 2.0) 중 하나를 사용하고 에이전트 애플리케이션이 HTTP 프로토콜 계약에 지정된 대로 WebSocket 서비스 계약을 구현합니다.
이러한 유연성을 통해 다양한 프로그래밍 언어 및 프레임워크에서 선호하는 WebSocket 구현을 사용하여 기존 코드베이스 및 개발 워크플로와의 호환성을 보장할 수 있습니다.
AgentCore 런타임에서 WebSocket 사용
이 시작하기 자습서에서는 배포를 위해 bedrock-agentcore Python SDK 및 AgentCore CLI를 사용하여 양방향 스트리밍을 지원하는 에이전트 애플리케이션을 생성, 테스트 및 배포합니다.
주제
사전 조건
시작하기 전에 다음이 있는지 확인합니다.
-
AWS 자격 증명이 구성된 계정입니다. AWS 자격 증명을 구성하려면 AWS CLI의 구성 및 자격 증명 파일 설정을 참조하세요.
-
Python 3.10 이상 설치됨
-
AWS 권한: AgentCore CLI를 사용하여 에이전트를 생성하고 배포하려면 적절한 권한이 있어야 합니다. 자세한 내용은 AgentCore CLI 사용을 참조하세요.
1단계: 프로젝트 설정 및 종속성 설치
프로젝트 폴더를 생성하고 필요한 패키지를 설치합니다.
mkdir agentcore-runtime-quickstart-websocket cd agentcore-runtime-quickstart-websocket python3 -m venv .venv source .venv/bin/activate
pip를 최신 버전으로 업그레이드합니다.
pip install --upgrade pip
다음과 같은 필수 패키지를 설치합니다.
-
bedrock-agentcore - AI 에이전트를 구축하기 위한 Amazon Bedrock AgentCore SDK, python
websockets라이브러리 종속성이 포함됩니다.
pip install bedrock-agentcore
2단계: 양방향 스트리밍 에이전트 생성
라는 양방향 스트리밍 에이전트 코드의 소스 파일을 생성합니다websocket_echo_agent.py. 다음 코드를 추가합니다.
from bedrock_agentcore import BedrockAgentCoreApp app = BedrockAgentCoreApp() @app.websocket async def websocket_handler(websocket, context): """Simple echo WebSocket handler.""" await websocket.accept() try: data = await websocket.receive_json() # Echo back await websocket.send_json({"echo": data}) except Exception as e: print(f"Error: {e}") finally: await websocket.close() if __name__ == "__main__": app.run(log_level="info")
다음을 requirements.txt 생성하고 추가합니다.
bedrock-agentcore
Python websockets 라이브러리 종속성이 포함되어 있습니다.
코드 이해
-
BedrockAgentCoreApp: AI 에이전트 배포를 위해 Starlette을 확장하는 에이전트 애플리케이션을 생성하여 WebSocket 지원, HTTP 라우팅, 미들웨어 및 예외 처리 기능을 제공합니다.
-
WebSocket 데코레이터:
@app.websocket데코레이터는 포트 8080의/ws경로에서 연결을 자동으로 처리합니다. -
에코 로직:를 사용하여 수신된 데이터를 다시 보냅니다.
{"echo": data} -
오류 처리: try/except/finally 구조를 사용하여 적절한 오류 로깅 및 정상적인 연결 종료를 보장합니다.
3단계: 양방향 스트리밍 에이전트를 로컬에서 테스트
양방향 스트리밍 에이전트 시작
터미널 창을 열고 다음 명령을 사용하여 양방향 스트리밍 에이전트를 시작합니다.
python websocket_echo_agent.py
서버가 포트 8080에서 실행 중임을 나타내는 출력이 표시되어야 합니다.
WebSocket 연결 테스트
라는 로컬 WebSocket 클라이언트를 생성합니다websocket_agent_client.py.
import asyncio import websockets import json async def local_websocket(): uri = "ws://localhost:8080/ws" try: async with websockets.connect(uri) as websocket: # Send a message await websocket.send(json.dumps({"inputText": "Hello WebSocket!"})) # Receive the echo response response = await websocket.recv() print(f"Received: {response}") except Exception as e: print(f"Connection failed: {e}") if __name__ == "__main__": asyncio.run(local_websocket())
다른 터미널 창을 열고 클라이언트를 실행하여 양방향 스트리밍 에이전트를 로컬에서 테스트합니다.
python websocket_agent_client.py
성공: Received: {"echo":{"inputText":"Hello WebSocket!"}}와 같은 응답이 표시됩니다. 에이전트를 실행 중인 터미널 창에서를 입력하여 에이전트를 Ctrl+C 중지합니다.
4단계: AgentCore 런타임에 양방향 스트리밍 에이전트 배포
배포 도구 설치
AgentCore CLI를 설치합니다.
npm install -g @aws/agentcore
설치 확인:
agentcore --help
프로젝트 생성 및에 배포 AWS
양방향 스트리밍 에이전트를 위한 새 프로젝트를 생성합니다.
agentcore create
에이전트를 배포합니다.
agentcore deploy
참고
에이전트 파일이 있는 프로젝트 디렉터리(agentcore-runtime-quickstart-websocket)에서이 명령을 실행합니다.
배포 후 다음과 같은 에이전트 런타임 ARN을 받게 됩니다.
arn:aws:bedrock-agentcore:us-west-2:accountId:runtime/websocket_echo_agent-xyz123
배포된 에이전트를 호출하는 데 필요하므로이 ARN을 저장합니다.
5단계: 배포된 양방향 스트리밍 에이전트 간접 호출
환경 변수 설정
필요한 환경 변수를 설정합니다.
-
에이전트 ARN을 내보냅니다.
export AGENT_ARN="arn:aws:bedrock-agentcore:us-west-2:accountId:runtime/websocket_echo_agent-xyz123" -
OAuth를 사용하는 경우 보유자 토큰을 내보냅니다.
export BEARER_TOKEN="your_oauth_token_here"
인증 방법
InvokeAgentRuntimeWithWebSocketStream API 작업은 클라이언트와 에이전트 간의 양방향 스트리밍을 지원하는 WebSocket 연결을 설정합니다. 다음 방법을 사용하여 WebSocket 연결을 인증할 수 있습니다.
-
AWS 서명 버전 4 헤더: 자격 AWS 증명을 사용하여 WebSocket 핸드셰이크 요청 헤더에 서명
-
AWS 서명 버전 4 미리 서명된 URL: 쿼리 파라미터로 제공된 SigV4 서명을 사용하여 미리 서명된 WebSocket URL 생성
-
OAuth Bearer 토큰: 외부 ID 제공업체 통합을 위한 권한 부여 헤더에 OAuth 토큰 전달
작은 정보
bedrock-agentcore:InvokeAgentRuntimeWithWebSocketStream 권한이 있는지 확인합니다.
SigV4 서명 헤더를 사용하여 연결
다음 예제에서는 SigV4 서명 헤더를 사용하여 WebSocket 연결을 설정하고 에이전트 런타임과 통신하는 방법을 보여줍니다.
from bedrock_agentcore.runtime import AgentCoreRuntimeClient import websockets import asyncio import json import os async def main(): # Get runtime ARN from environment variable runtime_arn = os.getenv('AGENT_ARN') if not runtime_arn: raise ValueError("AGENT_ARN environment variable is required") # Initialize client client = AgentCoreRuntimeClient(region="us-west-2") # Generate WebSocket connection with authentication ws_url, headers = client.generate_ws_connection( runtime_arn=runtime_arn ) try: async with websockets.connect(ws_url, additional_headers=headers) as ws: # Send message await ws.send(json.dumps({"inputText": "Hello!"})) # Receive response response = await ws.recv() print(f"Received: {response}") except websockets.exceptions.InvalidStatus as e: print(f"WebSocket handshake failed with status code: {e.response.status_code}") print(f"Response headers: {e.response.headers}") print(f"Response body: {e.response.body.decode()}") except Exception as e: print(f"Connection failed: {e}") if __name__ == "__main__": asyncio.run(main())
클라이언트를 실행하여 배포된 에이전트를 테스트합니다.
python websocket_agent_client_sigv4_headers.py
성공: 다음과 같은 응답이 표시됩니다.
Received: {"echo":{"inputText":"Hello!"}}
미리 서명된 URL을 사용하여 연결(쿼리 파라미터를 통한 SigV4)
다음 예제에서는 SigV4 쿼리 파라미터를 사용하여 WebSocket URL을 생성하고 연결을 설정하는 방법을 보여줍니다.
from bedrock_agentcore.runtime import AgentCoreRuntimeClient import websockets import asyncio import json import os async def main(): runtime_arn = os.getenv('AGENT_ARN') if not runtime_arn: raise ValueError("AGENT_ARN environment variable is required") client = AgentCoreRuntimeClient(region="us-west-2") # Generate WebSocket pre-signed URL (with SigV4 via query parameters) # wss://...amazonaws.com/runtimes/.../ws?X-Amz-Algorithm=AWS4-HMAC-SHA256 # &X-Amz-Credential=...&X-Amz-Date=...&X-Amz-Expires=300 # &X-Amz-SignedHeaders=...&X-Amz-Signature=... sigv4_url = client.generate_presigned_url( runtime_arn=runtime_arn, expires=300 # 5 minutes ) try: async with websockets.connect(sigv4_url) as ws: await ws.send(json.dumps({"inputText": "Hello!"})) response = await ws.recv() print(f"Received: {response}") except websockets.exceptions.InvalidStatus as e: print(f"WebSocket handshake failed with status code: {e.response.status_code}") print(f"Response headers: {e.response.headers}") print(f"Response body: {e.response.body.decode()}") except Exception as e: print(f"Connection failed: {e}") if __name__ == "__main__": asyncio.run(main())
클라이언트를 실행하여 배포된 에이전트를 테스트합니다.
python websocket_agent_client_sigv4_query_parameters.py
성공: 다음과 같은 응답이 표시됩니다.
Received: {"echo":{"inputText":"Hello!"}}
OAuth를 사용하여 연결
AgentCore 런타임은 WebSocket 연결에 대한 OAuth Bearer 토큰 인증을 지원합니다. OAuth 인증을 사용하려면 Authenticate and authorize with Inbound Auth and Outbound Auth의 JWT 인바운드 권한 부여 및 OAuth 아웃바운드 액세스 샘플 섹션에 설명된 대로 JWT 권한 부여로 에이전트 런타임을 구성해야 합니다. 인바운드 인증 및 아웃바운드 인증으로 인증 및 권한 부여
OAuth 설정을 완료하고 4단계: 보유자 토큰을 사용하여 OAuth 가이드에서 에이전트를 호출한 후 보유자 토큰을 얻은 후에는 해당 토큰을 사용하여 WebSocket 연결을 설정할 수 있습니다. OAuth
OAuth를 사용하는 Python 클라이언트
다음 예제에서는 OAuth를 사용하여 Python에서 WebSocket 연결을 설정하는 방법을 보여줍니다.
from bedrock_agentcore.runtime import AgentCoreRuntimeClient import websockets import asyncio import json import os async def main(): # Get runtime ARN from environment variable runtime_arn = os.getenv('AGENT_ARN') if not runtime_arn: raise ValueError("AGENT_ARN environment variable is required") # Get OAuth bearer token from environment variable bearer_token = os.getenv('BEARER_TOKEN') if not bearer_token: raise ValueError("BEARER_TOKEN environment variable required for OAuth") # Initialize client client = AgentCoreRuntimeClient(region="us-west-2") # Generate WebSocket connection with OAuth ws_url, headers = client.generate_ws_connection_oauth( runtime_arn=runtime_arn, bearer_token=bearer_token ) try: async with websockets.connect(ws_url, additional_headers=headers) as ws: # Send message await ws.send(json.dumps({"inputText": "Hello!"})) # Receive response response = await ws.recv() print(f"Received: {response}") except websockets.exceptions.InvalidStatus as e: print(f"WebSocket handshake failed with status code: {e.response.status_code}") print(f"Response headers: {e.response.headers}") print(f"Response body: {e.response.body.decode()}") except Exception as e: print(f"Connection failed: {e}") if __name__ == "__main__": asyncio.run(main())
클라이언트를 실행하여 배포된 에이전트를 테스트합니다.
python websocket_agent_client_oauth.py
성공: 다음과 같은 응답이 표시됩니다.
Received: {"echo":{"inputText":"Hello!"}}
OAuth를 사용하는 브라우저 JavaScript 클라이언트
브라우저의 기본 WebSocket API는 핸드셰이크 중에 사용자 지정 헤더를 설정하는 메서드를 제공하지 않습니다. 브라우저에서 OAuth 인증을 지원하기 위해 AgentCore 런타임은 WebSocket 핸드셰이크 중에 Sec-WebSocket-Protocol 헤더에 포함된 보유자 토큰을 수락합니다.
토큰은 base64url로 인코딩되고 접두사 base64UrlBearerAuthorization. 뒤에 감시 하위 프로토콜이 붙어야 합니다base64UrlBearerAuthorization.
다음 예제에서는 OAuth를 사용하여 브라우저 JavaScript에서 WebSocket 연결을 설정하는 방법을 보여줍니다.
<!DOCTYPE html> <html> <body> <button onclick="connect()">Connect</button> <div id="output"></div> <script> function connect() { const bearerToken = "your_oauth_token_here"; const runtimeArn = "arn:aws:bedrock-agentcore:us-west-2:accountId:runtime/agent-xyz123"; // Base64url encode token const base64url = btoa(bearerToken) .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=/g, ''); const ws = new WebSocket( `wss://bedrock-agentcore.us-west-2.amazonaws.com/runtimes/${runtimeArn}/ws`, [`base64UrlBearerAuthorization.${base64url}`, "base64UrlBearerAuthorization"] ); ws.onopen = () => ws.send(JSON.stringify({ inputText: "Hello!" })); ws.onmessage = (e) => document.getElementById("output").innerText = e.data; } </script> </body> </html>
참고
이 인증 방법은 사용자 지정 헤더를 설정할 수 없는 브라우저 기반 클라이언트를 위한 것입니다. 브라우저가 아닌 클라이언트(Python, Node.js 서버 등)의 경우 OAuth 클라이언트에 표시된 OAuth 헤더 인증을 OAuth와 함께 사용합니다.
참고
이외의 하위 프로토콜base64UrlBearerAuthorization은 아직 지원되지 않습니다.
중요
다음은 참조 예제입니다. 프로덕션 코드에서 토큰을 하드코딩하는 것은 권장되지 않습니다.
세션 관리
WebSocket 연결에 session_id (X-Amzn-Bedrock-AgentCore-Runtime-Session-Id)를 제공하면(URL 쿼리 파라미터 또는 요청 헤더로) 연결이 격리된 런타임 세션으로 라우팅됩니다. 에이전트는 해당 세션 내에 저장된 대화 컨텍스트에 액세스하여 이전 상호 작용을 참조하여 대화의 연속성을 구현할 수 있습니다. 서로 다른 세션 IDs 별도의 격리된 컨텍스트에 액세스하여 사용자 또는 대화 간의 완전한 격리를 보장합니다.
추적, 정리 및 오류 처리를 포함한 포괄적인 세션 수명 주기 관리는 에이전트를 위한 격리된 세션 사용을 참조하세요.
WebSocket 연결과 함께 세션 사용
WebSocket 연결과 함께 세션을 사용하려면 각 사용자 또는 대화에 대해 고유한 세션 ID를 생성하고 연결을 설정할 때 전달합니다.
예
작은 정보
최상의 결과를 얻으려면 세션 IDs에 UUID 또는 기타 고유 식별자를 사용하여 다른 사용자 또는 대화 간의 충돌을 방지합니다.
관련 WebSocket 연결에 동일한 세션 ID를 사용하면 동일한 대화에서 컨텍스트를 유지하여 에이전트가 이전 상호 작용을 기반으로 하는 일관된 응답을 제공할 수 있습니다.
WebSocket 연결을 사용한 세션 수명 주기
WebSocket 연결의 경우 클라이언트와 에이전트 간에 메시지 활동이 있을 때마다 세션의 유휴 제한 시간이 재설정됩니다. 여기에는 클라이언트에서 에이전트로 데이터 전송, 에이전트에서 클라이언트로 응답 수신 또는 WebSocket ping/pong 프레임과 같은 WebSocket 메시지 교환이 포함됩니다. 즉, 활성 WebSocket 대화는 메시지가 계속 흐르는 한 세션을 활성 상태로 유지하여 지속적인 상호 작용 중에 세션이 조기에 종료되지 않도록 합니다.
수명 주기 설정 구성에 대한 자세한 내용은 Amazon Bedrock AgentCore 수명 주기 설정 구성을 참조하세요. 에이전트 상태를 통해 세션 수명 주기를 직접 제어하려면 런타임 세션 수명 주기 관리를 참조하세요.
런타임 세션 중지
구성 가능한 세션IdleRuntimeSessionTimeout(기본값은 15분) 전에 실행 중인 세션을 중지하려면 실행 중인 세션 중지를 참조하세요.
관찰성
Amazon Bedrock AgentCore 관찰성을 사용하면 Amazon Bedrock AgentCore 런타임에서 호스팅하는 에이전트를 추적, 디버깅 및 모니터링할 수 있습니다. 먼저 Amazon Bedrock AgentCore 런타임 관찰성 활성화의 지침에 따라 CloudWatch 트랜잭션 검색을 활성화합니다. 에이전트를 관찰하려면 Amazon Bedrock AgentCore 에이전트의 관찰성 데이터 보기를 참조하세요.
WebSocket 연결의 경우 추적은 개별 메시지 교환이 아닌 전체 연결 세션을 나타냅니다.
사용자 지정 헤더
사용자 지정 헤더를 사용하면 애플리케이션의 컨텍스트 정보를 초기 WebSocket 연결 시 에이전트 코드로 직접 전달할 수 있습니다. 사용자 지정 헤더 지원, 구성 및 제한에 대한 자세한 내용은 사용자 지정 헤더를 Amazon Bedrock AgentCore 런타임에 전달을 참조하세요.
또한 접두사가 인 헤더는 WebSocket 연결에서 URL 쿼리 파라미터로 전달할 X-Amzn-Bedrock-AgentCore-Runtime-Custom- 수 있습니다.
예를 들어 WebSocket URL에서 사용자 지정 헤더를 쿼리 파라미터로 전달할 수 있습니다.
wss://bedrock-agentcore.<region>.amazonaws.com/runtimes/<agentRuntimeArn>/ws?X-Amzn-Bedrock-AgentCore-Runtime-Custom-TestHeader=query-param-test-value
에이전트 애플리케이션 컨테이너는 다음을 헤더로 수신합니다.
"headers": { "x-amzn-bedrock-agentcore-runtime-custom-testheader": "query-param-test-value" }
부록
보안 고려 사항
작은 정보
모든 런타임 보안 권장 사항에 대한 통합 보기는 AgentCore 런타임의 보안 모범 사례를 참조하세요.
- Authentication
-
모든 WebSocket 연결에는 SigV4 또는 OAuth 2.0을 통한 적절한 AWS 인증이 필요합니다.
- 세션 격리
-
각 세션은 전용 리소스가 있는 격리된 실행 환경에서 실행됩니다.
- 전송 보안
-
모든 연결은 암호화된 통신을 위해 HTTPS를 통해 WSS(WebSocket Secure)를 사용합니다.
- 액세스 통제
-
IAM 정책은 WebSocket 연결 권한 및 특정 에이전트에 대한 액세스를 제어합니다.
문제 해결
일반적인 WebSocket 관련 문제
발생할 수 있는 일반적인 문제는 다음과 같습니다.
- 연결 실패
-
에이전트 애플리케이션이에서 연결 요청을 처리하는지 확인
/ws - 인증 방법 불일치
-
클라이언트가 에이전트가 구성된 것과 동일한 인증 방법(OAuth 또는 SigV4)을 사용하는지 확인합니다.
- 제한 초과로 인해 연결이 종료됨
-
메시지 프레임 속도 또는 메시지 프레임 크기 제한과 같은 제한을 초과하면 연결이 자동으로 닫힙니다. 전체 제한 정보는 Amazon Bedrock AgentCore 할당량을 참조하세요.
- 메시지 프레임 크기 초과
-
메시지 프레임 조각화를 구성하거나 32KB 프레임 크기 제한 미만으로 유지되도록 청킹을 구현합니다. 전송하기 전에 대용량 메시지를 더 작은 청크로 분할
- 상태 확인 실패
-
에이전트 컨테이너가 HTTP 프로토콜 계약에 지정된 대로
/ping엔드포인트를 구현하는지 확인합니다. 이 엔드포인트는 에이전트가 작동하고 요청을 처리할 준비가 되었는지 확인하여 서비스 모니터링 및 자동 복구를 활성화합니다.
오류 처리
WebSocket 연결은 오류 통신에 표준 닫기 코드를 사용합니다. 일반적인 종료 코드는 다음과 같습니다.
-
1000- 일반 종료 -
1001- 사라짐 -
1008- 정책 위반(한도 초과) -
1009- 메시지가 너무 큼(메시지 프레임 크기 제한 초과) -
1011- 서버 오류
WebSocket과 다른 프로토콜 비교
WebSocket을 사용하는 경우:
-
자연스러운 대화 흐름을 위한 즉각적인 오디오 스트리밍을 통한 실시간 음성 대화
-
양방향 audio/text/binary 데이터 흐름(클라이언트에서 에이전트로 또는 그 반대로 데이터 청크 스트리밍)
-
중단 처리(사용자가 대화 중에 에이전트를 중단할 수 있음)
HTTP를 사용해야 하는 경우:
-
양방향 스트리밍이 필요하지 않은 요청-응답 패턴에 대한 HTTP
추가 시작하기 예제
AgentCore 런타임에서 WebSocket 양방향 스트리밍을 사용하는 추가 예제는 WebSocket 양방향 스트리밍 GitHub 샘플을
-
Sonic 구현(Python) : 실시간 오디오 대화, 음성 선택 및 중단 지원을 제공하는 네이티브 Amazon Nova Sonic WebSocket 구현
-
Strands 구현(Python) : 자동 세션 관리 및 도구 통합을 통해 간소화된 실시간 오디오 대화를 위해 Strands BidiAgent를 사용하는 프레임워크 기반 구현
-
에코 구현(Python) : WebSocket 연결 및 인증을 테스트하기 위한 간단한 에코 서버