1
2

More than 1 year has passed since last update.

【python3】GPT-3.5 APIを、本家サイト風に使う

Posted at

背景

  • chatGPTを使って業務でラクしたり、色々実験したりしたいが、実行に時間がかかるし、やりとりが学習に使われる可能性があり機密情報に気を使わないといけない、サイトに訪問するのも面倒臭い(たまに繋がらないし)
  • gpt-3.5-turbo のAPIが公開されたので、これを使えばchatGPTをCLI上でも使える。しかしこれだけでは色々問題があった。具体的には
    • いちいちHTTPリクエスト書くのは面倒だし、実験の速度が重要なので、API実行速度以外の障壁をなるべく無くしたい
    • 出力をmarkdown記法としてレンダリングしてほしい
    • 過去のやり取りを読み込んだり、スレッドを複数作成して並行して話をしたり、気に入らない回答の再生成をしたり、本家サイトと同様の機能が欲しい。リアルタイム出力は遅くなるならいらない。
  • そこで、"pythonなら書けるし、きっとjupyterなら出力をmarkdownとしてレンダリングしてくれるだろう"と思い至り、「ぼくだけのChat-GPT環境」を作ってみることにした。

前提

筆者はM1MacBookを使っており、バージョンはMonterey(12.6.2)です。
python3が最初から使える状態でスタートします

APIKeyの発行

まずはAPIKeyの発行です。APIKeyは、 OpenAIにログインの後、View APIKeyページのCreate new secret keyというボタンから発行することができます。(発行したキーを保管しておきましょう)

ライブラリのインストール

pythonのパッケージ管理ツールであるpipを使って、必要なライブラリをインストールします

$ python3 -m pip install openai
$ python3 -m pip install jupyterlab

openaiは、その名の通りopenAIのAPIを扱うためのpythonライブラリで
jupyterlabは、ブラウザで動くpythonの開発環境です。
(IPythonをつかってmarkdownを扱うため、SpyderでもPyCharmでも、VSCodeでも、IPython環境さえあれば問題ないです。)

jupyterlabの起動

python3 -m jupyterlab -port 8888

これでおそらくブラウザが立ち上がり
image.png
こんな感じの画面になると思います。

ここで、 まずOtherのPython Fileをクリックして、 gptAPIを使うための自作モジュールを作ります

gpt.pyの作成

import openai
from IPython.display import Markdown, display
openai.api_key = "apikey"  # ここに前工程で作成したAPIKeyをいれる

def role_content(content, role="user"):
    return {"role": role, "content": content}


class Thread:
    content_tree = []
    latest_response = None
    # APIのstopパラメータに入れても良いのだが、出力が途中で切れるのが悲しいので、プロンプトにしてみた。
    system_prompt = role_content("質問には最長でも2000文字程度で回答してください","system")
    max_depth = 10


    def set_system_prompt(self, content):
        self.system_prompt = role_content(content, "system")
    

    def question(self, content=None):

        if self.latest_response:
            self.content_tree.append(self.latest_response)
            self.latest_response = None
        if content:
            self.content_tree.append(role_content(content, "user"))
        if len(self.content_tree) > self.max_depth:
            self.content_tree = self.content_tree[-selfmax_depth:]

        response = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=[self.system_prompt]+self.content_tree)

        self.latest_response = role_content(response['choices'][0]["message"]["content"], "assistant")
        display(Markdown(self.latest_response["content"]))
        return(self.latest_response["content"])


    def regenelate(self):

        self.latest_response = None
        response = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=[self.system_prompt]+self.content_tree)
        self.latest_response = role_content(response['choices'][0]["message"]["content"], "assistant")
        display(Markdown(self.latest_response["content"]+"\n(再生成)"))

        return(self.latest_response["content"])


def q(content, prompt=None, thread=None):
    if not thread:
        thread = Thread()
    if prompt:
        thread.set_system_prompt(prompt)
    thread.question(content)
    return thread


def r(thread):
    thread.regenelate()

untitled.pyとしてファイルが作成されるはずなので、 これをgpt.pyなど分かりやすい名前にしておく

いざ実行

これで下準備は全て終わり。

使い方

上タブから、ランチャーを開き、一番上のNotebook(python3)をクリック

まず

import gpt

で先ほど作ったモジュールを読み込み、

t1 = gpt.q("質問文字列")

で出力される というのがメインの使い方です。 この続きを出力したいときは

t1 = gpt.q("つづきの質問", thread=t1)

とでき、 またプロンプトを与えたい時は

t1 = gpt.q("つづきの質問", prompt="あなたは哲学者です", thread=t1)

のような形で使えます。
この場合 t1 がスレッドのインスタンスなので、 別のスレッドで会話を始めたい時は

t2 = gpt.q("別の質問")

とすれば、別スレッドが作成されるし、t1での最後のやり取りが気に入らなかったら
 

gpt.r(t)

で再度出力を吐き出します
別スレッドは別notebookを作成して実行するのがグラフィカルにもよさそうですね。

実行例

こんな感じで、ちゃんとマークダウン出力をレンダリングできました!
image.png

さいごに

結構細かい操作ができるGPT環境ができて個人的には満足です。
やっていることはpythonコードの実行なので、pythonが苦痛なく使える人は、結構使いやすいんじゃないかなと思います。
また今回はサボりましたが、APIのパラメータ類ももっと入れられるはずなので、実験が進んだらそこらへんも調整しやすい仕組みを作ろうかと思います。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2