Skip to content

Instantly share code, notes, and snippets.

@andreas-kater
Created September 11, 2025 14:12
Show Gist options
  • Save andreas-kater/705c4f2c2d2b1323bc93b80709dce83d to your computer and use it in GitHub Desktop.
Save andreas-kater/705c4f2c2d2b1323bc93b80709dce83d to your computer and use it in GitHub Desktop.
Recursive ChatGPT function calling
import OpenAI from 'openai';
import 'dotenv/config';
//Instructions to run:
// 1. npm install openai dotenv
// 2. create .env file with OPENAI_API_KEY=yourkey
// 3. node index.js
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
async function extractTopics({ text }) {
console.log('calling extractTopics')
const prompt = `Extract the main three topics from the following text as a JSON array of strings (topics only, no explanation):\n"""${text}"""`;
const response = await openai.chat.completions.create({
model: 'gpt-4',
messages: [
{ role: 'system', content: 'You are a helpful assistant that extracts topics from text.' },
{ role: 'user', content: prompt }
]
});
const content = response.choices[0].message.content;
try {
const topics = JSON.parse(content);
if (Array.isArray(topics)) return topics;
return [];
} catch (e) {
return content.match(/\w+/g) || [];
}
}
function sort(words) {
console.log('calling sort')
const unique = Array.from(new Set(words))
return unique.sort();
}
const functions = [
{
name: 'extractTopics',
description: 'Extracts the main topics from a given text.',
parameters: {
type: 'object',
properties: {
text: { type: 'string', description: 'The input text to extract topics from.' }
},
required: ['text']
}
},
{
name: 'sortTopics',
description: 'sorts topics into alphabetical order.',
parameters: {
type: 'object',
properties: {
text: { type: 'array', items: { type: 'string' }, description: 'an array of topics' }
},
required: ['']
}
}
];
async function chatWithFunctionCall(userInput) {
return chatWithFunctionCallRecursive([{ role: 'user', content: userInput }]);
}
async function chatWithFunctionCallRecursive(messages) {
const response = await openai.chat.completions.create({
model: 'gpt-4',
messages,
functions,
function_call: 'auto'
});
const msg = response.choices[0].message;
if (msg.function_call) {
let result;
const args = JSON.parse(msg.function_call.arguments);
if (msg.function_call.name === 'extractTopics') {
const topics = await extractTopics(args);
result = { topics };
} else if (msg.function_call.name === 'sortTopics') {
result = { sorted: sort(args.text) };
} else {
result = { error: 'Unknown function' };
}
const newMessages = [
...messages,
msg,
{
role: 'function',
name: msg.function_call.name,
content: JSON.stringify(result)
}
];
return chatWithFunctionCallRecursive(newMessages);
} else {
console.log('ChatGPT:', msg.content);
return msg.content;
}
}
const demoText = 'OpenAI develops artificial intelligence technologies such as ChatGPT, which can understand and generate human language.';
chatWithFunctionCall(`What are the main topics in this text? "${demoText}" Make sure they are ordered alphabetically.`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment