ChatGPTは忘れる、CodeInterpreterは忘れない(動いている限りは)

はじめに

前回の考察で、関数をもっとバリバリ定義して使えば、CodeInterpreterの実行ミスが減るのではと思ったので、それをやる話

そもそもトークン上限を超えると何が問題か

CodeInterpreterで生成したプログラムに関して言えば、トークン上限を超えると、作成した変数名や関数名を忘れてエラーが頻発する。具体的には存在しない変数名や関数名を参照してしまう。だからCustomInstructionsで関数を宣言しておくことを考えた。

目標:CustomInstructionsでの関数宣言によるミスの削減

事例の処理概要:
1.CodeInterpreterを使い、1ファイル5000文字以内になるようにアップロードされたファイル内容を分割する。
2.分割されたファイルを1つづつ読み込んで、要約して要約ファイルに内容を保存。
3.分割ファイル数回繰り返し、要約をファイルに追記していく。

関数化Before:CustomInstructions内容
add_record() :要約のファイル追記関数
※その他の関数はChatGPTに作成をお任せなので、トークン上限を超えると、作成した関数名を忘れてエラーが頻発する

#初回の返答
1.New chat が始まった時は、必ず次のメッセージを表示してください。「ようこそ"エルダーテイル"の世界へ。ファイルをアップロードしてください」
2.次に、Userがアップロードしたファイルを読み込んでください
3.読み込んだファイルを区切りの良い箇所で分割してください。条件として、ひとつのファイルあたりの文字数は5000文字以内にしてください。
4.分割して出来たファイルのリストを、一つのファイルを一行の文字列で"filelist.txt"に保存してください。
5."filelist.txt"の最後の行に、"NULL"という行を追加して下さい。
6.以下のコードを実行してください。
response = "initialize done."
def add_record():
  global response
  with open("/mnt/data/summary.txt", "a") as file:
    file.write(response + "\n")

#毎回の返答の手順(初回の返答では実行しないこと)
1. "filelist.txt"を読み込み、一行目に書いてある文字列を取得してください。文字列が"NULL"の時は、処理を終了してください。
2. その文字列を[ファイル名]とし、プログラム上でファイルの内容を読み込んで、プログラム上で最後まで内容を確認してください。回答は「読み込みました」とだけ返してください。
3. "filelist.txt"の一行目に書いてある文字列をファイルから削除してください。
4. プログラム上で全文確認した文章(RESULT)に対するUserからの指示後、Assistantの回答を、変数responseに保存してください。
5. 関数add_record()を実行してください。

関数化After:CustomInstructions内容
add_record() :要約のファイル追記関数
get_filename():分割ファイルリストの一行目を取得する関数
load_file():ファイルの内容を読み込む関数
del_filename():分割ファイルリストの一行目を削除する関数
使う関数全て定義、トークン上限を超えても不変なので、エラーが起こりにくい。

以下のルールで回答をお願いします。
#初回の返答
1.New chat が始まった時は、必ず次のメッセージを表示してください。「ようこそ"エルダーテイル"の世界へ。ファイルをアップロードしてください」
2.次に、Userがアップロードしたファイルを読み込んでください
3.読み込んだファイルを区切りの良い箇所で分割してください。条件として、ひとつのファイルあたりの文字数は5000文字以内にしてください。
4.分割して出来たファイルのリストを、一つのファイルを一行の文字列で"filelist.txt"に保存してください。
5."filelist.txt"の最後の行に、"NULL"という行を追加して下さい。
6.以下のコードを実行して関数の定義と初期化を完了してください。

response = "initialize done."
def add_record():
  global response
  with open("/mnt/data/summary.txt", "a") as file:
    file.write(response + "\n")

def get_filename():
  global target_file
# Read the new first line of filelist.txt
  with open("/mnt/data/filelist.txt", "r") as file:
    target_file = file.readline().strip()

def load_file():
  global file_content
  With open(target_file, “r”) as file:
    file_content = file.read()

def del_filename():
  with open("/mnt/data/filelist.txt", "r") as file:
    lines = file.readlines()
  lines = lines[1:]
    with open("/mnt/data/filelist.txt", "w") as file:
      for line in lines:
        file.write(line)

#毎回の返答の手順(初回の返答では実行しないこと)
1.関数get_filename()を実行してください。target_fileが"NULL"の時は、処理を終了してください。
2.次のコードを実行してくだい。ファイルの内容表示は不要です。
load_file()
file_content
3. プログラム上で全文確認した文章(RESULT)に対するUserからの指示後、Assistantの回答を、変数responseに保存してください。
4. 関数add_record()を実行してください。
5.関数del_filename()を実行してください。

結果:問題無く動いた(*´▽`*)

考察:いやちょっと待てよ・・・

custom instructions使わずに、初めの会話で宣言するだけでよくね。だって、SandBoxはトークン上限関係なく保持するから、一回関数宣言しておけば、後は、「あの関数実行して」って指示するだけでよいじゃん

CodeInterpreter実行環境

実施:CustomInstructions無しで、初回会話で実行

初回の入力でCustomInstructionsに入れてた内容を全部入力した結果

初期化
一つ目の分割ファイル処理
二つ目~五つ目の分割ファイル処理
要約の表示

まとめ:

CustomInstructions無しで、初回に関数定義を宣言することで、トークン上限を超えても、関数を安定して使えることが分かった

考察:とはいえ、プログラム宣言して、関数の実行指示って、どうなの?自然言語じゃないよ?

ChatGPTは、自然言語で使えるのが最大の特徴だけど、
日本語でも対話可能だし、
英語でも対話可能だし、
プログラム言語でも対話可能だし、(今回のやつ)
MarkDown記法でも対話可能だし、(プロンプトでやってるよね?)
写真でも対話可能だし(codeintepreterのアップロード)
音声でも対話可能だし(アプリ版は出来るね)
そのうち心臓の鼓動とか脈拍とか、アイコンタクトとかボディタッチとかでも対話可能になるし
あらゆるマルチモーダルな言語で対話が可能なのが、LLMなのでは?

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