OpenAIのFunction callingで小説の解析をしてみる
ローカルLLMのチューニングに奮闘されているsaldraさんが、ご自身が運営されているDiscordコミュニティに、Function callingのアイデアを募る投稿をされていました。サンプルコードも貼ってくださったので、早速試してみることにしました。
様々な使い方が考えられる夢の機能であるFunction callingですが、趣味で小説を書く私としては、小説の分析に使えないかなと思いました。例えば、もうパブリックドメインになった古典小説を解析して要素を分解し、自分なりに現代劇として再構成する、なんて使い方は楽しそうです。GPT-3.5、GPT-4は外国語を読み込んで解析して日本語で返すということもできますから、外国の古典小説の分析もできそうです。
とりあえずはFunction callingの威力を確かめるべく、自分の書いた原稿で試してみました。ブルーアーカイブというゲームの二次創作小説です(二次創作ガイドラインが整備されていて安心して二次創作を楽しめる作品です)
文字数はだいた3800文字。トークン数から考えてもテストには最適でしょう。
試してみたソースコードはこちら。Discordコミュニティに貼られたサンプルコードをほとんどそのまま拝借しています。
import openai
import json
from dotenv import load_dotenv
load_dotenv()
import os
model_name = "gpt-4-0613"
openai.api_key = os.getenv("OPENAI_API_KEY")
functions=[
{
"name":"whoisheroine",
"description":"",
"parameters":{
"type":"object",
"properties":{
"heroine":{
"type":"string",
"description":"与えられた小説を解析し、主人公の名前を返します。"
},
"appearance":{
"type":"string",
"description":"与えられた小説を解析し、主人公の外見を返します。"
},
"personality":{
"type":"string",
"description":"与えられた小説を解析し、主人公の性格を返します。"
},
"other":{
"type":"string",
"description":"与えられた小説を解析し、主人公のその他の情報を返します。"
}
}
},
"type":"object",
}
]
arg = """
(※小説の本文を貼る)
"""
question = f'「{arg}」について、この小説の登場人物を判定し、名前をheroineに、外見をappearance' \
f'に、性格をpersonarityに、その他の情報をotherに入れてください。' \
f'複数人の登場人物がいます。全ての人物について同様の内容をリストアップして返してください。'
print(question)
res = openai.ChatCompletion.create(
model=model_name,
messages=[{
"role":"user",
"content":question
}],
functions=functions,
function_call = "auto"
)
res_json = json.loads(res["choices"][0]["message"]["function_call"]["arguments"])
print(res_json)
すると、以下の様なJSONが返ってきました(改行はこちらで入れています)
細かいところを言うと、ハスミ先輩はコハルに助けられてはいないのですが(私が書いた原稿の中ではコハルが助けたのはミカ)、他の部分は書いた内容の通りで、かなり良い感じに抽出できています。
同じ内容は、ChatGPTでも得ることができます。ですが、このFunction callingを使うと夢が広がるのが、複数の小説を同じ視点で、同じフォーマットで大量に解析できることでしょう。
古典小説は、現代の小説にも受け継がれるフォーマットがたくさんあります。登場人物やシーンを抽出し、プロットを取り出しておけば、後から自分なりにアイデアを作るのに役立つでしょう。また、たとえば主人公の社会的地位を同じフォーマットで抽出し、小説の年代別に整理することで、歴史の中で移りゆく主人公像の変遷なども分析出来そうです。
というわけで、ちょっと興奮したので、深夜の走り書きとしてまとめてみました。Function calling、色んなアイデアを見てみたいです。