hero_picture
Cover Image for API Gatewayのストリーミングレスポンスを試し、ついでにStreamlitもサーバーレスにする。

API Gatewayのストリーミングレスポンスを試し、ついでにStreamlitもサーバーレスにする。

こんにちは、クラウドソリューション事業部の中村です。

API Gatewayにストリーミングレスポンスをサポートするアップデートがきました。

アップデートで追加された機能を使うことにより、特定のケースにおいてはStreamlitをホストするEC2やECSが不要になりました。

本記事では、API Gatewayのストリーミングレスポンスの動作検証とStliteを用いて、サーバレスでエージェントを呼び出せるか。について書いていきます。

参考: Building responsive APIs with Amazon API Gateway response streaming

構成図

Lambda

ドキュメントとAWSのブログを参考に実装していきます。

ドキュメント : Stream the integration response for your proxy integrations in API Gateway

1import { pipeline } from 'node:stream/promises'
2
3export const handler = awslambda.streamifyResponse(async (event, responseStream, _context) => {
4
5	// AgentCore呼び出しコード(省略)
6	
7  const response = await client.send(command)
8  responseStream = awslambda.HttpResponseStream.from(responseStream, {
9    statusCode: 200,
10    headers: {
11      'Content-Type': 'application/json',
12      'Access-Control-Allow-Origin': '*',
13    }
14  })
15
16  await pipeline(response.response, responseStream)
17
18  responseStream.end()
19})

Stlite (Streamlit)

手軽にPythonでWebアプリケーションを作成できるStreamlitを、WebAssembly (WASM)を使用することで、Webブラウザ上で実行できるようにするプロジェクトです。

Webブラウザ上で完結するため、CloudFront + S3の構成で ほぼ Streamlitを実行できるようになります。

「Stliteでboto3使えばいいんじゃないの?」と思われた方もいらっしゃると思いますが、WASMの制約で動作しませんでした。

Stlite Sharing: https://edit.share.stlite.net/

Stlie(github): https://github.com/whitphx/stlite

API Gateway

今回の目玉です。

リリースブログに Cloudformation のテンプレートが掲載されていましたので、それを参考に AWS CDK に起します。

L2コンストラクターで設定できない値だったので、addPropertyOverrideを使用してプロパティを上書きします。

1// 略
2constructor(scope: Construct, id: string, props: BackendConstructProps) {
3	super(scope, id)
4
5	const proxyLambda = new lambdaNodejs.NodejsFunction(this, 'ProxyLambda', {
6		// 省略   
7	})
8
9	const apiGateway = new apigateway.RestApi(this, 'ApiGateway')
10	const apiGatewayResource = apiGateway.root.addResource('agent-core-invoke',{
11		// 省略
12	})
13	const proxyLambdaIntegration = new apigateway.LambdaIntegration(proxyLambda)
14	const apiGatewayMethod = apiGatewayResource.addMethod('POST', proxyLambdaIntegration, {
15		authorizationType: apigateway.AuthorizationType.NONE,
16	})
17
18	const region = cdk.Stack.of(this).region
19	const streamingUri = `arn:aws:apigateway:${region}:lambda:path/2021-11-15/functions/${proxyLambda.functionArn}/response-streaming-invocations`
20
21	const cfnApiGatewayMethod = apiGatewayMethod.node.defaultChild as apigateway.CfnMethod
22	cfnApiGatewayMethod.addPropertyOverride('Integration.Uri', streamingUri)
23	cfnApiGatewayMethod.addPropertyOverride('Integration.ResponseTransfer', 'STREAM')
24}

動作確認してみる

📣
スマートフォンではGIFが再生されないようです、すみません。

生成されたレスポンスがパラパラ出てくれていますね!

サンプルエージェントですので、<thinking> が出ていることについては目を瞑っていただけると幸いです。

まとめ

API Gateway のストリーミングレスポンスを活用することで、EC2 や ECS を用意せずに、慣れたフレームワーク・UIからBedrock AgentCoreを呼び出せることが分かりました。

一方で、初回アクセス時には WASM の初期化処理に時間がかかったり、EC2やECSと比較して動作が重く感じる事もありましたが、個人利用であれば十分だと感じました。(私の環境の問題もあります)

ここまで読んでいただきありがとうございました。

https://github.com/mu7889yoon/examples/tree/main/agent-core-stlite-sse


👉️ AWS Graviton のことなら acCloud にお任せください!
👉️ AWS Graviton のことなら acCloud にお任せください!