Cloudflareを使用してゼロから$0コストでAgentic RAG AIアシスタントを構築する方法
管理されたベクトルデータベースに月額20ドルを支払い、コールドスタートするサーバーレス関数でAIチャットボットをホストしているなら、それは間違っています。
自分のポートフォリオにAIアシスタントを追加しようと決めたとき、私には2つの厳しい要件がありました。遅延がゼロであること、そして実行コストが完全に0ドルであることです。
AIアーキテクチャ全体をエッジに移行することで、この両方を達成しました。このチュートリアルでは、Cloudflare Developer Platformを使用して、ゼロからステートフルなAgentic RAG(Retrieval-Augmented Generation)システムを構築する方法を正確に紹介します。
$0 スタックアーキテクチャ
企業レベルのパフォーマンスを維持しながらコストをゼロに保つために、私たちはCloudflareの無料ティアに完全に依存しています。
- Cloudflare Workers: エッジコンピュートランタイム。(1日10万リクエストまで無料)。
- Cloudflare Vectorize: セマンティック検索のためのベクトルデータベース。(月間3000万クエリ次元まで無料)。
- Cloudflare D1: チャット履歴用のサーバーレスSQLiteデータベース。(1日500万行の読み取りまで無料)。
- Cloudflare AI Gateway: LLMリクエストのキャッシュとレート制限の防止用。
単にドキュメントをプロンプトに詰め込むだけの受動的なRAGシステムではなく、私たちはAgentic(エージェント型)システムを構築しています。これは、AIが「ReAct」(推論と行動)ループで実行され、ユーザーの入力に基づいて動的に呼び出すことができるカスタムツールを備えていることを意味します。
ステップ 1: エッジワーカーの初期化
まず、Cloudflare Workerを立ち上げる必要があります。これが私たちのオペレーションの頭脳として機能します。
npm create cloudflare@latest agentic-assistant
cd agentic-assistant
wrangler.toml ファイルを開きます。ここからが魔法の始まりです。D1データベースとVectorizeインデックスをワーカー環境に直接バインドして、ほぼゼロレイテンシで実行されるようにする必要があります。
name = "agentic-assistant"
main = "src/index.ts"
compatibility_date = "2026-05-01"
[[d1_databases]]
binding = "DB"
database_name = "chat_history"
database_id = "your-d1-id"
[[vectorize]]
binding = "KNOWLEDGE_BASE"
index_name = "rag-index"
ステップ 2: ナレッジベースへの取り込み
エージェントが質問に答えられるようになる前に、データが必要です。私は自分の職業的背景、サービス、価格を含むシンプルな rag-data.ts ファイルを作成しました。
このデータをCloudflare Vectorizeに埋め込むために、CloudflareネイティブのWorkers AIテキスト埋め込みモデルを使用します。これは、OpenAI埋め込みAPIを呼び出すよりもはるかに安価(かつ高速)です。
import { Ai } from '@cloudflare/ai';
export default {
async fetch(request, env) {
const ai = new Ai(env.AI);
// 1. エッジでベクトル埋め込みを生成
const { data } = await ai.run('@cf/baai/bge-small-en-v1.5', {
text: "Elvis LiはAIを専門とするソロ・フルスタック・開発者です。"
});
// 2. Vectorizeに直接挿入
await env.KNOWLEDGE_BASE.upsert([{
id: "bio-1",
values: data[0],
metadata: { category: "background" }
}]);
return new Response("Knowledge Base updated!");
}
}
ステップ 3: ツール呼び出しReActループの構築
これがシステムを Agentic にする理由です。標準的なRAGは、ベクトルデータベースを盲目的に検索するだけです。私たちのシステムは、LLMに検索が必要かどうかを 判断 させます。
私はCloudflare AI Gateway経由で Gemini 1.5 Pro を使用しています。利用可能なツールのJSONスキーマをGeminiに提供します。
const tools = [
{
name: "query_knowledge_base",
description: "これを使用して、Elvisに関する事実についてベクトルデータベースを検索します。",
parameters: {
type: "object",
properties: {
query: { type: "string" }
},
required: ["query"]
}
}
];
ユーザーが 「どのようなAIシステムを構築していますか?」 と質問すると、ワーカーはリクエストを傍受し、エージェントループをトリガーします。
- リクエスト (The Request): ワーカーはユーザーのメッセージとツールリストをGeminiに送信します。
- 思考 (The Thought): Geminiは答えを知らないことに気づきますが、
query_knowledge_baseツールが知っていることを認識します。そしてtool_callレスポンスを返します。 - 行動 (The Action - RAG): ワーカーはツール呼び出しを傍受し、Geminiが生成した検索クエリを受け取り、Workers AIを介して埋め込み、Cloudflare Vectorizeにクエリを実行します。
- 解決 (The Resolution): ワーカーはベクトル検索結果をGeminiにフィードバックし、Geminiは自然で人間のような応答を合成します。
これらはすべて、物理的にユーザーの近くに配置された単一のエッジノード内で発生するため、信じられないほど高速な応答時間が実現します。
ステップ 4: Cloudflare D1による状態の永続化
AIが記憶喪失に陥るなら、それは役に立ちません。チャットボットを会話型にするには、メッセージ履歴を保持する必要があります。
外部のPostgreSQLインスタンスをセットアップする代わりに、Cloudflare D1 を使用します。これはDurable Objects上に構築されたSQLiteであり、ワーカーと一緒にエッジで実行されることを意味します。
// エッジでローカルに会話を保存
await env.DB.prepare(`
INSERT INTO messages (session_id, role, content)
VALUES (?, ?, ?)
`).bind(sessionId, 'user', userQuery).run();
すべての着信リクエストにおいて、ワーカーはLLMにアクセスする前に SELECT * FROM messages WHERE session_id = ? を実行してチャット履歴を再構築するだけです。D1はサーバーレスで分散型であるため、このクエリによるオーバーヘッドはほぼゼロです。
結果:エンタープライズグレード、ゼロコスト
Cloudflare Workers、Vectorize、D1を活用することで、高価な管理されたベクトルデータベース、コールドスタートするLambda、専用のデータベースサーバーの必要性を排除できます。
その結果、運用コストが0ドルで、ほぼすべての商用代替手段よりも速く応答する、完全自律型でステートフルなAgentic RAGシステムが完成します。個人のポートフォリオ、スタートアップのランディングページ、または社内ツールを構築している場合、これが2026年の決定的なアーキテクチャとなります。

