Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

JavaScript と Cloudflare Workers で OpenAI GPT の function calling を使う

最終更新 Markdown で表示Agent セットアップ

このチュートリアルでは、OpenAI の最新 Chat Completions API モデルで使える OpenAI の function calling 機能を活用するプロジェクトを作ります。

function calling を使うと、AI モデルは入力に応じて関数を呼ぶべきかを判断し、関数のシグネチャに合わせた JSON で応答できます。function calling を使い、ユーザーのメッセージに関連する情報があるウェブサイトの URL をモデルに決めさせ、そのサイトのテキストを取得し、リアルタイムの Web データを踏まえた最終応答を返す流れを作ります。

このチュートリアルで学ぶこと

  • OpenAI の function calling の使い方
  • Cloudflare Worker への OpenAI API の組み込み
  • Cheerio を使ったウェブサイト本文の取得と処理
  • JavaScript での API 応答と function call の扱い
  • Wrangler で API キーを secrets として保存する方法

始める前に

すべてのチュートリアルは、Cloudflare Workers アカウント、C3、および Wrangler のセットアップが完了している前提です。セットアップは Get started ガイド で行います。

1. 新しい Worker プロジェクトを作る

コマンドラインで Worker プロジェクトを作成します。

npm create cloudflare@latest -- openai-function-calling-workers

セットアップでは、次のオプションを選びます。

  • What would you like to start with? では、Hello World example を選びます。
  • Which template would you like to use? では、Worker only を選びます。
  • Which language do you want to use? では、JavaScript を選びます。
  • Do you want to use git for version control? では、Yes を選びます。
  • Do you want to deploy your application? では、No を選びます(デプロイ前にいくつか変更します)。

新しい openai-function-calling-workers Worker プロジェクトへ移動します。

cd openai-function-calling-workers

新しい openai-function-calling-workers ディレクトリ内に、src/index.js ファイルがあります。このチュートリアルの大半では、このファイルを設定します。

このチュートリアルには OpenAI アカウントと API キーも必要です。持っていない場合は、新しい OpenAI アカウントを作成 し、API キーを作成 してから進めてください。あとで使えるよう、API キーは安全な場所に保存してください。

2. OpenAI にリクエストする

Worker プロジェクトができたら、最初のリクエストを OpenAI に送ります。OpenAI API とのやり取りには OpenAI の Node ライブラリを使います。このプロジェクトでは、ウェブサイトの HTML を処理するために Cheerio ライブラリも使います。

npm i openai cheerio

次に、index.js で Worker の骨格を定義します。

export default {
	async fetch(request, env, ctx) {
		// Initialize OpenAI API
		// Handle incoming requests
		return new Response("Hello World!");
	},
};

export default の上に、openaicheerio の import を追加します。

import OpenAI from "openai";
import * as cheerio from "cheerio";

fetch 関数の中で、OpenAI クライアントをインスタンス化します。

async fetch(request, env, ctx) {
  const openai = new OpenAI({
    apiKey: env.OPENAI_API_KEY,
  });

  // Handle incoming requests
  return new Response('Hello World!');
},

wrangler secret putOPENAI_API_KEY を設定します。この secret の値は、先ほど OpenAI ダッシュボードで作成した API キーです。

npx wrangler secret put <OPENAI_API_KEY>

ローカル開発では、Worker プロジェクトに .dev.vars という新しいファイルを作り、次の行を追加します。OPENAI_API_KEY は、自分の OpenAI API キーに置き換えてください。

OPENAI_API_KEY = "<YOUR_OPENAI_API_KEY>"

次に、OpenAI の Chat Completions API へリクエストします。

export default {
	async fetch(request, env, ctx) {
		const openai = new OpenAI({
			apiKey: env.OPENAI_API_KEY,
		});

		const url = new URL(request.url);
		const message = url.searchParams.get("message");

		const messages = [
			{
				role: "user",
				content: message ? message : "What's in the news today?",
			},
		];

		const tools = [
			{
				type: "function",
				function: {
					name: "read_website_content",
					description: "Read the content on a given website",
					parameters: {
						type: "object",
						properties: {
							url: {
								type: "string",
								description: "The URL to the website to read",
							},
						},
						required: ["url"],
					},
				},
			},
		];

		const chatCompletion = await openai.chat.completions.create({
			model: "gpt-4o-mini",
			messages: messages,
			tools: tools,
			tool_choice: "auto",
		});

		const assistantMessage = chatCompletion.choices[0].message;
		console.log(assistantMessage);

		//Later you will continue handling the assistant's response here
		return new Response(assistantMessage.content);
	},
};

OpenAI に渡している引数を確認します。

  • model: OpenAI に使わせたいモデルです。ここでは gpt-4o-mini を使います。
  • messages: 会話に含まれるすべてのメッセージの配列です。最初はユーザーからのメッセージを渡し、あとからモデルの応答を追加します。ユーザーメッセージの内容は、リクエスト URL の message クエリパラメーターか、デフォルトの "What's in the news today?" です。
  • tools: AI モデルが使えるアクションの配列です。この例では、指定したウェブサイトの内容を読む read_website_content だけです。
    • name: 関数名です。ここでは read_website_content です。
    • description: 関数の目的をモデルに伝える短い説明です。省略できますが、ツールを選ぶタイミングの判断に役立ちます。
    • parameters: 関数を表す JSON Schema オブジェクトです。ここでは、必須プロパティ url を持つオブジェクトを含む応答を求めます。
  • tool_choice: 技術的には省略でき、デフォルトは auto です。function call か通常のメッセージ応答のどちらも、OpenAI が返せることを示します。

3. read_website_content() 関数を作る

次に、tools 配列で参照している read_website_content 関数を定義します。read_website_content は、指定した URL の内容を取得し、cheerio ライブラリで <p> タグからテキストを取り出します。

index.jsexport default ブロックの上に、次のコードを追加します。

async function read_website_content(url) {
	console.log("reading website content");

	const response = await fetch(url);
	const body = await response.text();
	let cheerioBody = cheerio.load(body);
	const resp = {
		website_body: cheerioBody("p").text(),
		url: url,
	};
	return JSON.stringify(resp);
}

この関数では、OpenAI から受け取った URL を使い、JavaScript の Fetch API でウェブサイトの内容を取得し、段落テキストを取り出します。次に、この関数をいつ呼ぶかを決めます。

4. アシスタントのメッセージを処理する

次に、OpenAI API の応答を処理し、function call が含まれているかを確認します。function call がある場合は、Worker 内の対応する関数を実行します。アシスタントは複数の function call を要求する場合があります。

export default ブロック内の fetch メソッドを、次のように変更します。

// ... your previous code ...

if (assistantMessage.tool_calls) {
	for (const toolCall of assistantMessage.tool_calls) {
		if (toolCall.function.name === "read_website_content") {
			const url = JSON.parse(toolCall.function.arguments).url;
			const websiteContent = await read_website_content(url);
			messages.push({
				role: "tool",
				tool_call_id: toolCall.id,
				name: toolCall.function.name,
				content: websiteContent,
			});
		}
	}

	const secondChatCompletion = await openai.chat.completions.create({
		model: "gpt-4o-mini",
		messages: messages,
	});

	return new Response(secondChatCompletion.choices[0].message.content);
} else {
	// this is your existing return statement
	return new Response(assistantMessage.content);
}

アシスタントメッセージに function call があるかは、tool_calls プロパティで確認します。AI モデルはデフォルトで複数の関数を呼べるため、想定される function call をループして messages 配列に追加します。各 read_website_content の呼び出しは、先ほど定義した read_website_content 関数を実行し、OpenAI が生成した URL を引数として渡します。

secondChatCompletion は、各 function call で取得したデータを踏まえた応答を返すために必要です。最後のステップは、Worker のデプロイです。

npx wrangler dev を実行し、表示された URL をブラウザーで開いてコードを確認します。取得した Web データのリアルタイム情報を使った、OpenAI の応答が表示されます。

5. Worker アプリケーションをデプロイする

アプリケーションをデプロイするには、npx wrangler deploy コマンドを実行します。

npx wrangler deploy

<YOUR_WORKER>.<YOUR_SUBDOMAIN>.workers.dev で Worker をプレビューできます。この URL にアクセスすると、OpenAI の応答が表示されます。任意で message URL パラメーターを付けて、カスタムメッセージを書けます。例: https://<YOUR_WORKER>.<YOUR_SUBDOMAIN>.workers.dev/?message=What is the weather in NYC today?

6. 次のステップ

このチュートリアルの完成コードは GitHub を参照してください。

Workers と AI の続きは、LangChain と Cloudflare Workers を一緒に使うガイド や、Cloudflare Workers で ChatGPT プラグインを作る方法 を参照してください。

質問がある場合、サポートが必要な場合、プロジェクトを共有したい場合は、Discord の Cloudflare Developer コミュニティに参加し、ほかの開発者や Cloudflare チームとつながってください。

役に立ちましたか?