見出し画像

OpenAIの新発表『Assistants API』を試す

皆さん、11/7 AM3:00に始まったOpenAI DevDayはもうご覧になったでしょうか?

私は運良く海外にいて無理なくリアルタイムで聞くことができたのですが、1時間の発表の間、終始驚かされていたので体調が悪いです。

いろいろすごい機能が発表されたのですが、今回はその中の一つ、Assistants APIについて、解説と実行してみたという内容の記事を書こうと思います。

ちなみに下記の内容のほぼ意訳なので、英語が読める方はこちらを見てもらったほうが早いです。

Assistants APIとは?

The Assistants API allows you to build AI assistants within your own applications. An Assistant has instructions and can leverage models, tools, and knowledge to respond to user queries. The Assistants API currently supports three types of tools: Code Interpreter, Retrieval, and Function calling. In the future, we plan to release more OpenAI-built tools, and allow you to provide your own tools on our platform.

つまりアシスタント API を使用すると、独自アプリの中で AI アシスタントを構築できるようになります。そのまんまですね。
このAIアシスタントが様々なOpenAIモデルやツール使用して、ユーザーの質問に答えます。

現在使えるツールは、Code Interpreter、Knowledge Retrieval(検索)、Function Callingの3 種類ですが、今後OpenAI社によって拡充される予定とのこと。

早速使ってみる

百聞は一見にしかず、上の説明だとふわっとしか伝わらないと思うので動かしてみましょう。

環境

python 3.10

ソースコード

# assistant.py

import time
from openai import OpenAI
from dotenv import load_dotenv

load_dotenv()
client = OpenAI()

assistant = client.beta.assistants.create(
    name="Math Tutor",
    instructions="You are a personal math tutor. Write and run code to answer math questions.",
    tools=[{"type": "code_interpreter"}],
    model="gpt-4-1106-preview"
)

thread = client.beta.threads.create()

message = client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content="I need to solve the equation `3x + 11 = 14`. Can you help me?"
)

run = client.beta.threads.runs.create(
    thread_id=thread.id,
    assistant_id=assistant.id,
    instructions="Please address the user as Jane Doe. The user has a premium account."
)

while True:
    run = client.beta.threads.runs.retrieve(
        thread_id=thread.id,
        run_id=run.id
    )
    print(run.status)
    if run.status == "completed":
        break
    time.sleep(1)

messages = client.beta.threads.messages.list(
  thread_id=thread.id
)

for message in messages:
    print(message.content)
# .env

OPENAI_API_KEY='sk-xxxxx'
# requirements.txt

openai
python-dotenv


解説

アシスタント

assistant = client.beta.assistants.create(
    name="Math Tutor",
    instructions="You are a personal math tutor. Write and run code to answer math questions.",
    tools=[{"type": "code_interpreter"}],
    model="gpt-4-1106-preview"
)

アシスタントを作成します。名前、どのように役割なのか、使えるツール、モデルを指定します。
instructions が従来のSystemプロンプト的な役割と思ってもらえればよいかと思います。アシスタントなので、名前を指定できるのが面白いですね。

スレッド

thread = client.beta.threads.create()

スレッドを作成します。スレッドは会話のことだと思ってもらえればよいです。同じアシスタントにも複数の会話があると思ってもらえれば理解しやすいかなと思います。

ちなみにthreadは作成時に会話を指定しておくことも可能です。

thread = client.beta.threads.create(
  messages=[
    {
      "role": "user",
      "content": "Create 3 data visualizations based on the trends in this file."
    }
  ]
)

メッセージ


message = client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content="I need to solve the equation `3x + 11 = 14`. Can you help me?"
)

スレッドに含めるメッセージです。上記2つのどちらの方法でも問題ありません。

実行

会話を開始します。
そのためには、Runを作成する必要があります。
ここで、どのアシスタントがどのような会話をどういう条件で行えばいいかを指定します。
ちなみにこのステップでは結果は取得できません。

run = client.beta.threads.runs.create(
    thread_id=thread.id,
    assistant_id=assistant.id,
    instructions="Please address the user as Jane Doe. The user has a premium account."
)

Runにはライフサイクルがあり、実行したら下記のように状態を遷移します。

結果はRunを実行したあと、自動的にmessagesに保存されているのですが(再度取得する必要があります)、いつ終わったかを確認するためにretrieve関数でRunのライフサイクル情報を取得して、完了していたら結果を返すようにしました。

while True:
    run = client.beta.threads.runs.retrieve(
        thread_id=thread.id,
        run_id=run.id
    )
    print(run.status)
    if run.status == "completed":
        break
    time.sleep(1)

messages = client.beta.threads.messages.list(
  thread_id=thread.id
)

for message in messages:
    print(message.content)

実行結果

-> % pip install -r requirements.txt
-> % python assistant.py
in_progress
in_progress
in_progress
in_progress
completed
ThreadMessage(id='msg_BF1WEnTLaa72BFFrMf8wExvO', assistant_id='asst_JWYgJV9HL4Z85ywT62EjB68n', content=[MessageContentText(text=Text(annotations=[], value='The solution to the equation `3x + 11 = 14` is `x = 1`.'), type='text')], created_at=1699308737, file_ids=[], metadata={}, object='thread.message', role='assistant', run_id='run_1qzcEZvMNnza0Beq1lsb9wFW', thread_id='thread_pzs3LKOzYG3WHtTJZnCkWxNt')
ThreadMessage(id='msg_3G5EOwwwSdmrxgjRSdBfOs71', assistant_id=None, content=[MessageContentText(text=Text(annotations=[], value='I need to solve the equation `3x + 11 = 14`. Can you help me?'), type='text')], created_at=1699308732, file_ids=[], metadata={}, object='thread.message', role='user', run_id=None, thread_id='thread_pzs3LKOzYG3WHtTJZnCkWxNt')

ちゃんと結果が取得できていますね!!

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