Teilen über


Erste Schritte mit Azure OpenAI Assistants (Vorschau)

Mit Azure OpenAI Assistants (Vorschau) können Sie KI-Assistenten erstellen, die dank benutzerdefinierte Anweisungen auf Ihre Anforderungen zugeschnitten sind und durch erweiterte Tools wie Code Interpreter und benutzerdefinierte Funktionen ergänzt werden. In diesem Artikel finden Sie eine ausführliche exemplarische Vorgehensweise für die ersten Schritte mit der Assistenten-API.

Hinweis

  • Die Dateisuche kann bis zu 10.000 Dateien pro Assistent erfassen – 500 mal mehr als bisher. Sie ist schnell, unterstützt parallele Abfragen durch Multithreadsuchvorgänge und beinhaltet verbesserte Funktionen für Neusortierung und das Umschreiben von Abfragen.
    • Der Vektorspeicher ist ein neues Objekt in der API. Sobald eine Datei einem Vektorspeicher hinzugefügt wurde, wird sie automatisch geparst, aufgeteilt und eingebettet, damit sie durchsucht werden kann. Vektorspeicher können über Assistenten und Threads hinweg verwendet werden und vereinfachen so die Dateiverwaltung und Abrechnung.
  • Wir haben Unterstützung für den Parameter tool_choice hinzugefügt. Dieser kann verwendet werden, um die Nutzung eines bestimmten Tools (z. B. Dateisuche, Codeinterpreter oder eine Funktion) in einer bestimmten Ausführung zu erzwingen.

Support von Assistants

Support für Region und Modell

Codeinterpreter ist in allen Regionen verfügbar, die von den Azure OpenAI-Assistenten unterstützt werden. Die Modellseite enthält die aktuellsten Informationen zu Regionen/Modellen, in denen Assistants derzeit unterstützt werden.

API-Versionen

  • 2024-02-15-preview
  • 2024-05-01-preview

Unterstützte Dateitypen

Dateiformat MIME-Typ Code Interpreter
c. text/x-c
.cpp text/x-c++
.csv application/csv
.docx application/vnd.openxmlformats-officedocument.wordprocessingml.document
.html text/html
.java text/x-java
.json application/json
.md text/markdown
.PDF application/pdf
.php text/x-php
.pptx application/vnd.openxmlformats-officedocument.presentationml.presentation
.py text/x-python
.py text/x-script.python
.rb text/x-ruby
.tex text/x-tex
.txt text/plain
.css text/css
JPEG image/jpeg
.jpg image/jpeg
.js text/javascript
.gif image/gif
.png image/png
.tar application/x-tar
.ts application/typescript
.xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
.xml application/xml oder „text/xml“
.zip application/zip

Extras

Tipp

Wir haben Unterstützung für den tool_choice-Parameter hinzugefügt, der verwendet werden kann, um die Verwendung eines bestimmten Tools zu erzwingen (z. B. file_search, code_interpreter oder function) in einer bestimmten Ausführung.

Ein einzelner Assistent kann auf bis zu 128 Tools zugreifen, einschließlich Codeinterpreter und Dateisuche. Sie können über Funktionen aber auch Ihre eigenen benutzerdefinierten Tools definieren.

Dateien

Dateien können über Studio oder programmgesteuert hochgeladen werden. Der file_ids-Parameter ist erforderlich, um Tools wie code_interpreter den Zugriff auf Dateien zu gewähren. Bei Verwendung des Dateiuploadendpunkts müssen Sie den purpose auf „Assistenten“ festgelegt haben, die mit der Assistants-API verwendet werden sollen.

Assistants-Playground

In unserem Schnellstarthandbuch finden Sie eine exemplarische Vorgehensweise für den Assistants-Playground. Dieser bietet eine Umgebung ohne Code zum Testen der Funktionen von Assistenten.

Assistants-Komponenten

Komponente Beschreibung
Assistent Benutzerdefinierte KI, die Azure OpenAI-Modelle in Verbindung mit Tools verwendet.
Thread Eine Unterhaltungssitzung zwischen einem Assistenten und Benutzer*innen. Threads speichern Nachrichten und behandeln automatisch das Abschneiden, um Inhalte in den Kontext eines Modells einzupassen.
Meldung Eine Nachricht, die von einem Assistenten oder von Benutzer*innen erstellt wurde. Nachrichten können Text, Bilder und andere Dateien enthalten. Nachrichten werden als Liste im Thread gespeichert.
Run Aktivierung eines Assistenten, der basierend auf dem Inhalt des Threads mit der Ausführung beginnen soll. Der Assistent verwendet seine Konfiguration und die Nachrichten des Threads, um Aufgaben durch Aufrufen von Modellen und Tools auszuführen. Als Teil einer Ausführung fügt der Assistent Nachrichten an den Thread an.
Ausführungsschritt Eine detaillierte Liste der Schritte, die der Assistent als Teil einer Ausführung durchgeführt hat. Ein Assistent kann während seiner Ausführung Tools aufrufen oder Nachrichten erstellen. Wenn Sie die Ausführungsschritte untersuchen, können Sie verstehen, wie der Assistent zu seinen endgültigen Ergebnissen gelangt.

Einrichten Ihres ersten Assistenten

Erstellen eines Assistenten

In diesem Beispiel erstellen wir einen Assistenten, der Code schreibt, um Visualisierungen mithilfe der Funktionen des code_interpreter-Tools zu generieren. Die folgenden Beispiele sollen sequenziell in einer Umgebung wie Jupyter-Notebooksausgeführt werden.

import os
import json
from openai import AzureOpenAI
    
client = AzureOpenAI(
    api_key=os.getenv("AZURE_OPENAI_API_KEY"),  
    api_version="2024-05-01-preview",
    azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
    )

# Create an assistant
assistant = client.beta.assistants.create(
    name="Data Visualization",
    instructions=f"You are a helpful AI assistant who makes interesting visualizations based on data." 
    f"You have access to a sandboxed environment for writing and testing code."
    f"When you are asked to create a visualization you should follow these steps:"
    f"1. Write the code."
    f"2. Anytime you write new code display a preview of the code to show your work."
    f"3. Run the code to confirm that it runs."
    f"4. If the code is successful display the visualization."
    f"5. If the code is unsuccessful display the error message and try to revise the code and rerun going through the steps from above again.",
    tools=[{"type": "code_interpreter"}],
    model="gpt-4-1106-preview" #You must replace this value with the deployment name for your model.
)

Es gibt ein paar Details, die Sie bei der obigen Konfiguration beachten sollten:

  • Wir ermöglichen diesem Assistenten den Zugriff auf Code Interpreter mit der Zeile tools=[{"type": "code_interpreter"}],. Dadurch erhält das Modell Zugriff auf eine Python-Umgebung in einer Sandbox, um Code auszuführen, um Antworten auf die Frage von Benutzer*innen zu formulieren.
  • In den Anweisungen erinnern wir das Modell daran, dass es Code ausführen kann. Manchmal braucht das Modell Hilfe, um das richtige Tool zur Lösung einer bestimmten Anfrage zu finden. Wenn Sie wissen, dass Sie eine bestimmte Bibliothek verwenden möchten, um eine bestimmte Antwort zu generieren, von der Sie wissen, dass sie Teil von Codeinterpreter ist, kann es helfen, Anleitungen bereitzustellen, indem Sie etwas wie „Matplotlib verwenden, um X auszuführen“ sagen.
  • Da dies Azure OpenAI ist, muss der von Ihnen eingegebene Wert model=mit dem Bereitstellungsnamen übereinstimmen.

Als Nächstes werden wir den Inhalt des soeben erstellten Assistenten ausgeben, um zu bestätigen, dass die Erstellung erfolgreich war:

print(assistant.model_dump_json(indent=2))
{
  "id": "asst_7AZSrv5I3XzjUqWS40X5UgRr",
  "created_at": 1705972454,
  "description": null,
  "file_ids": [],
  "instructions": "You are a helpful AI assistant who makes interesting visualizations based on data.You have access to a sandboxed environment for writing and testing code.When you are asked to create a visualization you should follow these steps:1. Write the code.2. Anytime you write new code display a preview of the code to show your work.3. Run the code to confirm that it runs.4. If the code is successful display the visualization.5. If the code is unsuccessful display the error message and try to revise the code and rerun going through the steps from above again.",
  "metadata": {},
  "model": "gpt-4-1106-preview",
  "name": "Data Visualization",
  "object": "assistant",
  "tools": [
    {
      "type": "code_interpreter"
    }
  ]
}

Erstellen eines Threads

Erstellen Sie nun einen Thread.

# Create a thread
thread = client.beta.threads.create()
print(thread)
Thread(id='thread_6bunpoBRZwNhovwzYo7fhNVd', created_at=1705972465, metadata={}, object='thread')

Ein Thread ist im Wesentlichen der Datensatz der Unterhaltungssitzung zwischen dem Assistenten und Benutzer*innen. Es ähnelt dem Array/der Liste der Nachrichten in einem typischen Chatabschluss-API-Aufruf. Einer der Hauptunterschiede besteht darin, dass Sie im Gegensatz zu einem Array mit Chat-Abschlussnachrichten nicht bei jedem Aufruf Token verfolgen müssen, um sicherzustellen, dass Sie unter der Kontextlänge des Modells bleiben. Threads abstrahieren dieses Verwaltungsdetail und komprimieren den Threadverlauf nach Bedarf, damit die Unterhaltung fortgesetzt werden kann. Die Fähigkeit von Threads, dies mit größeren Unterhaltungen zu erreichen, wird verbessert, wenn Sie die neuesten Modelle verwenden, die über größere Kontextlängen und Support für die neuesten Features verfügen.

Erstellen Sie als Nächstes die erste Benutzerfrage, die Sie dem Thread hinzufügen möchten.

# Add a user question to the thread
message = client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content="Create a visualization of a sinewave"
)

Threadnachrichten auflisten

thread_messages = client.beta.threads.messages.list(thread.id)
print(thread_messages.model_dump_json(indent=2))
{
  "data": [
    {
      "id": "msg_JnkmWPo805Ft8NQ0gZF6vA2W",
      "assistant_id": null,
      "content": [
        {
          "text": {
            "annotations": [],
            "value": "Create a visualization of a sinewave"
          },
          "type": "text"
        }
      ],
      "created_at": 1705972476,
      "file_ids": [],
      "metadata": {},
      "object": "thread.message",
      "role": "user",
      "run_id": null,
      "thread_id": "thread_6bunpoBRZwNhovwzYo7fhNVd"
    }
  ],
  "object": "list",
  "first_id": "msg_JnkmWPo805Ft8NQ0gZF6vA2W",
  "last_id": "msg_JnkmWPo805Ft8NQ0gZF6vA2W",
  "has_more": false
}

Thread ausführen

run = client.beta.threads.runs.create(
  thread_id=thread.id,
  assistant_id=assistant.id,
  #instructions="New instructions" #You can optionally provide new instructions but these will override the default instructions
)

Wir könnten hier auch einen instructions-Parameter übergeben, aber dies würde die vorhandenen Anweisungen außer Kraft setzen, die wir bereits für den Assistenten bereitgestellt haben.

Threadstatus abrufen

# Retrieve the status of the run
run = client.beta.threads.runs.retrieve(
  thread_id=thread.id,
  run_id=run.id
)

status = run.status
print(status)
completed

Je nach der Komplexität der Abfrage, die Sie ausführen, könnte die Ausführung des Threads länger dauern. In diesem Fall können Sie eine Schleife erstellen, um den Ausführungsstatus des Threads mit Code wie dem folgenden Beispiel zu überwachen:

import time
from IPython.display import clear_output

start_time = time.time()

status = run.status

while status not in ["completed", "cancelled", "expired", "failed"]:
    time.sleep(5)
    run = client.beta.threads.runs.retrieve(thread_id=thread.id,run_id=run.id)
    print("Elapsed time: {} minutes {} seconds".format(int((time.time() - start_time) // 60), int((time.time() - start_time) % 60)))
    status = run.status
    print(f'Status: {status}')
    clear_output(wait=True)

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

print(f'Status: {status}')
print("Elapsed time: {} minutes {} seconds".format(int((time.time() - start_time) // 60), int((time.time() - start_time) % 60)))
print(messages.model_dump_json(indent=2))

Wenn eine Ausführung im Status in_progress ist oder sich in anderen nicht-terminalen Zuständen befindet, ist der Thread gesperrt. Wenn ein Thread gesperrt ist, können keine neuen Nachrichten hinzugefügt werden, und neue Ausführungen können nicht erstellt werden.

Threadnachrichten nach der Ausführung auflisten

Sobald der Ausführungsstatus den erfolgreichen Abschluss anzeigt, können Sie den Inhalt des Threads erneut auflisten, um die Antwort des Modells und aller Tools abzurufen:

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

print(messages.model_dump_json(indent=2))
{
  "data": [
    {
      "id": "msg_M5pz73YFsJPNBbWvtVs5ZY3U",
      "assistant_id": "asst_eHwhP4Xnad0bZdJrjHO2hfB4",
      "content": [
        {
          "text": {
            "annotations": [],
            "value": "Is there anything else you would like to visualize or any additional features you'd like to add to the sine wave plot?"
          },
          "type": "text"
        }
      ],
      "created_at": 1705967782,
      "file_ids": [],
      "metadata": {},
      "object": "thread.message",
      "role": "assistant",
      "run_id": "run_AGQHJrrfV3eM0eI9T3arKgYY",
      "thread_id": "thread_ow1Yv29ptyVtv7ixbiKZRrHd"
    },
    {
      "id": "msg_oJbUanImBRpRran5HSa4Duy4",
      "assistant_id": "asst_eHwhP4Xnad0bZdJrjHO2hfB4",
      "content": [
        {
          "image_file": {
            "file_id": "assistant-1YGVTvNzc2JXajI5JU9F0HMD"
          },
          "type": "image_file"
        },
        {
          "text": {
            "annotations": [],
            "value": "Here is the visualization of a sine wave: \n\nThe wave is plotted using values from 0 to \\( 4\\pi \\) on the x-axis, and the corresponding sine values on the y-axis. I've also added grid lines for easier reading of the plot."
          },
          "type": "text"
        }
      ],
      "created_at": 1705967044,
      "file_ids": [],
      "metadata": {},
      "object": "thread.message",
      "role": "assistant",
      "run_id": "run_8PsweDFn6gftUd91H87K0Yts",
      "thread_id": "thread_ow1Yv29ptyVtv7ixbiKZRrHd"
    },
    {
      "id": "msg_Pu3eHjM10XIBkwqh7IhnKKdG",
      "assistant_id": null,
      "content": [
        {
          "text": {
            "annotations": [],
            "value": "Create a visualization of a sinewave"
          },
          "type": "text"
        }
      ],
      "created_at": 1705966634,
      "file_ids": [],
      "metadata": {},
      "object": "thread.message",
      "role": "user",
      "run_id": null,
      "thread_id": "thread_ow1Yv29ptyVtv7ixbiKZRrHd"
    }
  ],
  "object": "list",
  "first_id": "msg_M5pz73YFsJPNBbWvtVs5ZY3U",
  "last_id": "msg_Pu3eHjM10XIBkwqh7IhnKKdG",
  "has_more": false
}

Datei-ID abrufen

Wir hatten gefordert, dass das Modell ein Bild einer Sinuswelle erzeugt. Um das Bild herunterzuladen, müssen wir zuerst die Datei-ID der Bilder abrufen.

data = json.loads(messages.model_dump_json(indent=2))  # Load JSON data into a Python object
image_file_id = data['data'][0]['content'][0]['image_file']['file_id']

print(image_file_id)  # Outputs: assistant-1YGVTvNzc2JXajI5JU9F0HMD

Image herunterladen

content = client.files.content(image_file_id)

image= content.write_to_file("sinewave.png")

Öffnen Sie das Bild lokal, nachdem es heruntergeladen wurde:

from PIL import Image

# Display the image in the default image viewer
image = Image.open("sinewave.png")
image.show()

Screenshot einer von Code Interpreter generierten Sinuswelle

Stellen einer Folgefrage im Thread

Da der Assistent unsere Anweisungen nicht ganz gefolgt ist und den Code, der ausgeführt wurde, nicht in den Textteil seiner Antwort aufgenommen hat, werden wir ausdrücklich nach diesen Informationen fragen.

# Add a new user question to the thread
message = client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content="Show me the code you used to generate the sinewave"
)

Auch hier müssen wir den Threads ausführen und den Status abrufen:

run = client.beta.threads.runs.create(
  thread_id=thread.id,
  assistant_id=assistant.id,
  #instructions="New instructions" #You can optionally provide new instructions  but these will override the default instructions
)

# Retrieve the status of the run
run = client.beta.threads.runs.retrieve(
  thread_id=thread.id,
  run_id=run.id
)

status = run.status
print(status)

completed

Sobald die Ausführung den Status „abgeschlossen“ erreicht, werden wird die Nachrichten im Thread erneut auflisten, welche jetzt die Antwort auf unsere aktuelle Frage enthalten sollten.

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

print(messages.model_dump_json(indent=2))
{
  "data": [
    {
      "id": "msg_oaF1PUeozAvj3KrNnbKSy4LQ",
      "assistant_id": "asst_eHwhP4Xnad0bZdJrjHO2hfB4",
      "content": [
        {
          "text": {
            "annotations": [],
            "value": "Certainly, here is the code I used to generate the sine wave visualization:\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# Generating data for the sinewave\nx = np.linspace(0, 4 * np.pi, 1000)  # Generate values from 0 to 4*pi\ny = np.sin(x)  # Compute the sine of these values\n\n# Plotting the sine wave\nplt.plot(x, y)\nplt.title('Sine Wave')\nplt.xlabel('x')\nplt.ylabel('sin(x)')\nplt.grid(True)\nplt.show()\n```\n\nThis code snippet uses `numpy` to generate an array of x values and then computes the sine for each x value. It then uses `matplotlib` to plot these values and display the resulting graph."
          },
          "type": "text"
        }
      ],
      "created_at": 1705969710,
      "file_ids": [],
      "metadata": {},
      "object": "thread.message",
      "role": "assistant",
      "run_id": "run_oDS3fH7NorCUVwROTZejKcZN",
      "thread_id": "thread_ow1Yv29ptyVtv7ixbiKZRrHd"
    },
    {
      "id": "msg_moYE3aNwFYuRq2aXpxpt2Wb0",
      "assistant_id": null,
      "content": [
        {
          "text": {
            "annotations": [],
            "value": "Show me the code you used to generate the sinewave"
          },
          "type": "text"
        }
      ],
      "created_at": 1705969678,
      "file_ids": [],
      "metadata": {},
      "object": "thread.message",
      "role": "user",
      "run_id": null,
      "thread_id": "thread_ow1Yv29ptyVtv7ixbiKZRrHd"
    },
    {
      "id": "msg_M5pz73YFsJPNBbWvtVs5ZY3U",
      "assistant_id": "asst_eHwhP4Xnad0bZdJrjHO2hfB4",
      "content": [
        {
          "text": {
            "annotations": [],
            "value": "Is there anything else you would like to visualize or any additional features you'd like to add to the sine wave plot?"
          },
          "type": "text"
        }
      ],
      "created_at": 1705967782,
      "file_ids": [],
      "metadata": {},
      "object": "thread.message",
      "role": "assistant",
      "run_id": "run_AGQHJrrfV3eM0eI9T3arKgYY",
      "thread_id": "thread_ow1Yv29ptyVtv7ixbiKZRrHd"
    },
    {
      "id": "msg_oJbUanImBRpRran5HSa4Duy4",
      "assistant_id": "asst_eHwhP4Xnad0bZdJrjHO2hfB4",
      "content": [
        {
          "image_file": {
            "file_id": "assistant-1YGVTvNzc2JXajI5JU9F0HMD"
          },
          "type": "image_file"
        },
        {
          "text": {
            "annotations": [],
            "value": "Here is the visualization of a sine wave: \n\nThe wave is plotted using values from 0 to \\( 4\\pi \\) on the x-axis, and the corresponding sine values on the y-axis. I've also added grid lines for easier reading of the plot."
          },
          "type": "text"
        }
      ],
      "created_at": 1705967044,
      "file_ids": [],
      "metadata": {},
      "object": "thread.message",
      "role": "assistant",
      "run_id": "run_8PsweDFn6gftUd91H87K0Yts",
      "thread_id": "thread_ow1Yv29ptyVtv7ixbiKZRrHd"
    },
    {
      "id": "msg_Pu3eHjM10XIBkwqh7IhnKKdG",
      "assistant_id": null,
      "content": [
        {
          "text": {
            "annotations": [],
            "value": "Create a visualization of a sinewave"
          },
          "type": "text"
        }
      ],
      "created_at": 1705966634,
      "file_ids": [],
      "metadata": {},
      "object": "thread.message",
      "role": "user",
      "run_id": null,
      "thread_id": "thread_ow1Yv29ptyVtv7ixbiKZRrHd"
    }
  ],
  "object": "list",
  "first_id": "msg_oaF1PUeozAvj3KrNnbKSy4LQ",
  "last_id": "msg_Pu3eHjM10XIBkwqh7IhnKKdG",
  "has_more": false
}

So extrahieren Sie nur die Antwort auf unsere neueste Frage:

data = json.loads(messages.model_dump_json(indent=2))
code = data['data'][0]['content'][0]['text']['value']
print(code)

Aber sicher, hier ist der Code, den ich zum Generieren der Sinuswellenvisualisierung verwendet habe:

import numpy as np
import matplotlib.pyplot as plt

# Generating data for the sinewave
x = np.linspace(0, 4 * np.pi, 1000)  # Generate values from 0 to 4*pi
y = np.sin(x)  # Compute the sine of these values

# Plotting the sine wave
plt.plot(x, y)
plt.title('Sine Wave')
plt.xlabel('x')
plt.ylabel('sin(x)')
plt.grid(True)
plt.show()

Dunkler Modus

Lassen Sie uns dem Thread eine letzte Frage hinzufügen, um festzustellen, ob Code Interpreter das Diagramm für uns in den dunklen Modus wechseln kann.

# Add a user question to the thread
message = client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content="I prefer visualizations in darkmode can you change the colors to make a darkmode version of this visualization."
)

# Run the thread
run = client.beta.threads.runs.create(
  thread_id=thread.id,
  assistant_id=assistant.id,
)

# Retrieve the status of the run
run = client.beta.threads.runs.retrieve(
  thread_id=thread.id,
  run_id=run.id
)

status = run.status
print(status)
completed
messages = client.beta.threads.messages.list(
  thread_id=thread.id
)

print(messages.model_dump_json(indent=2))
{
  "data": [
    {
      "id": "msg_KKzOHCArWGvGpuPo0pVZTHgV",
      "assistant_id": "asst_eHwhP4Xnad0bZdJrjHO2hfB4",
      "content": [
        {
          "text": {
            "annotations": [],
            "value": "You're viewing the dark mode version of the sine wave visualization in the image above. The plot is set against a dark background with a cyan colored sine wave for better contrast and visibility. If there's anything else you'd like to adjust or any other assistance you need, feel free to let me know!"
          },
          "type": "text"
        }
      ],
      "created_at": 1705971199,
      "file_ids": [],
      "metadata": {},
      "object": "thread.message",
      "role": "assistant",
      "run_id": "run_izZFyTVB1AlFM1VVMItggRn4",
      "thread_id": "thread_ow1Yv29ptyVtv7ixbiKZRrHd"
    },
    {
      "id": "msg_30pXFVYNgP38qNEMS4Zbozfk",
      "assistant_id": null,
      "content": [
        {
          "text": {
            "annotations": [],
            "value": "I prefer visualizations in darkmode can you change the colors to make a darkmode version of this visualization."
          },
          "type": "text"
        }
      ],
      "created_at": 1705971194,
      "file_ids": [],
      "metadata": {},
      "object": "thread.message",
      "role": "user",
      "run_id": null,
      "thread_id": "thread_ow1Yv29ptyVtv7ixbiKZRrHd"
    },
    {
      "id": "msg_3j31M0PaJLqO612HLKVsRhlw",
      "assistant_id": "asst_eHwhP4Xnad0bZdJrjHO2hfB4",
      "content": [
        {
          "image_file": {
            "file_id": "assistant-kfqzMAKN1KivQXaEJuU0u9YS"
          },
          "type": "image_file"
        },
        {
          "text": {
            "annotations": [],
            "value": "Here is the dark mode version of the sine wave visualization. I've used the 'dark_background' style in Matplotlib and chosen a cyan color for the plot line to ensure it stands out against the dark background."
          },
          "type": "text"
        }
      ],
      "created_at": 1705971123,
      "file_ids": [],
      "metadata": {},
      "object": "thread.message",
      "role": "assistant",
      "run_id": "run_B91erEPWro4bZIfryQeIDDlx",
      "thread_id": "thread_ow1Yv29ptyVtv7ixbiKZRrHd"
    },
    {
      "id": "msg_FgDZhBvvM1CLTTFXwgeJLdua",
      "assistant_id": null,
      "content": [
        {
          "text": {
            "annotations": [],
            "value": "I prefer visualizations in darkmode can you change the colors to make a darkmode version of this visualization."
          },
          "type": "text"
        }
      ],
      "created_at": 1705971052,
      "file_ids": [],
      "metadata": {},
      "object": "thread.message",
      "role": "user",
      "run_id": null,
      "thread_id": "thread_ow1Yv29ptyVtv7ixbiKZRrHd"
    },
    {
      "id": "msg_oaF1PUeozAvj3KrNnbKSy4LQ",
      "assistant_id": "asst_eHwhP4Xnad0bZdJrjHO2hfB4",
      "content": [
        {
          "text": {
            "annotations": [],
            "value": "Certainly, here is the code I used to generate the sine wave visualization:\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# Generating data for the sinewave\nx = np.linspace(0, 4 * np.pi, 1000)  # Generate values from 0 to 4*pi\ny = np.sin(x)  # Compute the sine of these values\n\n# Plotting the sine wave\nplt.plot(x, y)\nplt.title('Sine Wave')\nplt.xlabel('x')\nplt.ylabel('sin(x)')\nplt.grid(True)\nplt.show()\n```\n\nThis code snippet uses `numpy` to generate an array of x values and then computes the sine for each x value. It then uses `matplotlib` to plot these values and display the resulting graph."
          },
          "type": "text"
        }
      ],
      "created_at": 1705969710,
      "file_ids": [],
      "metadata": {},
      "object": "thread.message",
      "role": "assistant",
      "run_id": "run_oDS3fH7NorCUVwROTZejKcZN",
      "thread_id": "thread_ow1Yv29ptyVtv7ixbiKZRrHd"
    },
    {
      "id": "msg_moYE3aNwFYuRq2aXpxpt2Wb0",
      "assistant_id": null,
      "content": [
        {
          "text": {
            "annotations": [],
            "value": "Show me the code you used to generate the sinewave"
          },
          "type": "text"
        }
      ],
      "created_at": 1705969678,
      "file_ids": [],
      "metadata": {},
      "object": "thread.message",
      "role": "user",
      "run_id": null,
      "thread_id": "thread_ow1Yv29ptyVtv7ixbiKZRrHd"
    },
    {
      "id": "msg_M5pz73YFsJPNBbWvtVs5ZY3U",
      "assistant_id": "asst_eHwhP4Xnad0bZdJrjHO2hfB4",
      "content": [
        {
          "text": {
            "annotations": [],
            "value": "Is there anything else you would like to visualize or any additional features you'd like to add to the sine wave plot?"
          },
          "type": "text"
        }
      ],
      "created_at": 1705967782,
      "file_ids": [],
      "metadata": {},
      "object": "thread.message",
      "role": "assistant",
      "run_id": "run_AGQHJrrfV3eM0eI9T3arKgYY",
      "thread_id": "thread_ow1Yv29ptyVtv7ixbiKZRrHd"
    },
    {
      "id": "msg_oJbUanImBRpRran5HSa4Duy4",
      "assistant_id": "asst_eHwhP4Xnad0bZdJrjHO2hfB4",
      "content": [
        {
          "image_file": {
            "file_id": "assistant-1YGVTvNzc2JXajI5JU9F0HMD"
          },
          "type": "image_file"
        },
        {
          "text": {
            "annotations": [],
            "value": "Here is the visualization of a sine wave: \n\nThe wave is plotted using values from 0 to \\( 4\\pi \\) on the x-axis, and the corresponding sine values on the y-axis. I've also added grid lines for easier reading of the plot."
          },
          "type": "text"
        }
      ],
      "created_at": 1705967044,
      "file_ids": [],
      "metadata": {},
      "object": "thread.message",
      "role": "assistant",
      "run_id": "run_8PsweDFn6gftUd91H87K0Yts",
      "thread_id": "thread_ow1Yv29ptyVtv7ixbiKZRrHd"
    },
    {
      "id": "msg_Pu3eHjM10XIBkwqh7IhnKKdG",
      "assistant_id": null,
      "content": [
        {
          "text": {
            "annotations": [],
            "value": "Create a visualization of a sinewave"
          },
          "type": "text"
        }
      ],
      "created_at": 1705966634,
      "file_ids": [],
      "metadata": {},
      "object": "thread.message",
      "role": "user",
      "run_id": null,
      "thread_id": "thread_ow1Yv29ptyVtv7ixbiKZRrHd"
    }
  ],
  "object": "list",
  "first_id": "msg_KKzOHCArWGvGpuPo0pVZTHgV",
  "last_id": "msg_Pu3eHjM10XIBkwqh7IhnKKdG",
  "has_more": false
}

Extrahieren Sie die neue Bilddatei-ID, und laden Sie das Bild herunter und zeigen es an:

data = json.loads(messages.model_dump_json(indent=2))  # Load JSON data into a Python object
image_file_id = data['data'][0]['content'][0]['image_file']['file_id'] # index numbers can vary if you have had a different conversation over the course of the thread.

print(image_file_id)

content = client.files.content(image_file_id)
image= content.write_to_file("dark_sine.png")

# Display the image in the default image viewer
image = Image.open("dark_sine.png")
image.show()

Screenshot einer von Code Interpreter generierten Sinuswelle im dunklen Modus

Zusätzliche Referenz

Ausführungsstatusdefinitionen

Status Definition
queued Wenn Ausführungen zum ersten Mal erstellt werden, oder wenn Sie die required_action abschließen, werden sie in einen Status „Warteschlange“ verschoben. Sie sollten fast sofort zu „in_progress“ wechseln.
in_progress Während dem Status „in_progress“ verwendet der Assistent das Modell und die Tools, um Schritte auszuführen. Sie können den Fortschritt der Ausführung anzeigen, indem Sie die Ausführungsschritte untersuchen.
completed Die Ausführung wurde erfolgreich abgeschlossen! Sie können jetzt alle Nachrichten anzeigen, die der Assistent zum Thread hinzugefügt hat, und alle Schritte, welche die Ausführung durchgeführt hat. Sie können die Unterhaltung auch fortsetzen, indem Sie dem Thread weitere Benutzernachrichten hinzufügen und eine weitere Ausführung erstellen.
requires_action Bei Verwendung des Funktionsaufruftools wechselt die Ausführung zu einem Status „required_action“, sobald das Modell die Namen und Argumente der aufzurufenden Funktionen bestimmt hat. Anschließend müssen Sie diese Funktionen ausführen und die Ausgaben übermitteln, bevor die Ausführung fortgesetzt wird. Wenn die Ausgaben nicht vor Ablauf des Zeitstempels „expires_at“ bereitgestellt werden (ca. 10 Minuten nach der Erstellung), wird die Ausführung in einen Status „abgelaufen“ verschoben.
expired Dies geschieht, wenn die Ausgaben des Funktionsaufrufs nicht vor „expires_at“ übermittelt wurden und die Ausführung abläuft. Wenn die Ausführungen zu lange dauern und die in expires_at angegebene Zeit überschreiten, wird zusätzlich der Lauf von unseren Systemen abgebrochen.
cancelling Sie können versuchen, eine Ausführung im Status „in_progress“ mit dem Endpunkt „Ausführung abbrechen“ abzubrechen. Sobald der Versuch zum Abbruch erfolgreich ist, wird der Status der Ausführung in „abgebrochen“ verschoben. Der Abbruch wird versucht, ist aber nicht garantiert.
cancelled Die Ausführung wurde erfolgreich abgebrochen.
failed Sie können den Grund für den Fehler anzeigen, indem Sie das last_error-Objekt in der Ausführung betrachten. Der Zeitstempel für den Fehler wird unter „failed_at“ aufgezeichnet.

Nachrichtenanmerkungen

Anmerkungen zu Assistentennachrichten unterscheiden sich von den Inhaltsfilteranmerkungen, die in Abschluss- und Chatabschluss-API-Antworten vorhanden sind. Assistentenanmerkungen können innerhalb des Inhaltsarrays des Objekts auftreten. Anmerkungen enthalten Informationen dazu, wie Sie den Text in den Antworten an Benutzer*innen kommentieren sollten.

Wenn Anmerkungen im Nachrichteninhaltsarray vorhanden sind, werden unlesbare, vom Modell generierte Teilzeichenfolgen im Text angezeigt, die Sie durch die richtigen Anmerkungen ersetzen müssen. Diese Zeichenfolgen können etwa wie 【13†source】 oder sandbox:/mnt/data/file.csv aussehen. Hier ist ein Python-Codeschnipsel aus OpenAI, der diese Zeichenfolgen durch die Informationen ersetzt, die in den Anmerkungen vorhanden sind.


from openai import AzureOpenAI
    
client = AzureOpenAI(
    api_key=os.getenv("AZURE_OPENAI_API_KEY"),  
    api_version="2024-05-01-preview",
    azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
    )

# Retrieve the message object
message = client.beta.threads.messages.retrieve(
  thread_id="...",
  message_id="..."
)

# Extract the message content
message_content = message.content[0].text
annotations = message_content.annotations
citations = []

# Iterate over the annotations and add footnotes
for index, annotation in enumerate(annotations):
    # Replace the text with a footnote
    message_content.value = message_content.value.replace(annotation.text, f' [{index}]')

    # Gather citations based on annotation attributes
    if (file_citation := getattr(annotation, 'file_citation', None)):
        cited_file = client.files.retrieve(file_citation.file_id)
        citations.append(f'[{index}] {file_citation.quote} from {cited_file.filename}')
    elif (file_path := getattr(annotation, 'file_path', None)):
        cited_file = client.files.retrieve(file_path.file_id)
        citations.append(f'[{index}] Click <here> to download {cited_file.filename}')
        # Note: File download functionality not implemented above for brevity

# Add footnotes to the end of the message before displaying to user
message_content.value += '\n' + '\n'.join(citations)

Nachrichtenanmerkung Beschreibung
file_citation Dateizitate werden vom Abruftool erstellt und definieren Verweise auf ein bestimmtes Zitat in einer bestimmten Datei, die vom Assistenten zum Generieren der Antwort hochgeladen und verwendet wurde.
file_path Dateipfadanmerkungen werden vom Tool „code_interpreter“ erstellt und enthalten Verweise auf die vom Tool generierten Dateien.

Siehe auch