こんにちは、クラウドソリューション事業部の中村です。
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}動作確認してみる
生成されたレスポンスがパラパラ出てくれていますね!
サンプルエージェントですので、<thinking> が出ていることについては目を瞑っていただけると幸いです。
まとめ
API Gateway のストリーミングレスポンスを活用することで、EC2 や ECS を用意せずに、慣れたフレームワーク・UIからBedrock AgentCoreを呼び出せることが分かりました。
一方で、初回アクセス時には WASM の初期化処理に時間がかかったり、EC2やECSと比較して動作が重く感じる事もありましたが、個人利用であれば十分だと感じました。(私の環境の問題もあります)
ここまで読んでいただきありがとうございました。
https://github.com/mu7889yoon/examples/tree/main/agent-core-stlite-sse
