✏️
OpenAIのFunction callingをつかって自然言語で関数を呼び出す
OpenAI APIの今回のアップデートでFunction callingがやってきました。
Function callingとは何であるか?
自然言語から関数呼び出しのデータをつくるものです。
たとえば以下のように自然言語から関数呼び出しのデータをつくることができます。
6月1日の8時にアニメを見る予定を追加
createTodo({ title: "アニメを見る", year: 2023, month: 6, date: 1, hour: 8, minute: 0 })
これによってSiriのようにユーザーからのお願いに答える(適切なシステムを呼び出し)サービスを、なんでも・だれでも作ることができるようになります。
Function callingとは何でないか?
- ChatGPTの中でAPIの関数を呼び出す
- ChatGPTの中でAPIの関数の呼び出しが行えるわけではありません
実装例
上のユースケースを実際に実装してみましょう。
基本の流れは公式ドキュメントの「Function calling example」が参考になります。
Completions API
import axios from "axios";
export const call = async ({
apiKey,
messages,
functions,
}: {
apiKey: string | null | undefined;
messages: { role: string; content: string }[];
functions: any[]; // TODO:
}) => {
if (apiKey == null) {
throw new Error("apiKey is required");
}
const data = await axios.post(
"https://api.openai.com/v1/chat/completions",
{
model: "gpt-3.5-turbo-0613",
messages,
functions,
temperature: 0,
},
{
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${apiKey}`,
},
}
);
return data.data.choices[0]; // eslint-disable-line @typescript-eslint/no-unsafe-member-access
};
Completions API 引数
6月1日の12時にアニメを見る予定を追加
{
name: "createTodo",
description: "Create a ToDo with schedule from a given text",
parameters: {
type: "object",
properties: {
year: {
type: "number",
description: "Schedule year, e.g. 2023",
},
month: {
type: "number",
description: "Schedule month, e.g. 6",
},
date: {
type: "number",
description: "Schedule date, e.g. 1",
},
hour: {
type: "number",
description: "Schedule hour, e.g. 8",
},
minute: {
type: "number",
description: "Schedule minute, e.g. 0",
},
title: {
type: "string",
description: "Todo title, e.g. watch the anime",
},
},
required: ["title", "year", "month", "date", "hour", "minute"],
},
},
const result = await call({
apiKey: process.env.OPENAI_API_KEY,
messages: [{ role: "user", content: `${data.message}` }],
functions: [
{
name: "createTodo",
description: "Create a ToDo with schedule from a given text",
parameters: {
type: "object",
properties: {
year: {
type: "number",
description: "Schedule year, e.g. 2023",
},
month: {
type: "number",
description: "Schedule month, e.g. 6",
},
date: {
type: "number",
description: "Schedule date, e.g. 1",
},
hour: {
type: "number",
description: "Schedule hour, e.g. 8",
},
minute: {
type: "number",
description: "Schedule minute, e.g. 0",
},
title: {
type: "string",
description: "Todo title, e.g. watch the anime",
},
},
required: ["title", "year", "month", "date", "hour", "minute"],
},
},
],
});
呼び出し
{
index: 0,
message: {
role: 'assistant',
content: null,
function_call: {
name: 'createTodo',
arguments: '{\n' +
' "year": 2023,\n' +
' "month": 6,\n' +
' "date": 1,\n' +
' "hour": 8,\n' +
' "minute": 0,\n' +
' "title": "アニメを見る"\n' +
'}'
}
},
finish_reason: 'function_call'
}
const args = JSON.parse(result.message.function_call.arguments);
const todo = await createTodo({ data: args });
さいごに
Function calling激熱ですね……!
Discussion