OpenAI, Assistants API のサンプルコードを動かしてみた
OpenAI が提供する新サービス、 Assistants API について、公式からのドキュメントが公開されていた。いくつかサンプルコードが公開されていたので、実際に実行してみて結果を確認した。
こちらのページでは Assistants API の使い方について、実際のステップごとにコードを提示しながら解説されている。ただ、それぞれにバラバラに記述されているため全体の構造が分かりにくく、Python 初心者の私にはこれで実際に動くコードに仕上げるのは難しそうだな、と感じたので、少しずつ ChatGPT に内容を尋ねながら全体の流れを把握し、最終的に1本のコードにまとめてそれを実行することができた。以下、その記録。
実行環境
Mac OS 14.0 (Sonoma)
Python 3.11.6
openai 1.2.4
仮想環境上で実行
Assistants API を呼び出すのに必要な API キーは、事前に OpenAI の自分のページで生成しておいた。.env ファイルにこのAPIキーを書き込んでおき、それを python コードと同じディレクトリに保存。コードの冒頭でこれを読み込んで openai インスタンスに書き込めば、以降の処理で API 呼び出しが可能となる。
完成したコード
# from openai import OpenAI
import openai
import time
from dotenv import load_dotenv
import os
# .envファイルから環境変数を読み込む
load_dotenv()
# OpenAI APIキーを環境変数から取得
openai.api_key = os.getenv("OPENAI_API_KEY")
# OpenAIのクライアントを初期化
# client = OpenAI()
client = openai.Client()
# アシスタントを作成
assistant = client.beta.assistants.create(
name="Math Tutor",
instructions="You are a personal math tutor. Answer questions briefly, in a sentence or less.",
model="gpt-4-1106-preview",
)
# 作成したアシスタントのIDを取得
MATH_ASSISTANT_ID = assistant.id
# ユーザーのメッセージを送信し、新しいRunを作成する関数
def submit_message(assistant_id, thread, user_message):
client.beta.threads.messages.create(
thread_id=thread.id, role="user", content=user_message
)
return client.beta.threads.runs.create(
thread_id=thread.id,
assistant_id=assistant_id,
)
# スレッドのメッセージを取得する関数
def get_response(thread):
return client.beta.threads.messages.list(thread_id=thread.id, order="asc")
# ユーザー入力に基づいてスレッドとRunを作成する関数
def create_thread_and_run(user_input):
thread = client.beta.threads.create()
run = submit_message(MATH_ASSISTANT_ID, thread, user_input)
return thread, run
# メッセージを整形して表示する補助関数
def pretty_print(messages):
print("# Messages")
for m in messages:
print(f"{m.role}: {m.content[0].text.value}")
print()
# Runの完了を待つ関数
def wait_on_run(run, thread):
while run.status == "queued" or run.status == "in_progress":
run = client.beta.threads.runs.retrieve(
thread_id=thread.id,
run_id=run.id,
)
time.sleep(0.5)
return run
# 3つの異なるユーザー入力に対するスレッドとRunの作成と実行
thread1, run1 = create_thread_and_run("I need to solve the equation `3x + 11 = 14`. Can you help me?")
thread2, run2 = create_thread_and_run("Could you explain linear algebra to me?")
thread3, run3 = create_thread_and_run("I don't like math. What can I do?")
# 各スレッドのRunの完了を待ち、応答を表示
run1 = wait_on_run(run1, thread1)
pretty_print(get_response(thread1))
run2 = wait_on_run(run2, thread2)
pretty_print(get_response(thread2))
run3 = wait_on_run(run3, thread3)
pretty_print(get_response(thread3))
# スレッド3に感謝のメッセージを送信
run4 = submit_message(MATH_ASSISTANT_ID, thread3, "Thank you!")
run4 = wait_on_run(run4, thread3)
pretty_print(get_response(thread3))
1, 14 行目のコメントアウトは、OpenAI のサンプルではこのように記述してあったのだけど、実際に実行してみたらうまく行かなかったので、(ChatGPTの意向で)このように修正した。
出力結果
# Messages
user: I need to solve the equation `3x + 11 = 14`. Can you help me?
assistant: Yes, to solve the equation `3x + 11 = 14`, subtract 11 from both sides to get `3x = 3`, and then divide by 3 to find `x = 1`.
# Messages
user: Could you explain linear algebra to me?
assistant: Linear algebra is the branch of mathematics concerning linear equations, linear functions, and their representations through matrices and vector spaces.
# Messages
user: I don't like math. What can I do?
assistant: Find aspects of math that relate to your interests, apply it to real-world problems you care about, or try different learning methods to make it more enjoyable.
# Messages
user: I don't like math. What can I do?
assistant: Find aspects of math that relate to your interests, apply it to real-world problems you care about, or try different learning methods to make it more enjoyable.
user: Thank you!
assistant: You're welcome! If you have more questions or need assistance with math, feel free to ask.
Assistants API の利用における主要なステップ
0. OpenAIのAPI利用環境をセットアップ(APIキー設定など)。
1. アシスタントを作成: `client.beta.assistants.create()`
2. スレッドを作成: `client.beta.threads.create()`
3. スレッドにメッセージを送信: `client.beta.threads.messages.create()`
4. アシスタントとスレッドを指定して実行。
5. 実行が完了するのを待つ。
6. APIによって情報が追加されたスレッドを取得(および出力)。
同じスレッドで会話を続けたい場合はステップ3以降を繰り返し、新しいスレッドを立ち上げたい場合はステップ2以降を繰り返します。異なるアシスタントを使用したい場合はステップ1からやり直します。これにより、柔軟にさまざまな会話シナリオやアシスタントの機能を利用することができます。
余談
私のプログラミング知識は20年前のC言語で止まったままになっていて、ついぞオブジェクト指向(もはや死語?!)というのが理解できないままになっていた。今回 Python を触ってみて当然のようにオブジェクト指向の記述で面食らったが、そこは何度でも納得の行くまで質問に付き合ってくれる ChatGPT の助力もあって、ある程度は理解が進んだと思う。本当にありがたい技術だ。