Remarque
L’accès à cette page requiert une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page requiert une autorisation. Vous pouvez essayer de modifier des répertoires.
S’applique uniquement à :le portail classique Foundry. Cet article n’est pas disponible pour le nouveau portail Foundry.
En savoir plus sur le nouveau portail.
Note
Les liens de cet article peuvent ouvrir du contenu dans la nouvelle documentation Microsoft Foundry au lieu de la documentation Foundry (classique) que vous affichez maintenant.
Note
L’API des assistants est obsolète et sera retirée le 26 août 2026. Utilisez le service Microsoft Foundry Agents, généralement disponible. Suivez le guide de migration pour mettre à jour vos charges de travail. En savoir plus.
Azure OpenAI Assistants (préversion) vous permet de créer des assistants IA adaptés à vos besoins grâce à des instructions personnalisées, renforcées par des outils avancés tels que l'interpréteur de code et les fonctions personnalisées. Dans cet article, nous fournissons une procédure pas à pas détaillée de prise en main de l’API Assistants.
Assistance des Assistants
Prise en charge de la région, du modèle et de l’API
La page modèles contient les informations les plus up-to-date sur les régions/modèles où les Assistants sont actuellement pris en charge. Les assistants peuvent être utilisés dans la version 2024-02-15-preview ainsi que dans les versions ultérieures de l’API de préversion d’inférence Azure OpenAI. Vous trouverez la liste complète des versions précédentes de l’API sur GitHub.
Types de fichiers pris en charge
| Format de fichier | MIME Type | Interpréteur de code |
|---|---|---|
| .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 | ✅ |
| 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 | texte/brut | ✅ |
| .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 ou « text/xml » | ✅ |
| .zip | application/zip | ✅ |
Outils
Conseil
Nous avons ajouté la prise en charge du tool_choice paramètre qui peut être utilisé pour forcer l'utilisation d'un outil spécifique (comme file_search, code_interpreter, ou un function) dans une exécution particulière.
Un assistant individuel peut accéder à jusqu’à 128 outils, notamment l’interpréteur de code et la recherche de fichiers, mais vous pouvez également définir vos propres outils personnalisés via des fonctions.
Fichiers
Les fichiers peuvent être chargés via Studio ou par programmation. Le file_ids paramètre est requis pour donner aux outils comme code_interpreter l’accès aux fichiers. Lorsque vous utilisez le point de terminaison de téléchargement de fichiers, vous devez avoir le purpose réglage pour assistants être utilisé avec l’API Assistants.
Composants d'assistants
| Composant | Description |
|---|---|
| Assistant | IA personnalisée qui utilise Azure modèles OpenAI conjointement avec les outils. |
| Fil | Session de conversation entre un Assistant et un utilisateur. Les threads stockent les messages et gèrent automatiquement la troncation pour ajuster le contenu dans le contexte d’un modèle. |
| Message | Message créé par un Assistant ou un utilisateur. Les messages peuvent inclure du texte, des images et d’autres fichiers. Les messages sont stockés sous forme de liste sur le thread. |
| Courir | Activation d’un Assistant pour commencer à s’exécuter en fonction du contenu du thread. L’Assistant utilise sa configuration et les messages du thread pour effectuer des tâches en appelant des modèles et des outils. Dans le cadre d’une exécution, l’Assistant ajoute des messages au thread. |
| Étape d’exécution | Liste détaillée des étapes que l’Assistant a effectuées dans le cadre d’un processus. Un Assistant peut appeler des outils ou créer des messages pendant son exécution. L’examen des étapes d’exécution vous permet de comprendre comment l’Assistant obtient ses résultats finaux. |
Configuration de votre premier Assistant
Créer un assistant
Pour cet exemple, nous allons créer un assistant qui écrit du code pour générer des visualisations à l’aide des fonctionnalités de l’outil code_interpreter . Les exemples ci-dessous sont destinés à être exécutés de manière séquentielle dans un environnement tel que Jupyter Notebooks.
import os
import json
from openai import AzureOpenAI
client = AzureOpenAI(
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
api_version="2024-08-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.
)
Vous devez noter quelques détails à partir de la configuration ci-dessus :
- Nous allons autoriser cet assistant à accéder à l’interpréteur de code avec la ligne
tools=[{"type": "code_interpreter"}],. Cela permet au modèle d’accéder à un environnement Python isolé pour lancer et exécuter du code afin d’aider à formuler des réponses à la question d’un utilisateur. - Dans les instructions, nous rappelons au modèle qu’il peut exécuter du code. Parfois, le modèle a besoin d’aide pour le guider vers l’outil approprié pour résoudre une requête donnée. Si vous savez que vous souhaitez utiliser une bibliothèque particulière pour générer une certaine réponse que vous savez fait partie de l’interpréteur de code, il peut vous aider à fournir des conseils en disant quelque chose comme « Utiliser Matplotlib pour effectuer x ».
- Comme il s’agit d’Azure OpenAI, la valeur que vous entrez pour
model=doit correspondre au nom du déploiement.
Ensuite, nous allons imprimer le contenu de l’Assistant que nous venons de créer pour confirmer que la création a réussi :
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"
}
]
}
Créer un thread
Nous allons maintenant créer un thread.
# Create a thread
thread = client.beta.threads.create()
print(thread)
Thread(id='thread_6bunpoBRZwNhovwzYo7fhNVd', created_at=1705972465, metadata={}, object='thread')
Un thread est essentiellement l’enregistrement de la session de conversation entre l’Assistant et l’utilisateur. C'est similaire au tableau ou liste de messages dans un appel API typique de complétions de chat. L’une des principales différences est que, contrairement à un tableau de messages d’achèvement de conversation, vous n’avez pas besoin de suivre les jetons avec chaque appel pour vous assurer que vous restez en dessous de la longueur du contexte du modèle. Les threads suppriment ces détails de gestion et compressent l’historique des threads si nécessaire afin de permettre à la conversation de continuer. La possibilité pour les threads d’effectuer cette opération avec des conversations plus volumineuses est améliorée lors de l’utilisation des modèles les plus récents, qui ont des longueurs de contexte et une prise en charge plus importantes pour les fonctionnalités les plus récentes.
Créez ensuite la première question utilisateur à ajouter au thread.
# 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"
)
Répertorier les messages de thread
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
}
Exécuter le thread
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
)
Nous pourrions également passer un instructions paramètre ici, mais cela remplacerait les instructions existantes que nous avons déjà fournies pour l’assistant.
Récupérer l’état du thread
# 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
En fonction de la complexité de la requête que vous exécutez, le thread peut prendre plus de temps pour s’exécuter. Dans ce cas, vous pouvez créer une boucle pour surveiller l’état d’exécution du thread avec du code comme l’exemple ci-dessous :
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))
Lorsqu’une exécution est in_progress ou dans d’autres états non déterminaux, le thread est verrouillé. Lorsqu’un thread est verrouillé, les nouveaux messages ne peuvent pas être ajoutés et les nouvelles exécutions ne peuvent pas être créées.
Répertorier les messages de thread après l’exécution
Une fois que l’état de l’exécution indique la réussite de l’exécution, vous pouvez réexécuter le contenu du thread pour récupérer la réponse du modèle et des outils :
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
}
Récupérer l’ID de fichier
Nous avions demandé que le modèle génère une image d’une vague sinusoïque. Pour télécharger l’image, nous devons d’abord récupérer l’ID du fichier d’images.
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
Télécharger l’image
content = client.files.content(image_file_id)
image= content.write_to_file("sinewave.png")
Ouvrez l’image localement une fois qu’elle est téléchargée :
from PIL import Image
# Display the image in the default image viewer
image = Image.open("sinewave.png")
image.show()
Poser une question de suivi sur le thread
Étant donné que l’assistant n’a pas tout à fait suivi nos instructions et n’a pas inclus le code exécuté dans la partie texte de sa réponse, demandons explicitement cette information.
# 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"
)
Là encore, nous devons exécuter et récupérer l’état du thread :
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
Lorsque le statut d'exécution indique 'terminé', nous allons à nouveau afficher les messages dans le fil, qui devraient maintenant inclure la réponse à notre dernière question.
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
}
Pour extraire uniquement la réponse à notre dernière question :
data = json.loads(messages.model_dump_json(indent=2))
code = data['data'][0]['content'][0]['text']['value']
print(code)
Certes, voici le code que j’ai utilisé pour générer la visualisation d’onde sinusoïque :
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()
Mode sombre
Ajoutons une dernière question au thread pour voir si l’interpréteur de code peut permuter le graphique en mode sombre pour nous.
# 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
}
Extrayez le nouvel ID de fichier image et téléchargez et affichez l’image :
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()
Informations de référence supplémentaires
Définitions de statut de la course
| Statut | Définition |
|---|---|
queued |
Lorsque les exécutions sont créées pour la première fois ou lorsque vous terminez le required_action, elles sont déplacées vers un état mis en file d’attente. Ils devraient presque immédiatement passer à in_progress. |
in_progress |
Pendant in_progress, l’Assistant utilise le modèle et les outils pour effectuer les étapes. Vous pouvez afficher la progression effectuée par l’exécution en examinant les étapes d’exécution. |
completed |
La course s’est terminée avec succès ! Vous pouvez maintenant afficher tous les messages que l'Assistant a ajoutés au fil de discussion, ainsi que toutes les étapes effectuées lors de l'exécution. Vous pouvez également poursuivre la conversation en ajoutant d’autres messages utilisateur au thread et en créant une autre exécution. |
requires_action |
Lorsque vous utilisez l’outil d’appel de fonction, l’exécution passe à un état required_action une fois que le modèle détermine les noms et les arguments des fonctions à appeler. Vous devez ensuite exécuter ces fonctions et envoyer les sorties avant l’exécution. Si les sorties ne sont pas fournies avant que le timestamp expires_at ne soit dépassé (environ 10 minutes après la création), l’exécution passera à un état expiré. |
expired |
Cela se produit lorsque les sorties appelant la fonction n’ont pas été envoyées avant expires_at et que l’exécution expire. En outre, si les exécutions prennent trop de temps pour s’exécuter et dépassent le temps indiqué dans expires_at, nos systèmes expirent l’exécution. |
cancelling |
Vous pouvez tenter d'annuler une exécution en cours à l'aide du point de terminaison Annuler l'exécution. Une fois la tentative d’annulation réussie, le statut d'exécution passe à annulé. L’annulation est tentée, mais n’est pas garantie. |
cancelled |
L’exécution a été annulée avec succès. |
failed |
Vous pouvez voir la raison de l’échec en regardant l’objet last_error dans la Run. L’horodatage de l’échec est enregistré sous failed_at. |
Annotations de message
Les annotations de message assistant sont différentes des annotations de filtrage de contenu qui sont présentes dans les réponses de l’API de saisie semi-automatique et de saisie de chat. Les annotations assistantes peuvent se produire dans le tableau de contenu de l’objet. Les annotations fournissent des informations sur la façon dont vous devez annoter le texte dans les réponses à l’utilisateur.
Lorsqu'il y a des annotations dans le tableau de contenu du message, vous verrez des sous-chaînes générées par un modèle illisibles dans le texte que vous devez remplacer par les annotations correctes. Ces chaînes peuvent ressembler à quelque chose comme 【13†source】 ou sandbox:/mnt/data/file.csv. Voici un extrait de code Python d’OpenAI qui remplace ces chaînes par les informations présentes dans les annotations.
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)
| Annotation de message | Description |
|---|---|
file_citation |
Les citations de fichiers sont créées par l’outil de récupération et définissent des références à une citation spécifique dans un fichier spécifique chargé et utilisé par l’Assistant pour générer la réponse. |
file_path |
Les annotations de chemin de fichier sont créées par l’outil code_interpreter et contiennent des références aux fichiers générés par l’outil. |
Voir aussi
- En savoir plus sur les assistants et l’interpréteur de code
- En savoir plus sur les assistants et les appels de fonction
- Exemples d'API Azure Assistants OpenAI