OSS版源内をデプロイして、ExApp機能を使ってカスタムアプリを登録してみた。
源内Webには、外部で作ったAIアプリを登録して、源内の画面から実行できるExApp機能があります。
今回は、以前私が構築した、AWSに関する構成相談や概算見積もりを支援するアプリケーション「AWS Specialist」をExAppとして登録してみました。
「AWS Specialist」の詳細は、以下に記載しておりますので、もしご興味のある方は見てみてください。
最初は「APIを用意して、URLとAPIキーを登録すればいけるやろ」と思っていました。実際、そこまで難しい話ではありません。ただ、ちゃんと使える形にしようとすると、タイムアウト、非同期処理、Base64のファイル連携あたりで考えることが出てきます。
この記事では、ExAppを実際に登録してみて分かったことを、実装者目線で整理します。
今回作ったもの
作ったのは、源内WebからAWS Specialistを呼び出すためのExAppです。
ざっくりした構成はこんな感じです。
ExApp登録で便利だったところ
源内Webでは、AIアプリ登録時にリクエスト形式(UI)をJSONで定義できます。これにより、バックエンドをある程度の形式に従って構築すればフロントエンドはローコードで実装できます。
今回は、次の入力項目を用意しました。
| 項目 | UI | 内容 |
|---|---|---|
| AWSに関する相談内容 | テキストエリア | 構成、見積もり、レビュー内容を入力する |
| 相談モード | セレクトボックス | 一般相談、見積もり作成、構成レビューなどを選ぶ |
| 添付ファイル | ファイル選択 | テキスト、CSV、JSON、画像などを添付する |
JSONを登録すると、源内Web側で入力画面が自動生成されます。専用のフロントエンドを作らなくても、チーム管理、認証、AIアプリ一覧、入力画面、実行結果表示の流れにそのまま乗せられます。
これはかなり楽でした。外部AIアプリ側はバックエンドの機能開発に集中して、入口や公開範囲の管理は源内Webに任せられます。
ExAppを構築、登録する上での注意点
ここからは、私がExAppを構築する上での注意点を2つ説明します。
タイムアウトについて
OSS版源内のデフォルトでは、ExAppを中継するAPI GW及びLambdaは29秒でタイムアウトします。即ちExAppがコールされてから29秒以内にレスポンスを返さなければタイムアウトでエラーが発生するということです。
こちらは環境変数(cdk.json)を設定することで300秒まで延長可能です。
(リージョン APIの統合のタイムアウトのクォータに引っかかるため、クォータの引き上げリクエストが必要)
"crossAccountBedrockRoleArn": "",
"exAppInvokeTimeoutSeconds": 29,
"dataRetentionDays": {
"dynamoDbTtl": 364,
"s3FileExpiration": 364
},
ただし昨今のAIアプリにおいては、外部ツールの呼び出しやRAG検索等を行うと、処理時間が5分を超えることはざらにあると思います。
そうした場合は、非同期処理を実装しましょう。
非同期処理について
源内のAIアプリAPI仕様では、同期だけでなく非同期実行も想定されています。
同期実行では、初回リクエストのレスポンスにそのまま結果を返します。
{
"outputs": "構成レビューの結果です。"
}
一方、非同期実行では、初回リクエストでは受付結果を返し、結果取得用のURLを渡します。
{
"outputs": "",
"request_id": "request-123",
"status": "PENDING",
"status_url": "https://example.com/requests/request-123/status"
}
その後、源内側はstatus_urlを使って状態を確認します。ExApp側は、処理状態に応じてPENDING、IN_PROGRESS、COMPLETED、ERRORのようなステータスを返します。
この形にしておくと、初回リクエストでは「受け付けた」ことだけを返し、実処理は裏側で進められます。
非同期処理の流れとしては以下のようになります。
源内Web(Lambda)は、レスポンスコード202及びstatus_urlを受け取ると、SQSとLambdaを使用したポーリングジョブを起動します。そして定期的にExAppに進行状況をポーリングし、結果をDynamoDBに格納。
クライアントはそのDynamoDBを参照して結果を取得するという流れです。
恐らく大半のAIアプリでは処理時間が5分近く、もしくは超過すると考えられるため、この非同期処理は源内を扱う上では何度も利用する処理になりそうです。
添付ファイルについて
ExAppでは、添付ファイルを設定することができます。
ただし、源内からExApp APIへファイルを送る場合、ファイル内容はBase64エンコードされた文字列としてリクエストに含まれます。
そのため、ファイル入力を付けるなら、少なくとも次の制約は見ておいた方がよいです。
- API GatewayやALBなど入口の上限
- Lambdaなど実行基盤のペイロード上限
- WAFを入れる場合の検査サイズ
- 複数ファイルを同時に送った場合の総量
特に気をつけるべきはWAFの検査サイズ上限でしょうか。
WAFにはリクエストボディ内で検査できるデータ量に上限があり、それ以上のデータは検査されないという仕様があります。
リクエスト本文の検査サイズ制限とは、AWS WAF が検査できるリクエスト本文の最大サイズです。Web リクエストの本文がこの制限を超えると、基盤となるホストサービスは、制限内のコンテンツのみを AWS WAF に転送して検査します。
Application Load BalancerとAWS AppSyncの場合、制限は8KB(8,192バイト)に固定されています。
CloudFront、API Gateway、Amazon Cognito、App Runner、Verified Access、およびAmazon Bedrock AgentCore Gatewayの場合、デフォルトの制限は16 KB(16,384バイト)です。この制限は、各リソースタイプごとに16 KBずつ増やすことができ、最大64 KBまで設定可能です。設定オプションは、16 KB、32 KB、48 KB、および64 KBです。
また、WAFを使用する際によく使われるManaged RulesであるCommon Rule Setには、リクエストボディのサイズが8KBを超過する場合そのリクエストをブロックするSizeRestrictions_BODYがデフォルトで有効化されています。
そのため、「開発/検証環境ではWAFを利用していなかったが、本番で適用した際急にリクエストがブロックされる」的なことが起こり得ますので、十分に注意しましょう。
AIアプリに欲しい機能と源内ExAppの対応状況
最後にAIアプリを構築する上で個人的に欲しい機能とExAppにおける対応状況をまとめてみました。
ストリーミング系処理については、源内Webを間に挟んでいるため仕方ないでしょう。
| 機能 | ExAppでの対応 | コメント |
|---|---|---|
| ファイル入力 | 対応 | Base64送信になるため、ファイルサイズとAPI上限を考慮した設計が必要 |
| Markdown出力 | 対応 | 回答本文をoutputsで返せば、源内Web側で表示しやすい |
| ファイル出力 | 対応 | 仕様に合わせた返却形式と、ファイル保存方式の設計が必要 |
| 会話継続 | 対応 |
sessionIdや会話履歴を、バックエンド側のセッションと対応させる |
| 過去会話の再開 | 対応 | 保存済みのsessionIdや会話履歴を使って、バックエンド側のセッションを復元する |
| リアルタイムストリーミング | 非対応 | 現状のExApp連携では、逐次トークン表示はできず、完了後の結果表示になる |
| 思考過程やツール実行状況の逐次表示 | 非対応 | 表示したい場合は、ステータス取得APIや結果保存形式を追加設計する必要がある |
まとめ
ExAppについて、実際に構築してみた結果「思ったより簡単だな。」というのが正直な感想です。何よりドキュメントがしっかりしているため、迷うことなく実装を進めることができました。デジタル庁に感謝ですね。
話は変わりますが、皆様はAWS Summit Japan 2026での源内についてのセッションはご覧になられましたでしょうか?まだ見られていないという方は以下リンクからぜひ資料だけでも見ることをお勧めします。純粋にすげー...ってなりました。





