見出し画像

ChatGPT勉強日記 #2. APIの公式ドキュメントを読む(続き)

前回↓↓↓、OpenAI APIの公式ドキュメントのなかで自分の目に留まったも使い方をピックアップして紹介した。

今回はより深くOpenAI APIのコンテキスト記憶や外部ツール連携について書かれているところを読んで行きたい。

ChatGPTの記憶(コンテクストの復元について)

Tactic: For dialogue applications that require very long conversations, summarize or filter previous dialogue

ChatGPTは過去の会話内容を覚えていてくれて、それを踏まえた上で新しい質問に答えてくれる。このような会話の”コンテクスト”の記憶と復元について面白い記述が上のリンクにかかれている。

コンテキストの記憶には限界があり、長く会話を続けていると先に話した内容を覚えておくことがChatGPTは苦手だということ。

この対処方法として先の会話内容を(おそらくこちらがどこかDBなどを用意して)保存しておいて、あるタイミングでそれをサマリーとしてドカンとChatGPTに与えて、以前の会話のコンテクストを復元する、
という方法が紹介されています。
または、以前の会話内容が大きくなりすぎた場合、そこからいくつかの内容をピックアップしてChatGPTに与えることも考えられる、と書かれています。(これはおそらく同じような会話内容をパラメータを変えて何度も繰り返すような入力を過去に行ったときは有効だと僕は思いました。いろんなトピックを永遠としていたときは過去の会話の一部を無作為に抽出してChatGPTにコンテキスト復元をさせるのは難しいのではないかと思っています)


Open AI APIではなく、ChatGPTでの話ですが、Code Interpreterをつかって会話内容をテキストファイルに保存し、使い回すことで長期的にコンテキストを維持する方法を行っている人をTwitterで見つけました。


ChatGPTの記憶には、これから詳しく勉強しようと思っている
embeddingsをつかったり、
See the tactic "Use embeddings-based search to implement efficient knowledge retrieval".

embeddingで生成したベクターデータを保存する↓のようなサードパーティのサービスを使ったりするのだと思うがまだ詳細を勉強してないで詳述することはスキップしたいと思う。



外部のツールを使う

Strategy: Use external tools

Tactic: Use embeddings-based search to implement efficient knowledge retrieval

いよいよ核心的な部分に入ってきたなという感じ。

Embeddingという機能を使うとより効果的な知識の取得が可能になるとまず書いてあった。またEmbeddingを使うことで、実行中にダイナミックに関連する情報をモデルにインプットできるともかいてある。
やや抽象的な表現だが、ここの解像度を自分の中で上げていきたいところである。

Text Embeddingは1つのベクターデータ(配列データ、あるいは行列データのことであろう)で、このベクターデータををストアしておくことで、他のテキストデータとの近似度(似ている度、マッチ度、関連度)を図ることができるというものである。

これと、高速なベクターサーチアルゴリズムをつかうことで、効率よく知識を引き出すことができる。

ここでいうベクターサーチアルゴリズムというのはベクター同士の近似度を高速で計算して一番近いものを検索するアルゴリズムのことだろう。
おそらく計算グラフをつくって高速で行列同士の誤差を計算してマッチングするようなアルゴリズムだと素人考えでイメージしてみた。

Embeddingとこのベクターサーチアルゴリズムによって、効率よく適切な回答にたどり着けるとのこと。

急にここからChatGPT内部の話になっているようで、読み手としては最初混乱したが、だんだん腑に落ちてきた。

Example implementations can be found in the OpenAI Cookbook. See the tactic “Instruct the model to use retrieved knowledge to answer queries” for an example of how to use knowledge retrieval to minimize the likelihood that a model will make up incorrect facts.

残念ながらここのリンクが切れてた。。。一番読みたいところなのに、そしてAICookbookのサンプルコードもなくなったようだ。

Example implementations can be found in the OpenAI Cookbook. See the tactic “Instruct the model to use retrieved knowledge to answer queries” for an example of how to use knowledge retrieval to minimize the likelihood that a model will make up incorrect facts.

あとでサンプルコードをGitHubのヒストリーから探してみよう。もしかしたら別のいい方法が提供されているのかもしれない。


コードを直接実行させる

Tactic: Use code execution to perform more accurate calculations or call external APIs

これはSYSTEMで渡す命令の中にトリプルクォート(""")で括ったコードを書いておき、ユーザーのインプットに対してそれを実行してもらうというもの。
下の例ではPythonのコードでメールをコードを"""で囲んで書いておき、これを実行するというもの。

面白いのは、「アリスに。。。。の内容のメールを送ってください」という命令の仕方をしなくても、「アリスに10時にコーヒーショップで会おうと知らせてくれる?」という自然な文体を送るとChat GPTが「ではアリスにメールを送りましょうか?どんなメッセージを送りたいですか?」とさり気なくメール送信するメッセージを聞き出してくれることだ。

どれくらい誤作動が起きるのか少し心配だが自然な会話から関数のパラメータを聞き出してくれるのはすごい。最初サンプルの意味がわからないほどエレガントだった。


Function calling

Function calling
近い将来、自分が最もお世話になるだろう機能がこれだろう。
ここに書いてあるサンプルコードは

def run_conversation():

という関数のなかで、openapi.ChatCompletionのcreate関数に、モデル、メッセージ、関数(functions)、そしてfunctions_callを引数として渡している。

    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo-0613",
        messages=messages,
        functions=functions,
        function_call="auto",  # auto is default, but we'll be explicit
    )

functionsの定義を見ると、それはUSERからの会話から関数を呼ぶかどうかの判断材料と、読んだ場合どういう引数を会話から抽出すればいいかの定義が書いてある。

functions = [
        {
            "name": "get_current_weather",
            "description": "Get the current weather in a given location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA",
                    },
                    "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
                },
                "required": ["location"],
            },
        }
    ]

つまり、functionsは、会話からある内部関数を呼ぶための会話の受け皿である。どう言った場合なら受けられるのか、受けられる場合どういう情報がほしいのか、を記述してあるのである。

functionsが配列になっていることに気づいた人もいるかもしれない。functionsは複数の受け皿を入れることができるようになっている。
ここに登録した受け皿から、モデルがどの受け皿がUSERからのインプットを受け取るのに一番ふさわしいのかを判断して、一番ふさわしいfunctionを呼ぶようにできている。

function_call

openapi.ChatCompletionのcreate関数に渡した、function_callだが、

function_call="auto",  # auto is default, but we'll be explicit

この"auto"というのは、functions配列に用意した受け皿からモデルが自分で考えて最適なものを自動的に選ぶという設定である。

このドキュメントにはこのfunction_callに"none"を設定するとfunctionsのfunctionを一切呼ばなくなると書いてある。また

function_call={"name": "get_current_weather"}

このように{"name": "functionの名前"}を指定すると、functionsのなかから必ず指定したfunctionを強制的に呼ぶようにできるとも書いてある。
この方法は常に固定のfunctionを呼ばせるには良さそうだが、USERの会話内容によっては引数を適切に抜き出せないときもfunctionが呼ばれないか少し心配だ。公式ドキュメントのサンプルの天気を取得するデモでは、引数を得られなかったら、追加で「場所はどこですか?」などの質問をして引数を取得しているので心配ないのかもしれない。後でいろいろ実験して見ようと思った。

OpenAI Cookbookのレポジトリにより高度なfunction callingのサンプルがあった↓

https://github.com/openai/openai-cookbook/blob/main/examples/How_to_call_functions_with_chat_models.ipynb

これは、function callingからDBをクエリする部分まで入っているサンプルである。

自分が何らかのデータセットを持っている場合、

  • embeddingで最初にデータセットを入れて、モデルがそのデータを使って返すようにするか

  • function callを使ってDBからデータを引き出すか

2つのデータセットの活用の仕方があるので、ケースによって使い分けて行くことになるのだろうと思った。
このあたりはいろいろとプロトタイプを作って早く経験値を上げていきたいと思った。


その他

Chat GPTも間違えることがある

Strategy: Give GPTs time to "think"

ChatGPTを使っているとプログラムの書き方などを相談すると間違えていることは結構あるなと感じる。
でも簡単な数学の問題の答え合わせでも間違えることあり、その場合の解決方法が載っていたので紹介したい。

間違いを起こすプロンプトの例は↓

Tactic: Instruct the model to work out its own solution before rushing to a conclusion

この例では

SYSTEM Determine if the student's solution is correct or not.

のように、USERでインプットされる生徒の回答が正解か、間違っているかをモデルに命令させている。
生徒の答えは間違っているのだが、正解とモデルは判断している。

この対策として、

SYSTEM
First work out your own solution to the problem. Then compare your solution to the student's solution and evaluate if the student's solution is correct or not. Don't decide if the student's solution is correct until you have done the problem yourself.

https://platform.openai.com/playground/p/default-avoid-rushing-to-a-conclusion

のように、まずモデルに
自分で問題の答えを考えてください
それから、生徒の解答と自分の解答を比べてください
自分の解答を考えるまでは生徒の解答が正解だとは思わないでください

のように、まずモデルに考えさせ、それから答え合わせを指せることで、誤作動を回避できるようだ。

ここまで読んで、いままでTwitterでブックマークしてきたものの多くがどのように動作しているのかイメージできるようになった。

今後は自分で実際にコードを書いていろいろ試していきたい。

続く。


このブログに関する質問やWeb・Android・iOSアプリの開発の相談はこちらからお願いします。↓↓↓

@mizutory
mizutori@goldrushcomputing.com



この記事が気に入ったらサポートをしてみませんか?