この記事のゴール
- Bubble だけで 自前の知識データ(PDF/TXT等)を検索して回答 させる。
- 知識データに無ければWeb検索も併用 して回答させる。
- エラーになりやすい API Connector の具体設定とJSON例 を網羅。
この記事を手順どおり進めれば “動く” ところまで行けます。
全体像(アーキテクチャ)
ユーザー ─▶ Bubble(API Connector)
├─▶ Files API:ファイルをOpenAIへアップロード
├─▶ Vector Stores API:ベクターストア作成・ファイル登録
└─▶ Responses API:
・File Searchツールで社内文書を検索
・必要ならWeb Searchツールでネット検索
・最終回答を返却
事前準備
- OpenAI APIキーを取得(環境変数やBubbleのSecretsに保存推奨)
- Bubbleプラグイン API Connector をインストール
- (任意)ファイルをアップロードさせるための File Uploader 要素を用意
用語整理
用語 | 役割 | ざっくり説明 |
---|---|---|
Files API | 生ファイルアップロード | PDF/TXTなどをOpenAIに送る |
Vector Store | インデックス格納庫 | ファイルを分割・埋め込みして検索できる状態にする箱 |
File Search | 内蔵ツール | Vector Storeに入っている文書から関連箇所を検索 |
Responses API | 本体 | モデル呼び出し+ツール実行+回答生成 |
Web Search | 内蔵ツール | 必要に応じてインターネット検索を実行 |
実装ステップ一覧
- Files API:ファイルをアップロード →
file_id
を取得 - Vector Store 作成 →
vs_id
を取得 - Vector Store にファイルを紐付け(
file_id
を登録) - (必要なら)ステータス確認ポーリング:
in_progress
→completed
になるまで待つ - Responses API:
- ① ファイルのみ検索(File Search ツールだけ)
- ② ファイル+Web検索(Web Search ツールも追加)
- 回答テキストを表示/保存
1. Files API:ファイルアップロード
API Connector 設定例
- Name:
fileUpload
- Use as: Action / Data type: JSON
- Method: POST
- URL:
https://api.openai.com/v1/files
- Headers:
Authorization: Bearer YOUR_API_KEY
- Body type: Form-data
- Param1:
purpose
(text) =assistants
- Param2:
file
(file) = FileUploader の value(Send file ✓)
- Param1:
※
purpose
にresponse
を入れると 400 エラーになります。必ずassistants
。
レスポンス例
{
"object": "file",
"id": "file-QLQLjixUpfsuP5Zr6xqJCX",
"purpose": "assistants",
"filename": "manual.pdf",
"bytes": 11877,
"status": "processed"
}
この id
(例:file-QLQL...
)を保存します。
2. Vector Store 作成
- Name:
vectorStore_create
- Method: POST
- URL:
https://api.openai.com/v1/vector_stores
- Headers:
Authorization: Bearer YOUR_API_KEY
,Content-Type: application/json
- Body (raw JSON):
{ "name": "MyKB" }
返却の id
(例:vs_6884...
)を保存。
3. Vector Store にファイルを追加
単一ファイル(最も簡単)
- Name:
vs_add_file
- Method: POST
- URL:
https://api.openai.com/v1/vector_stores/[vs_id]/files
[vs_id]
はパラメータ化。Initialize時に一旦実値を入れる。
- Headers:
Authorization: Bearer ...
,Content-Type: application/json
- Body:
{ "file_id": "file-QLQLjixUpfsuP5Zr6xqJCX" }
レスポンス例(最初は status: "in_progress"
)
{
"id": "file-QLQLjixUpfsuP5Zr6xqJCX",
"object": "vector_store.file",
"status": "in_progress"
}
4. ステータス確認(ポーリング)
- Name:
vs_get_file_status
- Method: GET
- URL:
https://api.openai.com/v1/vector_stores/[vs_id]/files/[file_id]
- Headers: Authorization だけでOK
status
が completed
になったら検索に使えます。Bubbleでは Backend workflow(API Workflow)で数秒おきに再実行するのが楽です。
5-A. 回答取得:ファイルだけで検索する
API Connector 設定(Responses API)
- Name:
responses_ask_local
- Method: POST
- URL:
https://api.openai.com/v1/responses
- Headers:
Authorization: Bearer ...
,Content-Type: application/json
- Body (raw JSON):
{
"model": "gpt-4o-mini",
"input": "<質問文>",
"tools": [
{
"type": "file_search",
"vector_store_ids": ["<vs_id>"],
"max_num_results": 3
}
]
}
max_num_results
: 取り出すチャンク上限(3〜8くらいで調整)。
レスポンスの取り出しresponse.output_text
相当の場所をBubbleでパースします。公式SDKと違い、Raw JSON内の output[0].content[0].text.value
等を使うことになります(仕様は随時変わるため、Initialize時に確認)。
5-B. 回答取得:ファイル+Web検索も使う
ファイルに無いときだけWeb検索させたいなら、ツールを2つ指定します。
{
"model": "gpt-4o-mini",
"input": "<質問文>",
"tools": [
{
"type": "file_search",
"vector_store_ids": ["<vs_id>"],
"max_num_results": 3
},
{ "type": "web_search" }
]
}
web_search_options
など未サポート項目を入れると 400 エラーになります。必要最小限でOK。
優先順位を明示したいときのプロンプト例
まずVector Store内の情報だけで回答してください。該当が無い場合のみweb_searchツールを使い、上位2〜3件を要約して補足してください。見つからない場合は「見つからない」と答えてください。
2段階方式(アプリ側制御)も有効
1回目:File Searchだけで投げる → 返答が空/曖昧なら
2回目:Web Searchも付けて再質問
6. 画面表示・保存
- Bubbleのテキスト要素に APIレスポンスのフィールドをバインド
- チャット履歴を作るなら DB に質問・回答・参照ファイルIDを保存
- 引用元(annotations)のURLやファイル名を表示して透明性UP
エラー対策まとめ
症状 | 原因 | 対処 |
---|---|---|
400 invalid_json | JSONにコメント/余計なカンマ | コメント禁止、末尾カンマ削除 |
400 purpose エラー | purpose が assistants 以外 | assistants に修正 |
400 unknown_parameter | 未対応フィールド(例: web_search_options) | そのキーを削除 |
401 Unauthorized | Authorizationヘッダー不備/キー違い | Bearer <space> API_KEY を再確認 |
“issue getting the file” | Data typeをFileにしていた/Send file未チェック | Data type=JSON、Send file✓ |
応用:複数Vector Store/メタデータフィルタ
vector_store_ids
は配列。用途や部門ごとにVSを分け、配列で渡すだけ。- 1つのVector Storeに集約してもOK。その場合はファイル登録時に
metadata
を付け、metadata_filter
で絞り込む実装(現状SDKが楽、BubbleでもJSONで可)。
参考プロンプト集
- ファイルのみ回答 添付ファイル群に含まれる情報だけを使って回答してください。根拠が無ければ「該当情報なし」と答えてください。
- ファイル優先+Web補完 まずVector Store内の情報だけで回答し、無い場合にのみweb_searchを実行して補足してください。検索結果はURLを明記し、3件以内に要約してください。
まとめ
- Bubbleでも ノーコードでRAG(簡易版) が組める。
- ポイントは API Connectorでの正しいJSON/ヘッダー設定 と ポーリング。
- Web検索を混ぜるときは
tools
にweb_search
を追加するだけ。 - 精度とコストは
max_num_results
やプロンプト、ファイル分割戦略でチューニング。
必要なら:
- Backend workflow の設定スクショ付き手順
- BubbleのJSON整形Tips(:format as JSON-safe など)
- SupabaseやCloudflare Workerを中継にした高度実装
も追記できます。お気軽にどうぞ!