AWS Hong Kong Summit 2026 · Developer Lounge Recap

Bedrock AgentCore로 만드는 Serverless AR 게임

AWS Hong Kong Summit 2026 · Developer Lounge 요약 · 6편 중 4편

AWS Magazine · 빅토리아 하버 현장 리포트


현장: Central-district swagger가 Serverless 주술을 만나다

기술 전환을 추적해 온 60년 동안 수백 개의 컨퍼런스 플로어에 서 봤지만, AWS Hong Kong Summit 2026 Developer Lounge의 전기 같은 맥박과 비견될 만한 곳은 거의 없었다.

빅토리아 하버의 펼쳐진 배경에 기대어, Developer Lounge는 홍콩 럭셔리와 AWS 하이테크 공예가 정면으로 충돌하는 장면이었다. 상상해 보라. 벤처캐피털과 스타트업 창업자들이 수제 드립 커피를 마시며 일곱 자리 딜을 닫고, 국제 스피커들이 아키텍처 다이어그램을 주고받고, 프라이빗 개발자 밋업이 고위험 벤처 토크로 웅성거리는 모습. 돈이 들어오고 나가고, 협업이 즉석에서 형성되고, 네온 빛과 Central-district 에너지 한가운데에서 빌더들이 화면 주위에 모여 순수한 serverless 주술을 목격했다.

라운지의 최대 볼거리? Cyrus Wong이 럭셔리 엔터테인먼트와 클라우드 엔지니어링을 한데 모은 데모: 주술회전 Domain Expansion AR Game.

「唔錯喎!反應好似我去搶購減價化妝品噉快!當堂順眼好多!」 (Not bad! Your reaction is almost as fast as me grabbing a limited-edition bag in Shibuya!)

카메라 앞에서 고죠 사토루의 Unlimited Void(무량공처) 또는 료멘 스쿠나의 Malevolent Shrine(복마어주자) 수인을 취하면, 화면이 3D 파티클 이펙트로 폭발하고 실제(또는 시뮬레이션) 휴머노이드 로봇이 쿵푸 자세를 취한다—전부 패션에 집착하는 현지 광둥어로 톡톡 쏘아대는 AI 해설자가 라이브로 나레이션한다.

다음은 이 팬메이드 애플리케이션이 AWS Bedrock AgentCore, AWS CDK, serverless 오케스트레이션으로 어떻게 구축되었는지에 대한 깊고 hands-on 아키텍처 분석이다.


쇼의 스타: AI 해설자 Nobara

경험의 심장부에는 Kugisaki Nobara(쿠기사키 노바라)를 모델로 한 AI 해설자가 있다. 멀티모달 AI 비전으로 구동되며, 플레이어의 손동작, 옷차림, 자세, 어수선한 방을 실시간으로 디스한다.

다국어 지원 & Vision Intelligence

  • 언어: 로컬 광둥어, 대만 만다린, 일본어, 영어.

  • 성격: Central-district 하이 패션이 애니메이션 주술과 만난다.

  • 모델 스택: Bedrock의 커스텀 ECR 컨테이너에서 실행되는 moonshotai.kimi-k2.5와, 고충실도 뉴럴 음성 합성을 위한 AWS Polly.

시스템 아키텍처 요약

표면 / 기능 모델 & 인프라 구현 핵심 서비스 스택
AI Commentator (Nobara) moonshotai.kimi-k2.5를 통한 시각 인식 텍스트 추론 AWS Bedrock AgentCore Runtime
Voice Synthesis (TTS) 뉴럴 광둥어, 만다린, 일본어, 영어 AWS Polly & Amazon S3
Gesture Tracking 60 FPS에서 21개 3D Landmark Google MediaPipe Hands (Client JS)
Robotics Control 하드웨어 & 3D 시뮬레이터 MQTT 자세 AWS IoT Core & AWS Lambda
Infrastructure 100% Infrastructure as Code AWS CDK (TypeScript)

Step-by-Step Hands-On 실행 흐름

+-----------------------------------------------------------------------------------+
END-TO-END GESTURE TO SPEECH FLOW

1. [ Browser Client ] -- MediaPipe 60FPS --> [ API Gateway ]
2. [ API Gateway ] -- Cognito JWT --> [ Monolithic Lambda ]
3. [ Monolithic Lambda ] -- XML multimodal payload --> [ AgentCore Runtime ]
4. [ AgentCore Runtime ] --> [ AWS Polly ] neural speech
5. [ AWS Polly ] --> [ S3 Audio Bucket ] --> browser playback
+-----------------------------------------------------------------------------------+

Step A: 클라이언트 측 제스처 감지 & API 시그널링

브라우저는 Google MediaPipe Hands를 사용하는 hand_tracker.js21개 3D landmark60 FPS로 분석한다. 제스처(예: Malevolent Shrine)가 검증되면, battle.js가 Cognito Bearer JWT와 함께 Amazon API Gateway로 POST 요청을 보낸다.

// battle.js: Dispatching recognized gesture to API Gateway[cite: 1]
async function triggerCursedTechnique(techniqueName) {
    const token = await getCognitoAccessToken(); // High-security Bearer Token[cite: 1]
    try {
        const response = await fetch("/api/trigger-technique", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "Authorization": `Bearer ${token}`
            },
            body: JSON.stringify({
                technique: techniqueName, // e.g. "malevolent_shrine"[cite: 1]
                robotId: "all",
                sessionId: "mcpserver"
            })
        });
        const result = await response.json();
        playCommentaryAudio(result.audioUrl); // Play resulting neural voice track[cite: 1]
    } catch (err) {
        console.error("Failed to execute server-side technique orchestration:", err); //[cite: 1]
    }
}

Step B: Cognito Authorization & XML Base64 Bypass

API Gateway가 토큰을 검증하면, 요청을 모놀리식 Flask Lambda(lambda_function.py)로 전달한다.

기업 네트워크 프록시가 전송 중 바이너리 multipart 이미지 데이터를 벗겨내는 것을 막기 위해, commentary.py는 웹캠 스냅샷을 텍스트 페이로드의 커스텀 XML 태그 안에 임베드한다.

# commentary.py: Packaging snapshots inside XML text tags[cite: 1]
def generate_ai_commentary(content_block, session_id="mcpserver", image_base64_p1=""):
    if image_base64_p1:
        content_block += f"\n<p1_webcam_base64_jpeg>{image_base64_p1}</p1_webcam_base64_jpeg>" #[cite: 1]

    agent_client = boto3.client("bedrock-agentcore", region_name="us-east-1") #[cite: 1]

    payload_dict = {
        "prompt": content_block,
        "session_id": session_id
    }

    response = agent_client.invoke_agent_runtime(
        agentRuntimeArn=os.environ.get("AGENTCORE_RUNTIME_ARN"),
        runtimeSessionId=session_id,
        payload=json.dumps(payload_dict).encode("utf-8")
    )
    return response.get("response").read().decode("utf-8") #[cite: 1]

Step C: Serverless AgentCore Runtime 실행

AWS Bedrock AgentCore Runtime은 IAM SigV4를 통해 호출을 커스텀 컨테이너(domain_commentator_agentcore)로 라우팅한다. 컨테이너의 FastAPI 서비스(commentator_agent.py)는 regex로 base64 XML 블록을 추출하고 Bedrock용 바이너리 멀티모달 페이로드를 재구성한다.

# commentator_agent.py: Unwrapping XML image parts inside container[cite: 1]
@app.post("/invocations")
async def invoke_agent(request: Request):
    body = await request.json()
    prompt_text = body.get("prompt", "")

    p1_pattern = re.compile(r"<p1_webcam_base64_jpeg>(.*?)</p1_webcam_base64_jpeg>", re.DOTALL) #[cite: 1]
    p1_match = p1_pattern.search(prompt_text)

    image_b64_p1 = ""
    if p1_match:
        image_b64_p1 = p1_match.group(1).strip()
        prompt_text = p1_pattern.sub("", prompt_text).strip() # Clean text prompt[cite: 1]

    img_bytes_p1 = base64.b64decode(image_b64_p1)
    message_content = [
        {"text": "Player 1 webcam snapshot:"},
        {"image": {"format": "jpeg", "source": {"bytes": img_bytes_p1}}},
        {"text": prompt_text}
    ]

    response = await strands_agent.invoke_async(message_content) #[cite: 1]
    return JSONResponse(content={"response": str(response)}, status_code=200) #[cite: 1]

Step D: AgentCore Tool Gateway를 통한 하드웨어 디스패치

모델이 물리적 액션을 트리거하면, 런타임이 AgentCore Tool Gateway(bedrockagentcore.Gateway)를 호출하고, 이는 IAM SigV4를 통해 robot_tool_lambda.py를 호출해 AWS IoT Core로 MQTT 명령을 발행한다.

# robot_tool_lambda.py: Stripping tool prefix and invoking IoT Core[cite: 1]
def lambda_handler(event, context):
    full_tool_name = event.get("tool_name", "") # e.g., "robot-only-mcp-lambda___robot_wave"[cite: 1]
    local_tool_name = full_tool_name.split("___")[-1] if "___" in full_tool_name else full_tool_name #[cite: 1]

    if local_tool_name == "robot_wave":
        iot_client = boto3.client("iot-data")
        iot_client.publish(
            topic="arn:aws:iot:us-east-1:123456789012:topic/robot_1/topic",
            qos=1,
            payload=json.dumps({"action": "wave_hand", "timestamp": int(time.time())})
        )
        return {"status": "SUCCESS", "message": "Robot hand wave triggered."} #[cite: 1]


Infrastructure as Code: CDK 핵심 패턴

인프라를 반복 가능하고, 현대적이며, 깨끗하게 유지하기 위해 전체 시스템은 AWS CDK로 모델링된다.

1. 중앙화된 Tool Gateway Construct (robot-tool-gateway.ts)

// Constructing the Tool Gateway with IAM SigV4 security[cite: 1]
export class RobotToolGatewayConstruct extends Construct {
  public readonly robotToolFunction: PythonFunction;
  public readonly gateway: bedrockagentcore.Gateway;

  constructor(scope: Construct, id: string, props: RobotToolGatewayConstructProps) {
    super(scope, id);

    this.robotToolFunction = new PythonFunction(this, "RobotToolFunction", {
      entry: path.join(__dirname, "../../../mcp_server"),
      runtime: SHARED_PYTHON_RUNTIME,
      index: "robot_tool_lambda.py",
      handler: "lambda_handler",
      timeout: Duration.seconds(30),
    });

    this.gateway = new bedrockagentcore.Gateway(this, "RobotToolGateway", {
      description: "AgentCore gateway fronting the robot Lambda tools",
      authorizerConfiguration: bedrockagentcore.GatewayAuthorizer.usingAwsIam(), // SigV4 Auth[cite: 1]
    });

    this.gateway.addLambdaTarget("RobotToolLambdaTarget", {
      gatewayTargetName: "robot-only-mcp-lambda",
      lambdaFunction: this.robotToolFunction,
      toolSchema: bedrockagentcore.ToolSchema.fromLocalAsset(materializeRobotToolSchemaAsset()),
    });
  }
}

2. Serverless AgentCore Commentator Runtime (domain-expansion-serverless.ts)

// Deploying commentator runtime with cost-aware lifecycles[cite: 1]
const runtime = new agentcore.Runtime(this, "Runtime", {
  runtimeName: "domain_commentator_agentcore",
  agentRuntimeArtifact: agentcore.AgentRuntimeArtifact.fromAsset(
    path.join(__dirname, "../../../domain-expansion-commentator-agentcore"),
    { platform: Platform.LINUX_ARM64 }
  ),
  authorizerConfiguration: agentcore.RuntimeAuthorizerConfiguration.usingIAM(),
  lifecycleConfiguration: {
    idleRuntimeSessionTimeout: Duration.seconds(120), // 2 min idle timeout[cite: 1]
    maxLifetime: Duration.seconds(900),              // 15 min max session[cite: 1]
  },
  tracingEnabled: true,
  environmentVariables: {
    BEDROCK_MODEL_ID: "moonshotai.kimi-k2.5",
  },
});


Split-Route API Gateway 보안 모델

팀은 고전적인 웹 충돌을 해결하기 위해 split-route REST 모델을 구현했다. 표준 브라우저 요소(<img src="...">)는 Bearer 헤더를 전달할 수 없지만, 쓰기 연산은 LLM 비용을 발생시킨다.

// Public vs Protected Endpoint Configuration[cite: 1]
const restApi = new apigateway.RestApi(this, "DomainExpansionRestApi", {
  restApiName: "Domain Expansion Serverless REST API",
});

const restAuthorizer = new apigateway.CognitoUserPoolsAuthorizer(this, "DomainExpansionRestApiAuthorizer", {
  cognitoUserPools: [props.userPool],
});

// 🔓 PUBLIC READ-ONLY ENDPOINTS (No Cognito Token required)[cite: 1]
apiResource.addResource("get-snapshot").addMethod("GET", lambdaIntegration, {
  authorizationType: apigateway.AuthorizationType.NONE, //[cite: 1]
});

// 🔒 PROTECTED WRITE ENDPOINTS (Strict Cognito Validation)[cite: 1]
apiResource.addResource("trigger-technique").addMethod("POST", lambdaIntegration, {
  authorizationType: apigateway.AuthorizationType.COGNITO, // Edge validation[cite: 1]
  authorizer: restAuthorizer,
});


관찰 가능성 & 엔터프라이즈 추적

관찰 가능성은 CloudWatch Vended Logs 네임스페이스와 AWS X-Ray로 처리된다.

// Configuring Vended Logs namespace for AgentCore[cite: 1]
const applicationLogGroup = new logs.LogGroup(scope, `${id}ApplicationLogGroup`, {
  logGroupName: `/aws/vendedlogs/bedrock-agentcore/gateway/APPLICATION_LOGS/${gateway.gatewayId}`, //[cite: 1]
  retention: logs.RetentionDays.THREE_DAYS,
});

이는 단일 X-Ray 맵에서 엔드투엔드 분산 추적을 보장한다.

Browser Gesture → API Gateway → Lambda Router → AgentCore Container → Strands LLM → AWS Polly TTS.


Smart Client Guards & Character Engineering

1. Cost-Guarding Session Logic (auth-check.js)

유휴 브라우저 탭이 AgentCore 소켓을 열어 두어 청구 누수가 생기는 것을 막기 위해, 클라이언트는 디바이스에서 30초마다 Cognito JWT를 검사한다.

Session Expired = currentTime >= jwt.exp

만료되면 활성 WebSocket을 즉시 닫는다.

function checkSessionGuard() {
    const token = getCognitoToken();
    if (isTokenExpired(token)) {
        if (webSocketConnection) webSocketConnection.close(); // Prevent billing leaks[cite: 1]
        triggerLocalLogout();
    }
}
setInterval(checkSessionGuard, 30000); // 0 cloud compute overhead[cite: 1]

2. Speech Text Sanitization (commentary_tts.py)

모델 출력을 AWS Polly에 전달하기 전에, BeautifulSoup으로 Markdown 기호(**bold**, #)를 깨끗한 평문으로 변환해 Polly가 문법을 소리 내어 읽지 않도록 한다.

import markdown
from bs4 import BeautifulSoup

def sanitize_text_for_tts(raw_text):
    html_formatted = markdown.markdown(raw_text)
    return BeautifulSoup(html_formatted, "html.parser").get_text() # Clean plain text[cite: 1]

3. Soul as Code Configuration

캐릭터 정체성은 런타임에 로드되는 표준 Markdown 파일로 완전히 분리된다.

  • IDENTITY.md: 톡톡 쏘는 광둥어 스타일과 태도에 대한 지시.

  • SOUL.md: 전투 lore 규칙(예: 고죠 사토루 사용자를 어떻게 디스할지).


아키텍처 경제학 & Pay-As-You-Go

아키텍처 선택 비용 & 효율 영향
Zero Idle Billing 활성 매치가 없을 때 $0.00; 상시 EC2/ECS 서버 없음.
S3 Lifecycle Rules 웹캠 스냅샷 & Polly MP3 오디오 스트림 7일 후 자동 삭제.
P2P Video WebRTC 비디오는 peer-to-peer로 직접 스트리밍; API Gateway WebSocket은 가벼운 텔레메트리만 처리.

맺음말: Developer Lounge의 바이브

Cyrus Wong과 팀이 AWS Hong Kong Summit 2026 Developer Lounge에서 보여 준 것은 재미있는 팬 게임 이상이었다. 그것은 현대 serverless 설계의 마스터클래스였다—하이 패션, 하이테크, 저지연, 제로 유휴 비용.

해가 Central 너머로 지며 빅토리아 하버를 비출 때도, 개발자들은 여전히 부스 주변에 모여 CDK 저장소를 훑고 수인을 테스트하고 있었다. 그것이 AWS Developer Lounge의 진짜 정신이다—세계적 수준의 엔지니어링, 생생한 로컬 문화, serverless 파워를 한 지붕 아래 모으는 것.