はじめに
こころはやってんの、ChatGPT?1 nikkieです。
先日も取り上げましたが、ChatGPT、すごいですよね!
アプリケーションにマッシュアップしている例も見かけるようになり、プログラムからどうやってChatGPTのAPIを叩くかに興味を持ちました。
この記事ではPython製の非公式ライブラリrevChatGPTを試します。
※この記事は2023/02/25時点の情報です。
OpenAI次第なので、今後使えなくなる可能性は十分にあります。
目次
revChatGPT
PyPIに公開されており、pip
でインストールできます!
Reverse Engineered ChatGPT API by OpenAI.
OpenAIによるChatGPTのAPIをリバースエンジニアリングしたそうです。
動作環境
完全に再現させるための情報です:
% pip freeze certifi==2022.12.7 charset-normalizer==3.0.1 idna==3.4 OpenAIAuth==0.3.2 requests==2.28.2 revChatGPT==2.3.8 urllib3==1.26.14
コマンドラインで動かす
READMEのConfigurationを実施する
https://github.com/acheong08/ChatGPT#configuration
(1) Open AIのアカウントがない場合は作りましょう。
私は既に作っていたので次の手順からやりました。
(2) Authentication method(認証方法)を1つ選びます。
私は「Access token」を選びました。
ChatGPTのWeb UIにログインした状態で https://chat.openai.com/api/auth/session を開くと確認できます。
キーaccessToken
の値を使って、config.jsonを作ります。
{ "access_token": "https://chat.openai.com/api/auth/session で確認できるaccessTokenの値" }
(3) (2)で作ったJSONを$HOME/.config/revChatGPT/config.json
に配置します。
私は今回、シンボリックリンクにしました3。
% mkdir -p ~/.config/revChatGPT % ln -s $PWD/config.json ~/.config/revChatGPT/config.json
以上でConfiguration完了です!
python -m revChatGPT.V1
https://github.com/acheong08/ChatGPT#command-line
コマンドラインでpython -m revChatGPT.V1
を実行すると、Web UIではなく、コマンドラインでChatGPTとお話しできます!!
ChatGPTさん、色々な作品をご覧になってた(本人(?)が見たと言っているので)
— nikkie にっきー (@ftnext) 2023年2月25日
イカゲーム、鬼滅無限列車、NileRed。
配信サービスのヘビーユーザなのかもしれません
nikkie:
最近 みた面白かった映画 を教えてほしいな
※非公式APIを叩くライブラリをお試ししています pic.twitter.com/6892mR26A9
Web UI同様、ChatGPTの応答が少しずつ表示されるんです!
このパッケージのUI(CUI)のポイントは以下です。
- (ChatGPTのWeb UI同様)改行込みの入力をサポート
- つまり、ChatGPTにテキストを送るにはEnterキーを2回連続で入力する必要がある(Press enter twice to submit your question.)
- Enterキー1回はテキストの改行になりChatGPTに送信されない
- ChatGPTに送信されるとコマンドラインには「Chatbot:」と表示される
!
で始まるいくつかのコマンドをサポート- これらのコマンドもEnterキー連続2回で実行される
スクリプトで動かす
https://github.com/acheong08/ChatGPT#developer-api
Basic example (streamed)を試す
import json from revChatGPT.V1 import Chatbot with open("config.json", encoding="utf8") as f: config = json.load(f) chatbot = Chatbot(config=config) while True: sentence = input("You (qで終了): ") stripped = sentence.strip() if not stripped: continue if stripped.lower() == "q": break print() print("Chatbot: ") prev_text = "" for data in chatbot.ask(stripped): message = data["message"][len(prev_text):] print(message, end="", flush=True) prev_text = data["message"] print()
これはpython -m revChatGPT.V1
の実装4と同様です。
応答が少しずつ表示されるのでstreamedだと理解しました。
Basic example (single result)
こちらは1回にまとめて応答を出力する実装です。
差分だけ示します。
while True: # sentenceの取得処理は共通 print() print("Chatbot: ") prev_text = "" for data in chatbot.ask(stripped): - message = data["message"][len(prev_text):] - print(message, end="", flush=True) - prev_text = data["message"] + response = data["message"] + print(response) # ChatGPTからの応答が全部responseにまとまっている print()
少しずつ応答が表示される場合5と違って、処理が動いているのかやや不安になります。
宿題事項
コマンドラインで何回かお話ししてからWeb UIを見ると、たくさんNew chatができていました。
revChatGPT自体はconversation_idの指定をサポートしています。
conversation_idを指定して、続きから話せるようにする(結果的にNew chatばかりにならない)が、次回まず取り組みたいことです。
また、ソースコードにはdebugレベルのログ出力があります。
ログレベルをdebugにして実行することでrevChatGPTの動きをより正確に理解できそうです。
ソースコードにはマジックナンバーの定数がいくつかあるので、Discussionsも見るとよさそうに思いました。
終わりに
ChatGPTにプログラムからアクセスしたく、revChatGPTを触りました。
このライブラリ、簡単な設定で使えてすごいですね(あくまで2023/02/25時点の情報です。OpenAI次第なので明日は分かりません)。
このライブラリが使えている間は、ChatGPTを使ったアプリケーションがすごく開発しやすそうですね。
取り組んでいるシオン・プロジェクトにマッシュアップできるという電波を受信したんですよ!
ChatGPTから始まりLLMが乱立、revChatGPT以外にもよさそうなライブラリはあると思うので、引き続き情報収集していきます。
よさそうなライブラリご存知の方、アウトプットしていただけるとみんな嬉しいんじゃないかと思います〜
- どうやら私は『かがみの孤城』のこころちゃんにChatGPTを使わせたいみたいです(←いや、なんでだ)。初出はこちら:動画や資料でChatGPTのヤバさを遅ればせながら認識!ワクワクもんだぁ! - nikkie-ftnextの日記↩
- 触ってから執筆している間に2.3.10になっていました https://github.com/acheong08/ChatGPT/releases/tag/2.3.10↩
-
設定を試行錯誤する必要があった時もエディタで開くのはワーキングディレクトリ1箇所だけにしたいという都合と、後述のスクリプトでの読み込みで同じディレクトリにあった方が書きやすいかなと考えました。今回はお試し優先で、アプリケーションを作るときにはシンボリックリンクでなく
mv
して配置するかなと思います↩ - https://github.com/acheong08/ChatGPT/blob/2.3.8/src/revChatGPT/V1.py#L526-L540↩
-
askメソッドの実装を覗いたところrequestsでSessionを貼り
stream=True
を指定。ChatGPTのAPIからレスポンスを生データの行ごとにyieldしていました。これによりstreamedは少しずつ出力されます。ref:https://github.com/acheong08/ChatGPT/blob/2.3.8/src/revChatGPT/V1.py#L241-L290 single resultのスクリプトの実装は、for文でジェネレータ(すなわちAPI)が全部返し切るのを待っていますね↩