はじめに
Function Callingはご存じの通り、関数の定義と入力をいれることで、定義された関数が必要であればその関数名と引数を回答として返してくれる機能です。実装方法なんかは公式・非公式含めてたくさんありますので、ここでは概要の動きと利用用途についての考察をしてみたいと思います。
ざっくりとした動き
まずは 「Web検索したりしながら情報をあつめて、その中から欲しい情報をメモに登録しながらメモをつくっていく」 というシナリオを想定します。
関数として必要な以下の2つを登録します。
- web_search(キーワードの配列)
- キーワードの配列をもとにWeb検索をする関数
- memo_insert(文章)
- ユーザ用のメモに文章を登録する関数
併せてシステムプロンプトとして以下のように関数を適宜使いこなして対応する旨定義します。
system_prompt = """\
あなたはAIコンシェルジュです。ユーザからの要望に従って、Web検索などを駆使して回答を作成します。
なお、ユーザには専用のメモがあり、その情報を取得したり、追加したりすることも実施して下さい。
"""
コードの詳細は割愛しますが、上記のシステムプロンプトと関数定義で以下のようなシーケンスフローが実現できます。
考察
Function Calling以前は、上記のシナリオを実現するためには、ユーザからの入力がWeb検索なのか、メモ登録なのかを判別するChatGPT、もしくは判別して挙動を変えるシステムプロンプトが必要でした。これが中々職人芸みたいなところもあって、思ったような動きをしないということが多かったかなと思います。(頑張ればできたりもするけどもモデル変更などに脆弱ですしね)
なのでFunction Callingを使うことで、
- 安全に関数呼び出しができるようになった
- 複数の意図をもったChatGPTが作りやすくなった
かなと思います。
ただし1つの目的で関数の引数を抜き出すだけに使うと、これまでもフォーマット指定で抽出できていたところ&細かい調整などもできていたところなので、そこまでのうま味はないように感じます。
ChatGPTに何をさせたいのかを設計した際に、Function Callingをつかってまとめれる部分は1つのシステムプロンプト+Function Callingを使う、っていうあたりが落としどころかなと。