1
4

More than 1 year has passed since last update.

function callingで、ChatGPTにQiitaのトレンド記事を表示させる

Posted at

こんばんは、すきにーです。

ChatGPTの新機能であるfunction callingを使って、
ChatGPTにQiitaのトレンド記事を表示させたいと思います。
https://qiita.com/trend

現在のトレンドのトップ3はこんな感じです
image.png

function callingとは

イメージとしては、GPT4のプラグイン機能をAPIで実装できるようになったという感じです。

Function callingは大きく3つのステップに分かれ、

① ユーザの質問からどの関数を呼ぶかをChatGPTに決めてもらう
② chatGPTが決めた関数を呼び出して処理実行
③ 関数の実行結果と最初の質問をChatGPTに渡して回答を生成する

という流れになります。

function callingの説明はこちらの記事が分かりやすかったです。

トレンド記事を表示させるコードを実装

まずライブラリをインポートします。

import openai
import os
import json

# OpenAI APIキーの準備
openai.api_key = "APIキー"

次にqiitaのトレンドを取得する関数を定義します。記事の取得にはQiitaのAPIを使用しました。
引数にタグを入れることで、タグに関するトレンドを表示させます。
(何もないときはトレンドTOP5が表示されます)

def get_qiita_trend(tag=None):
    url = "https://qiita-api.vercel.app/api/trend"
    response = requests.get(url)

    # ResponseオブジェクトからJSONデータを取得
    data = response.json()

    # 'node'の値を取得
    node_values = [item['node'] for item in data]

    # DataFrameを作成
    df = pd.DataFrame(node_values)
    
    # 'tags'列の中のJSONデータの'name'キーの値を表示
    df['tags'] = df['tags'].apply(lambda x: [tag['name'] for tag in x])
    
    if tag:
      df = df[df[['title', 'tags']].apply(lambda x: tag in x)] 

    # 指定された行数を表示
    qiita_trend = df[['title', 'tags', 'linkUrl']].head()
    
    return qiita_trend.head().to_json(orient='records')

functionの定義

functions=[
    {
        "name": "get_qiita_trend",
        "description": "qiitaのトレンド記事を取得",
        "parameters": {
            "type": "object",
            "properties": {
                "tag": {
                    "type": "string",
                    "description": "表示させたいトレンドのタグ",
                },
            },
        },
    }
]

入力文から 「呼び出す関数」 「引数」 をChatGPTに決めてもらう

model_name = "gpt-3.5-turbo-0613"

question = "Qiitaのトレンドを教えて"

response = openai.ChatCompletion.create(
    model=model_name,
    messages=[
        {"role": "user", "content": question},
    ],
    functions=functions,
    function_call="auto",
)
message = response["choices"][0]["message"]

messageの中身はこんな感じです。
今回は「Qiitaのトレンドを教えて」という入力だったので、引数であるargumentsの中身は空です。
image.png
もし入力文が「JavaScriptのトレンドを教えて」であった場合、argumentsのtagはJavaScriptになります。
image.png

get_qiita_trend関数の実行

if message.get("function_call"):

    function_name = message["function_call"]["name"]

    arguments = json.loads(message["function_call"]["arguments"])
    function_response = get_qiita_trend(
        tag=arguments.get("tag"),
    )

関数を実行した結果をもとに、ChatGPTが回答を生成する

    second_response = openai.ChatCompletion.create(
        model=model_name,
        messages=[
            {"role": "user", "content": question},
            message,
            {
                "role": "function",
                "name": function_name,
                "content": function_response,
            },
        ],
    )
    
    print(second_response.choices[0]["message"]["content"].strip())

ChatGPTの出力
image.png

入力文が「JavaScriptのトレンドを教えて」の場合
image.png

おわりに

以上がfunction callingでQiitaのトレンドを表示させる方法です。
function calling、使い方次第ではもっとすごいことができそうな気がしますが、私の中にはそれが浮かんでいないです...

お読みいただきありがとうございました!

参考記事

毎朝Qiitaトレンド記事が届くLINE Botを開発してみた
OpenAIがChatGPTを更にパワーアップ!「Function Calling」の使い方とは?
OpenAI Function callingで複雑なタスクを簡単に実現
https://platform.openai.com/docs/guides/gpt/function-calling

1
4
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
1
4