OpenAIのAssistantAPI Retrivalはクセが強い
お疲れ様です波浪です。
世の中ではGPTsが流行っていますが、AssistantAPI はあまり事例が見えないですね、なんでだろう?って使ってみたら大分死ねたのでその共有になります。
基本構造
まずアシスタントAPIは以下の構造であることを前提とします。
- Assistants
- File
- CodeInterpreter
- Retrival
- Run
- Step
- Thread
- Messages
- Message
- File
- Message
- Messages
- Fileは二つあって、AssistantとMessageにそれぞれ紐づく。
- Assistant のRetrival は ThreadのMessages、AssistantのFile、ThreadのFileの3つに作用
- AssistantとThreadは完全に分離している
- 一つのThreadに複数のAssistantを設定できる
しんどくなったポイント
複数のThreadを同期的に動作させるようなことはできない
複数のThreadを一つのアシスタントに設定する事で複数のThreadを同期的に動作させるようなことはできない。
⭕️ AssistantA(Thread Retrival) + Thread + AssistantB(Thread Retrival)
⭕️ ThreadA + AssistantA(ThreadA Retrival)
ThreadB + AssistantA(ThreadB Retrival)
❌ (ThreadA + ThreadB) + AssistantA(ThreadA Retrival + ThreadB Retrival)
→ ただし片方のThreadの内容を手動でFilesにアップロードして、AssistantAのFileに割り当てる事は可能なので手動で同期を図ることは可能
RetrivalをONにしているアシスタントにCSVを読ませてはいけない
この記事を書いている2023/12/28時点では アシスタントにCSVファイルをアップロードしてもアシスタントを作成することができません。
もし「できます!!」と言ってるAI驚き屋がいたら、それは128k tokenを使いきれていない=そもそもRetrivalを必要としないレベルのことをしているだけです。
なお公式にも使えないと書いてあります
Retrival をONにしているアシスタントを画像処理系のThreadに貼ってはいけない
CodeInterpreterで画像を出力させるパターンはよくあると思います、
たとえばこういうやつ↓
この時、Assistantは /mnt/data にファイルを配置しますが、Thread内にpng,csv等上述の RetrivalでNGになっているファイルが配置されると Retrivalがファイルを読めずにアシスタントのrunができなくなります。
初めからRetrivalに入れようとしなきゃいいのにと思うんですが、ある程度長いThreadになると勝手に入れようとしてエラーを吐き出します。
で、一度これになると当該Threadはそれ以上続けられないも同然になります。
進めるための修正方法として当該Messageからpathの部分だけ削除してしまえばよいのでは?という解決策を思いつきますが
上記URLの通り、Modifies Messageで修正できる項目はMetadataのみです、よって本文を修正できません
さらにMessageは削除できません。
よって、一度このエラーを出力する状態になったThreadでは他のRetrivalをONにしたアシスタントも使えなくなります。
日本語フォントを直接アップロードできない
アップロードしようとすると対象外ファイルで怒られるので、一回zipで圧縮してからアップロードしましょう。
と、いうか、大抵のファイルは一回zipにしたほうが良いです。
なぜならAssistantAPIはアップロード時に勝手にファイル名を変更して拡張子もファイル名も失ってしまいます。
それよりもzipでアップロードしてCodeInterpreterで解凍して使わせる方がファイル名も拡張子も消えないためCodeInterpreterが調子よく捌いてくれます。
あと頭紙としてzipファイルの中にREADMEや、ファイルの一覧を書いたtxtをいれておき Instractionに『zipファイルには「README」が入っています、これは当該zipに圧縮されたファイルそれぞれについて説明したファイルです、よく読んでから処理を開始してください』 とか指示しておくと CodeInterpreter がよしなに読み取って納得してくれます。
Threadの一覧が取得できない
自分の作ったThreadは自分でThreadIDを覚えておかないと2度と見ることができません。
Messagesには ListMessageがありますが
Threadには見ての通りありません
まあでもMessagesのListの取得は
https://api.openai.com/v1/threads/{thread_id}/messages
こんなURLだし
https://api.openai.com/v1/threads/
こうしたらThread一覧見れるんでしょ? そう思った貴方はこれを見ましょう
そう、このURLは Threadを作成する時のAPIです。
なんでだよ!!!!(心の叫び)
はい、というわけで、まじで現状ThreadのIDを控えておかないと復活することができなくなります
Filesが高い
AWS S3だと1回配置して1回読むだけなら 0.009USDくらいなのでなかなかに高いですね。
で、このファイル領域にも罠がありまして、上述したThread内で出力されたファイルもどうやらここに入るようなんですが、Filesで調べても出てきません。
Thread内にassistantが出力したFileはこのように Purpose : assistants_output になります
しかしながらFiles APIを叩いても、自分がAssistantに能動的にアップロードしたファイルしか出てきません
料金がどうなっているのかは今調査中なんですが、仮にこれにもお金がかかるとするとThreadIDを記録し損ねたThreadで出力したファイルは2度と消せません。え?まさか一生お金がかかり続けるの?まじで?
また料金がかからない場合、今度はThreadは永久に残ることになっていたはずだが、出力したファイルはどれくらいの期間取得できるのかが不明になります。 なんだその罠
ついでにですが、ThreadをDeleteしてもThreadで使ったファイルは消えないので、Threadを先に消すと2度とたどれなくなります。
まとめ
Retrival の仕事環境を整えよう
Retrival君はとてもナイーブな子なので使う時は、職場を綺麗に、彼が仕事しやすい環境を整えてあげましょう、Retrival君が使えないファイルをよく覚えて、Threadの中にそれらのファイルパスが入っていない事を確認しましょう。もしいけないファイルがある場合はThreadをまるごと取得して別の場所で綺麗にして、txtファイルやjsonファイルに変換して直接Assistantに渡しましょう。
Textでのみ会話するThreadであればRetrivalは大得意です、特性を理解して使いましょう
CodeInterpreter を信頼しよう
CodeInterpreter は60秒しか動けないこと、新規でライブラリが入れられないことを除けばかなり使える子です、なにしろユーザーが自分で作ったPythonファイルをアシスタントに追加してCodeInterpreterで実行することもできます。
システムの制限によりPythonのエラーを我々に見せられない場合があり、正しいエラーメッセージを教えてくれないので解決策を指示できなくなることがありますが、そういうものだと飲み込みましょう。
Files と CodeInterpreter が協力すると強力
ファイルは最大20個、1ファイル512MBまで使えます、つまり1アシスタントで10Gまでファイルを添付できます。
ベクトル化したいデータとベクトル化済みのIndexファイルを引き渡してCodeInterpreterを使えば擬似的なRetrivalすら実現できます。
ただし60秒の制限が厳しい事が多いです、Promptで自分で考えさせることもできますが
逐次必要な部分だけを切り出して別ファイルにするよう指示したりと短い時間で終わるために必要な処理は指示してあげたほうが早いです
余談
そもそもβ版なんで、と言われたらその通りなんですが、この記事の初めに書いた
世の中ではGPTsが流行っていますが、AssistantAPI はあまり事例が見えないですね、なんでだろう?
っていう自分の疑問には十分応えられたかなと思います
以上、よろしくお願いします。
Discussion