OpenAI Assistants APIの備忘録

Assistants API を使った開発する上でよく使いそうな処理を備忘録としてリストしておきます。(2023年11月時点)

公式ドキュメント

Assistants APIに関する公式ドキュメントは以下にあります。

Assistants APIはモデルを呼び出し、ツールを使用してタスクを実行することができます。

Assistants APIの仕組みとオブジェクト

Assistants APIで使用するオブジェクト図は以下のようになっています。

https://platform.openai.com/docs/assistants/how-it-works

Assistantは、あるタスクを担ったassistant aiの本体になります。使用するGPTモデルと、基本的な指示(instruction)を持っています。

Threadは、ユーザとアシスタントとの会話における一連のメッセージを適切に保持します。(切り捨ても自動的に処理するとなっていますが、詳細は不明です)

MessageはThreadに含まれています。ユーザからのメッセージとアシスタントが生成したメッセージがリストとして保存されます。

Runは、AssistantとTreadとを受け取って実行します。実行の結果は、Thread内のMessageに追加されます。

Fileオブジェクト

ファイルオブジェクトは、モデルをファインチューニングする場合と、 Assistantsのコンテンツとして使う場合とが想定されています。

上記アシスタントのオブジェクト図には含まれていませんが、Assistantsと組み合わせて使いますので記載しておきます。

ファイルのアップロード

from openai import OpenAI
client = OpenAI()

client.files.create(
  file=open("mydata.jsonl", "rb"),
  purpose="fine-tune"
)

purpose は、"fine-tune", "fine-tune-results", "assistants", "assistants_output"のいずれかの値をとります。

ファイルのリスト

アップロード済みのファイルのリストを取得する。

from openai import OpenAI
client = OpenAI()

client.files.list()

戻り値は、ファイルオブジェクトのリストになります。

例)

{
  "data": [
    {
      "id": "file-abc123",
      "object": "file",
      "bytes": 175,
      "created_at": 1613677385,
      "filename": "salesOverview.pdf",
      "purpose": "assistants",
    },
    {
      "id": "file-abc123",
      "object": "file",
      "bytes": 140,
      "created_at": 1613779121,
      "filename": "puppy.jsonl",
      "purpose": "fine-tune",
    }
  ],
  "object": "list"
}

ファイルの削除

アップロード済みのファイルをファイルidを指定して削除します。

from openai import OpenAI
client = OpenAI()

client.files.delete("file-abc123")

Assistantオブジェクト

アシスタントの作成

アシスタントを作成します。

パラメータは、modelのみ必須で、あとはオプションとなります。

instructionには、アシスタントに対する指示が記述されます。

from openai import OpenAI
client = OpenAI()

my_assistant = client.beta.assistants.create(
    instructions="You are an HR bot, and you have access to files to answer employee questions about company policies.",
    name="HR Helper",
    tools=[{"type": "retrieval"}],
    model="gpt-4",
    file_ids=["file-abc123"],
)
print(my_assistant)

アシスタントの取得

アシスタントIDを指定してアシスタントオブジェクトのインスタンスを取得します。

from openai import OpenAI
client = OpenAI()

my_assistant = client.beta.assistants.retrieve("asst_abc123")

アシスタントの変更

アシスタントidを指定して、アシスタントパラメータを変更します。

from openai import OpenAI
client = OpenAI()

my_updated_assistant = client.beta.assistants.update(
  "asst_abc123",
  instructions="You are an HR bot, and you have access to files to answer employee questions about company policies. Always response with info from either of the files.",
  name="HR Helper",
  tools=[{"type": "retrieval"}],
  model="gpt-4",
  file_ids=["file-abc123", "file-abc456"],
)

アシスタントの削除

アシスタントIDを指定してアシスタントを削除します。

from openai import OpenAI
client = OpenAI()

response = client.beta.assistants.delete("asst_abc123")

Threadオブジェクト

スレッドはユーザとの一連の対話を保持するオブジェクトです。

スレッドの作成

スレッドオブジェクトを作成します。

from openai import OpenAI
client = OpenAI()

empty_thread = client.beta.threads.create()

スレッドの取得

from openai import OpenAI
client = OpenAI()

my_thread = client.beta.threads.retrieve("thread_abc123")

スレッドの変更

from openai import OpenAI
client = OpenAI()

my_updated_thread = client.beta.threads.update(
  "thread_abc123", 
  metadata={
    "modified": "true", 
    "user": "abc123"
  }
)

スレッドの削除

スレッドオブジェクトを削除します。

from openai import OpenAI
client = OpenAI()

response = client.beta.threads.delete("thread_abc123")

Messageオブジェクト

メッセージオブジェクトはスレッドオブジェクトに含まれます。スレッドidを指定して作成します。

メッセージの作成

スレッドオブジェクト内にメッセージオブジェクトを追加します。

from openai import OpenAI
client = OpenAI()

thread_message = client.beta.threads.messages.create(
  "thread_abc123",
  role="user",
  content="How does AI work? Explain it in simple terms.",
)
print(thread_message)

{
  "id": "msg_abc123",
  "object": "thread.message",
  "created_at": 1699017614,
  "thread_id": "thread_abc123",
  "role": "user",
  "content": [
    {
      "type": "text",
      "text": {
        "value": "How does AI work? Explain it in simple terms.",
        "annotations": []
      }
    }
  ],
  "file_ids": [],
  "assistant_id": null,
  "run_id": null,
  "metadata": {}
}

ファイルIDとメタデータをオプションでつけることができます。

メッセージの取得

スレッドオブジェクト内のメッセージから、メッセージIDを指定して特定のメッセージオブジェクトを取得します。

from openai import OpenAI
client = OpenAI()

message = client.beta.threads.messages.retrieve(
  message_id="msg_abc123",
  thread_id="thread_abc123",
)
print(message)

{
  "id": "msg_abc123",
  "object": "thread.message",
  "created_at": 1699017614,
  "thread_id": "thread_abc123",
  "role": "user",
  "content": [
    {
      "type": "text",
      "text": {
        "value": "How does AI work? Explain it in simple terms.",
        "annotations": []
      }
    }
  ],
  "file_ids": [],
  "assistant_id": null,
  "run_id": null,
  "metadata": {}
}

メッセージの変更

メッセージIDとスレッドIDとを指定して、メッセージオブジェクトを変更します。以下の例では、metadataに値をセットしています。

from openai import OpenAI
client = OpenAI()

message = client.beta.threads.messages.update(
  message_id="msg_abc12",
  thread_id="thread_abc123",
  metadata={
    "modified": "true",
    "user": "abc123",
  },
)
print(message)

以下のようにmetadataが追加されているのがわかります。

{
  "id": "msg_abc123",
  "object": "thread.message",
  "created_at": 1699017614,
  "thread_id": "thread_abc123",
  "role": "user",
  "content": [
    {
      "type": "text",
      "text": {
        "value": "How does AI work? Explain it in simple terms.",
        "annotations": []
      }
    }
  ],
  "file_ids": [],
  "assistant_id": null,
  "run_id": null,
  "metadata": {
    "modified": "true",
    "user": "abc123"
  }
}

メッセージのリストを取得

スレッドオブジェクトに含まれるメッセージのリストを取得します。

from openai import OpenAI
client = OpenAI()

thread_messages = client.beta.threads.messages.list("thread_abc123")
print(thread_messages.data)

以下のような形式でメッセージが入っています。

{
  "object": "list",
  "data": [
    {
      "id": "msg_abc123",
      "object": "thread.message",
      "created_at": 1699016383,
      "thread_id": "thread_abc123",
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": {
            "value": "How does AI work? Explain it in simple terms.",
            "annotations": []
          }
        }
      ],
      "file_ids": [],
      "assistant_id": null,
      "run_id": null,
      "metadata": {}
    },
    {
      "id": "msg_abc456",
      "object": "thread.message",
      "created_at": 1699016383,
      "thread_id": "thread_abc123",
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": {
            "value": "Hello, what is AI?",
            "annotations": []
          }
        }
      ],
      "file_ids": [
        "file-abc123"
      ],
      "assistant_id": null,
      "run_id": null,
      "metadata": {}
    }
  ],
  "first_id": "msg_abc123",
  "last_id": "msg_abc456",
  "has_more": false
}

Runオブジェクト

RunオブジェクトはAssistantとThreadとを指定することで、タスクを実行します。

runの作成

from openai import OpenAI
client = OpenAI()

run = client.beta.threads.runs.create(
  thread_id="thread_abc123",
  assistant_id="asst_abc123"
)

thread_idとassistant_idとは必須です。

以下のパラメータを指定することで、assistant_idのパラメータをオーバーライドすることもできます。

model  
The ID of the Model to be used to execute this run. If a value is provided here, it will override the model associated with the assistant. If not, the model associated with the assistant will be used.

instructions
Override the default system message of the assistant. This is useful for modifying the behavior on a per-run basis.

tools
Override the tools the assistant can use for this run. This is useful for modifying the behavior on a per-run basis.

metadata
Set of 16 key-value pairs that can be attached to an object. This can be useful for storing additional information about the object in a structured format. Keys can be a maximum of 64 characters long and values can be a maxium of 512 characters long.
https://platform.openai.com/docs/api-reference/runs/createRun

runの取得

from openai import OpenAI
client = OpenAI()

run = client.beta.threads.runs.retrieve(
  thread_id="thread_abc123",
  run_id="run_abc123"
)

runの変更

from openai import OpenAI
client = OpenAI()

run = client.beta.threads.runs.update(
  thread_id="thread_abc123",
  run_id="run_abc123",
  metadata={"user_id": "user_abc123"},
)
print(run)

ツールの出力送信 (submit_tool_output)

submit_tool_outputは、Function_callingの実行のために使用します。

When a run has the status: "requires_action" and required_action.type is submit_tool_outputs, this endpoint can be used to submit the outputs from the tool calls once they're all completed. All outputs must be submitted in a single request.

https://platform.openai.com/docs/api-reference/runs/submitToolOutputs

from openai import OpenAI
client = OpenAI()

run = client.beta.threads.runs.submit_tool_outputs(
  thread_id="thread_abc123",
  run_id="run_abc123",
  tool_outputs=[
    {
      "tool_call_id": "call_abc123",
      "output": "28C"
    }
  ]
)
print(run)

”tool_call_id”は、run.statusがrequires_actionの時に、以下のように取得できます。

tool_id = run.required_action.submit_tool_outputs.tool_calls[0].id

"output"はFunctionの結果を指定します。

Threadの作成とRunの同時実行

Threadの作成とrunの実行を一度のリクエストで行います。

from openai import OpenAI
client = OpenAI()

run = client.beta.threads.create_and_run(
  assistant_id="asst_abc123",
  thread={
    "messages": [
      {"role": "user", "content": "Explain deep learning to a 5 year old."}
    ]
  }
)