LoginSignup
0
0

More than 1 year has passed since last update.

OpenAIのFunctionCallingをTypeScriptなしでNode.jsで使ってみる

Posted at

環境

  • node.js v18.16.0
  • OpenAIのモデル gpt-3.5-turbo-0613

さっそくコード

const { Configuration, OpenAIApi } = require("openai");

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

functions = {
  get_current_weather : ({location, offsetDay, unit}) => {
    // console.log(args);
    // const location = args.location;
    // const offsetDay = args.offsetDay;
    // const unit = args.unit;

    // .. 実際に天気APIなど使ったり

    weather_info = {
        "location": location,
        "temperature": "-10",
        "unit": unit,
        "offsetDay": offsetDay,
        "forecast": ["晴れ"],
    }
    return JSON.stringify(weather_info);
  }
}
async function main() {
  const prompt = {role: "user", content: "昨日の浪江の天気を教えて"};
  const response1 = await openai.createChatCompletion({
    model: "gpt-3.5-turbo-0613",
    messages: [prompt],
    functions: [
      {
        name: "get_current_weather",
        description: "与えられた場所の天気の情報を返す",
        parameters: {
          type: "object",
          properties: {
            location: {
              type: "string",
              description: "天気を知りたい場所の県や市の名前 例)愛知県名古屋市"
            },
            offsetDay: {
              type: "number",
              description: "天気を知りたい今日の日付からの差分の日付。例えば、昨日の天気を知りたい場合は-1"
            },
            unit: {
              type: "string",
              enum: ["celsius", "fahrenheit"]
            }
          },
          required: ["location", "offsetDay"]
        }
      }
    ]
  });
  const message = response1.data.choices[0].message;
  // console.log(message);

  // 関数を実行すると判断
  const functionCall = message?.function_call;
  if(functionCall) {
    const args = JSON.parse(functionCall.arguments || "{}");
    const funcResponse = functions[functionCall.name](args);

    const response2 = await openai.createChatCompletion(
      {
        model: 'gpt-3.5-turbo-0613',
        messages: [prompt, message, {
          role: 'function',
          content: funcResponse,
          name: functionCall.name
        }]
      }
    );
    const message2 = response2.data.choices[0].message;
    console.log(message2);
  }
  
}
main();

参考サイト

工夫した点

まず実装上の仕様として、

  • 実行したい関数の名前の文字列で来る
    • 関数名の文字列からその関数を実行する
    • この点はjs的に簡単にできそう!
  • 引数はjson形式の文字列で来る
    • オブジェクトを引数にわたすしかない
    • 自分的にこの点が今回学んだところ
functions[functionCall.name](args);

  get_current_weather : (args) => {
    console.log(args);
    const location = args.location;
    const offsetDay = args.offsetDay;
    const unit = args.unit;

引数がオブジェクトなら、オブジェクトで受け取ってconstに展開していくのが、あんましスマートじゃないと感じてちょっと調査したところ

functions[functionCall.name](args);

  get_current_weather : ({location, offsetDay, unit}) => {

引数をこんな感じで書くことで、展開する手間がはぶけた!

ただ、functions内にわたすparametersの中身と同じになるはずなので、ここらへんを共通化しつつ、うまく引数受取るのもできたらいいなと思ってます

ちなみに...

参考サイトからoffsetDayを付け加えてみた。
今週の天気教えてってやるとoffsetDayは0
今日は土曜なので、-6,-5,-4...って7回functionsが実行される感じだとおもろいなっておもた

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0