Skip to content

Latest commit

ย 

History

History
345 lines (276 loc) ยท 10.2 KB

README.md

File metadata and controls

345 lines (276 loc) ยท 10.2 KB

Logo

OpenAI Function calling tools

Current version LICENSE codecov semantic-release PRs welcome

OpenAI Function calling tools

OpenAI Function calling tools is a repository that offers a set of tools to help you easy to build a function calling model with OpenAI API.

More information about function calling

Sample: https://chatFn.io

image

๐Ÿช“ Tools

The repo provides the following tools you can use out of the box:

  • ๐Ÿ—บ๏ธ ShowPoisOnMap: A tool that can show points of interest on a map.
  • ๐ŸŒ ReverseGeocode: A tool that can convert coordinates into a human-readable address.
  • โฐ Clock: A clock that can tell you the time.
  • ๐Ÿงฎ Calculator: A simple calculator that can do basic arithmetic. Input should be a math expression.
  • ๐Ÿ” GoogleCustomSearch: A wrapper around the Google Custom Search API. Useful for when you need to answer questions about current events. Input should be a search query.
  • ๐Ÿ” BingCustomSearch: A wrapper around the Bing Custom Search API. Useful for when you need to answer questions about current events. Input should be a search query.
  • ๐Ÿ” SerperCustomSearch: A wrapper around the SerpAPI. Useful for when you need to answer questions about current events. Input should be a search query.
  • ๐Ÿž๏ธ SerperImagesSearch: Use SerpAPI to search images. Input should be a search query.
  • ๐Ÿ“ fs: WriteFileTool abd ReadFileTool access to the file system. Input should be a file path and text written to the file.
  • ๐Ÿชฉ webbrowser: A web browser that can open a website. Input should be a URL.
  • ๐Ÿšง sql: Input to this tool is a detailed and correct SQL query, output is a result from the database.
  • ๐Ÿšง JavaScriptInterpreter: A JavaScript interpreter. Input should be a JavaScript program string.

You can use { Tool } factory function to create a tool instance. See /tools for more examples.

๐Ÿ“ฆ Quick Install

npm install openai-function-calling-tools

๐Ÿ“– Usage

Example 1: Function Calls

use JavaScriptInterpreter to calculate 0.1 + 0.2

import { Configuration, OpenAIApi } from "openai";
import { createCalculator } from "openai-function-calling-tools"

const configuration = new Configuration({
    apiKey: process.env.OPENAI_API_KEY,
  });
const openai = new OpenAIApi(configuration);

const QUESTION = "What is 100*2?";

const messages = [
  {
    role: "user",
    content: QUESTION,
  },
];

# โœจ STEP 1: new the tools you want to use
const [calculator, calculatorSchema] = createCalculator();

# โœจ STEP 2:  add the tools to the functions object
const functions = {
  calculator,
};

const getCompletion = async (messages) => {
  const response = await openai.createChatCompletion({
    model: "gpt-3.5-turbo-0613",
    messages,
    # โœจ STEP 3: add the tools to the schema
    functions: [calculatorSchema],
    temperature: 0,
  });

  return response;
};

console.log("Question: " + QUESTION);
let response = await getCompletion(messages);

if (response.data.choices[0].finish_reason === "function_call") {
  const fnName = response.data.choices[0].message.function_call.name;
  const args = response.data.choices[0].message.function_call.arguments;

  console.log("Function call: " + fnName);
  console.log("Arguments: " + args);

  # โœจ STEP 4: call the function
  const fn = functions[fnName];
  const result = fn(JSON.parse(args));

  console.log("Calling Function Result: " + result);

  messages.push({
    role: "assistant",
    content: null,
    function_call: {
      name: fnName,
      arguments: args,
    },
  });

  messages.push({
    role: "function",
    name: fnName,
    content: JSON.stringify({ result: result }),
  });

  // call the completion again
  response = await getCompletion(messages);

  console.log(response.data.choices[0].message.content);
}

Example 2: Function Calls with Google Custom Search

๐Ÿ“ Note: You need to apply for a Google Custom Search API key and a Google Custom Search Engine ID to use this tool.

The following is a sequence diagram of the example

sequenceDiagram
  participant U as User
  participant M as Main Function
  participant O as OpenAI API
  participant F as Functions Object
  participant GC as Google Custom Search

  U->>M: Execute main function
  M->>M: Initialize configuration and API
  M->>M: Define QUESTION variable
  M->>M: Create Google Custom Search tool
  M->>F: Add tool to functions object
  loop Chat Completion Loop
      M->>O: Request chat completion
      O-->>M: Return response
      alt If finish reason is "stop"
          M->>U: Display answer and exit loop
      else If finish reason is "function_call"
          M->>M: Parse function call name and arguments
          M->>F: Invoke corresponding function
          F->>GC: Perform Google Custom Search
          GC-->>F: Return search results
          F->>M: Receive function result
          M->>M: Add result to message queue
          M->>M: Output function call details
      else Other cases
          M->>M: Continue loop
      end
  end

Code

const { Configuration, OpenAIApi } = require("openai");
const { createGoogleCustomSearch } = require("openai-function-calling-tools");

const main = async () => {
  const configuration = new Configuration({
    apiKey: process.env.OPENAI_API_KEY,
  });
  const openai = new OpenAIApi(configuration);

  const QUESTION = "How many tesla model 3 sale in 2022?"

  const messages = [
    {
      role: "user",
      content: QUESTION,
    },
  ];

  // โœจ STEP 1: new the tools you want to use
  const [googleCustomSearch, googleCustomSearchSchema] =
    createGoogleCustomSearch({
      apiKey: process.env.GOOGLE_API_KEY,
      googleCSEId: process.env.GOOGLE_CSE_ID,
    });


  // โœจ STEP 2:  add the tools to the functions object
  const functions = {
    googleCustomSearch,
  };

  const getCompletion = async (messages) => {
    const response = await openai.createChatCompletion({
      model: "gpt-3.5-turbo-0613",
      messages,
      // โœจ STEP 3: add the tools schema to the functions parameter
      functions: [googleCustomSearchSchema],
      temperature: 0,
    });

    return response;
  };
  let response;

  console.log("Question: " + QUESTION);

  while (true) {
    response = await getCompletion(messages);

    if (response.data.choices[0].finish_reason === "stop") {
      console.log(response.data.choices[0].message.content);
      break;
    } else if (response.data.choices[0].finish_reason === "function_call") {
      const fnName = response.data.choices[0].message.function_call.name;
      const args = response.data.choices[0].message.function_call.arguments;

      const fn = functions[fnName];
      const result = await fn(JSON.parse(args));

      console.log(`Function call: ${fnName}, Arguments: ${args}`);
      console.log(`Calling Function ${fnName} Result: ` + result);

      messages.push({
        role: "assistant",
        content: "",
        function_call: {
          name: fnName,
          arguments: args,
        },
      });

      messages.push({
        role: "function",
        name: fnName,
        content: JSON.stringify({ result: result }),
      });
    }
  }
};

main();

Example 3: Schema Extraction

Example to extract schema from a function call

Tree structure:

import { Configuration, OpenAIApi } from "openai";

const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);

const getCompletion = async (messages) => {
  const response = await openai.createChatCompletion({
    model: "gpt-3.5-turbo-0613",
    messages: [
      {
        role: "user",
        content: `root
              โ”œโ”€โ”€ folder1
              โ”‚   โ”œโ”€โ”€ file1.txt
              โ”‚   โ””โ”€โ”€ file2.txt
              โ””โ”€โ”€ folder2
                  โ”œโ”€โ”€ file3.txt
                      โ””โ”€โ”€ subfolder1
                              โ””โ”€โ”€ file4.txt`
      },
    ],
    functions: [
      {
        "name": "buildTree",
        "description": "build a tree structure",
        "parameters": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string",
              "description": "The name of the node"
            },
            "children": {
              "type": "array",
              "description": "The tree nodes",
              "items": {
                "$ref": "#"
              }
            },
            "type": {
              "type": "string",
              "description": "The type of the node",
              "enum": [
                "file",
                "folder"
              ]
            }
          },
          "required": [
            "name",
            "children",
            "type"
          ]
        }
      }
    ],
    temperature: 0,
  });

  return response;
};

let response = await getCompletion();

if (response.data.choices[0].finish_reason === "function_call") {
  const args = response.data.choices[0].message.function_call.arguments;
  // ๐ŸŒŸ output the Tree structure data
  console.log(args);
}

๐Ÿ’ป Supported Environments

  • Node.js v16 or higher
  • Cloudflare Workers
  • Vercel / Next.js (Backend, Serverless and Edge functions ๐Ÿ”ฅ)
  • Supabase Edge Functions
  • ๐Ÿšง Browser

๐Ÿ›ก๏ธ Safe for Production

Security Status

๐ŸŒŸ Inspiration

  • LangChainAI