INTEGRITY Cloudflare Docs

OpenAI GPT function calling with JavaScript and Cloudflare Workers

In this tutorial, you will build a project that leverages OpenAI's function calling feature, available in OpenAI's latest Chat Completions API models.

The function calling feature allows the AI model to intelligently decide when to call a function based on the input, and respond in JSON format to match the function's signature. You will use the function calling feature to request for the model to determine a website URL which contains information relevant to a message from the user, retrieve the text content of the site, and, finally, return a final response from the model informed by real-time web data.

What you will learn


Before you start

All of the tutorials assume you have already completed the Get started guide, which gets you set up with a Cloudflare Workers account, C3, and Wrangler.

1. Create a new Worker project

Create a Worker project in the command line:

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

For setup, select the following options:

Go to your new openai-function-calling-workers Worker project:

cd openai-function-calling-workers

Inside of your new openai-function-calling-workers directory, find the src/index.js file. You will configure this file for most of the tutorial.

You will also need an OpenAI account and API key for this tutorial. If you do not have one, create a new OpenAI account and create an API key to continue with this tutorial. Make sure to store you API key somewhere safe so you can use it later.

2. Make a request to OpenAI

With your Worker project created, make your first request to OpenAI. You will use the OpenAI node library to interact with the OpenAI API. In this project, you will also use the Cheerio library to handle processing the HTML content of websites

npm i openai cheerio

Now, define the structure of your Worker in index.js:

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

Above export default, add the imports for openai and cheerio:

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

Within your fetch function, instantiate your OpenAI client:

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

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

Use wrangler secret put to set OPENAI_API_KEY. This secret's value is the API key you created earlier in the OpenAI dashboard:

npx wrangler secret put <OPENAI_API_KEY>

For local development, create a new file .dev.vars in your Worker project and add this line. Make sure to replace OPENAI_API_KEY with your own OpenAI API key:

OPENAI_API_KEY = "<YOUR_OPENAI_API_KEY>"

Now, make a request to the 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);
	},
};

Review the arguments you are passing to OpenAI:

3. Building your read_website_content() function

You will now need to define the read_website_content function, which is referenced in the tools array. The read_website_content function fetches the content of a given URL and extracts the text from <p> tags using the cheerio library:

Add this code above the export default block in your index.js file:

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);
}

In this function, you take the URL that you received from OpenAI and use JavaScript's Fetch API to pull the content of the website and extract the paragraph text. Now we need to determine when to call this function.

4. Process the Assistant's Messages

Next, we need to process the response from the OpenAI API to check if it includes any function calls. If a function call is present, you should execute the corresponding function in your Worker. Note that the assistant may request multiple function calls.

Modify the fetch method within the export default block as follows:

// ... 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);
}

Check if the assistant message contains any function calls by checking for the tool_calls property. Because the AI model can call multiple functions by default, you need to loop through any potential function calls and add them to the messages array. Each read_website_content call will invoke the read_website_content function you defined earlier and pass the URL generated by OpenAI as an argument. `

The secondChatCompletion is needed to provide a response informed by the data you retrieved from each function call. Now, the last step is to deploy your Worker.

Test your code by running npx wrangler dev and open the provided url in your browser. This will now show you OpenAI’s response using real-time information from the retrieved web data.

5. Deploy your Worker application

To deploy your application, run the npx wrangler deploy command to deploy your Worker application:

npx wrangler deploy

You can now preview your Worker at <YOUR_WORKER>.<YOUR_SUBDOMAIN>.workers.dev. Going to this URL will display the response from OpenAI. Optionally, add the message URL parameter to write a custom message: for example, https://<YOUR_WORKER>.<YOUR_SUBDOMAIN>.workers.dev/?message=What is the weather in NYC today?.

6. Next steps

Reference the finished code for this tutorial on GitHub.

To continue working with Workers and AI, refer to the guide on using LangChain and Cloudflare Workers together or how to build a ChatGPT plugin with Cloudflare Workers.

If you have any questions, need assistance, or would like to share your project, join the Cloudflare Developer community on Discord to connect with fellow developers and the Cloudflare team.