Dev Lounge 精華回顧系列
- 第 1 篇:把架構寫成 Steering,引導 AI Agent
- 第 2 篇:Agent Harness 才是真正的工程護城河
- 第 3 篇:用白話詢問可觀測性資料
- 第 4 篇:以 Bedrock AgentCore 打造 Serverless AR 遊戲
- 第 5 篇:AgentCore 上的多 Agent 量化回測
- 第 6 篇:三分鐘用 Kiro 把部落格變簡報
AWS Hong Kong Summit 2026 · Developer Lounge 精華回顧 · 第 4 / 6 篇
AWS Magazine · 維多利亞港現場報導
現場:中環 swagger 遇上 Serverless 咒術
過去六十年追蹤科技變遷,我站過數百個展場,但很少有地方能媲美 AWS Hong Kong Summit 2026 Developer Lounge 那股電流般的脈動。
倚著維多利亞港壯闊天際,Developer Lounge 是香港奢華與 AWS 高科技工藝的正面碰撞。想像一下:創投與新創創辦人邊喝精品手沖咖啡邊談七位數交易,國際講者交換架構圖,私人開發者聚會裡高風險創投話題此起彼落。資金進進出出,合作即興成形;在霓虹閃爍與中環能量之中,工程師圍在螢幕前,見證純粹的 serverless 咒術。
Lounge 最吸睛的展示?Cyrus Wong 把奢華娛樂與雲端工程合而為一的 demo:咒術迴戰領域展開 AR 遊戲。
「唔錯喎!反應好似我去搶購減價化妝品噉快!當堂順眼好多!」 (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 編排建構的深入實戰架構拆解。
全場焦點:AI 評論員釘崎野薔薇
體驗核心是仿 Kugisaki Nobara(釘崎野薔薇) 打造的 AI 評論員。多模態 AI 視覺驅動,她即時吐槽玩家的手勢、穿搭、姿勢,甚至凌亂的房間。
多語支援與視覺智慧
-
語言:本地粵語、台灣華語、日語與英語。
-
個性:中環高級時尚 × 動畫咒術。
-
模型堆疊:
moonshotai.kimi-k2.5在 Bedrock 自訂 ECR 容器內執行,搭配 AWS Polly 高保真神經語音合成。
系統架構總覽
| 介面 / 功能 | 模型與基礎設施實作 | 關鍵服務堆疊 |
|---|---|---|
| AI 評論員(Nobara) | 透過 moonshotai.kimi-k2.5 進行視覺感知文字推理 |
AWS Bedrock AgentCore Runtime |
| 語音合成(TTS) | 神經粵語、華語、日語、英語 | AWS Polly & Amazon S3 |
| 手勢追蹤 | 60 FPS 的 21 個 3D 地標點 | Google MediaPipe Hands(Client JS) |
| 機器人控制 | 硬體與 3D 模擬器 MQTT 架式 | AWS IoT Core & AWS Lambda |
| 基礎設施 | 100% 基礎設施即程式碼 | AWS CDK(TypeScript) |
逐步實戰執行流程
+-----------------------------------------------------------------------------------+
端到端手勢到語音流程
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
+-----------------------------------------------------------------------------------+
步驟 A:用戶端手勢偵測與 API 信號
瀏覽器執行 hand_tracker.js,以 Google MediaPipe Hands 分析 21 個 3D 地標點、60 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]
}
}
步驟 B:Cognito 授權與 XML Base64 繞道
API Gateway 驗證 token 後,將請求轉發至單體 Flask Lambda(lambda_function.py)。
為避免企業網路代理在傳輸中剝除二進位 multipart 影像資料,commentary.py 將網路攝影機快照嵌入文字 payload 的自訂 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]
步驟 C:Serverless AgentCore Runtime 執行
AWS Bedrock AgentCore Runtime 透過 IAM SigV4 將呼叫路由至自訂容器(domain_commentator_agentcore)。容器內 FastAPI 服務(commentator_agent.py)以 regex 擷取 base64 XML 區塊,重建 Bedrock 的二進位多模態 payload:
# 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]
步驟 D:透過 AgentCore Tool Gateway 派發硬體指令
模型觸發實體動作時,runtime 呼叫 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]
基礎設施即程式碼: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 評論員 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",
},
});
分流式 API Gateway 安全模型
團隊實作分流 REST 模型,解決經典 Web 衝突:標準瀏覽器元素(<img src="...">)無法帶 Bearer header,但寫入操作會消耗 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。
智慧用戶端防護與角色工程
1. 成本防護工作階段邏輯(auth-check.js)
為避免閒置分頁維持 AgentCore socket 連線造成帳單外洩,用戶端每 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. 語音文字清理(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 設定
角色身分完全解耦為標準 Markdown 檔,在 runtime 載入:
-
IDENTITY.md:嗆辣粵語風格與氣質指引。 -
SOUL.md:戰鬥 lore 規則(例如如何吐槽五條悟玩家)。
架構經濟學與隨用隨付
| 架構選擇 | 成本與效率影響 |
|---|---|
| 零閒置計費 | 無對戰進行時 $0.00;無需持續運行的 EC2/ECS 伺服器。 |
| S3 生命週期規則 | 網路攝影機快照與 Polly MP3 音訊串流 7 天後自動刪除。 |
| P2P 視訊 WebRTC | 視訊串流點對點直連;API Gateway WebSocket 僅處理輕量遙測。 |
結語:Developer Lounge 的氛圍
Cyrus Wong 與團隊在 AWS Hong Kong Summit 2026 Developer Lounge 展示的,不只是一款有趣的同人遊戲,更是現代 serverless 設計的實戰課:高時尚、高科技、低延遲、零閒置成本。
夕陽照進中環、點亮維多利亞港時,開發者仍圍在攤位前掃 CDK 儲存庫、測試手勢。這才是 AWS Developer Lounge 真正的精神——把世界級工程、在地文化活力與 serverless 力量,聚在同一個屋簷下。
