Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Aplica-se somente a:Portal do Foundry (clássico). Este artigo não está disponível para o novo portal do Foundry.
Saiba mais sobre o novo portal.
Nota
Links neste artigo podem abrir conteúdo na nova documentação do Microsoft Foundry em vez da documentação da Foundry (clássica) que você está exibindo agora.
Nota
A API dos Assistentes está obsoleta e será aposentada em 26 de agosto de 2026. Use o serviço geralmente disponível Microsoft Foundry Agents. Siga o guia de migração para atualizar suas cargas de trabalho. Saiba mais.
Azure Assistentes openai (versão prévia) permite que você crie assistentes de IA adaptados às suas necessidades por meio de instruções personalizadas e aumentadas por ferramentas avançadas, como interpretador de código e funções personalizadas. Neste artigo, fornecemos um passo a passo detalhado de introdução à API de Assistentes.
Suporte a assistentes
Suporte a região, modelo e API
A página de modelos contém as informações mais up-to-date em regiões/modelos em que os Assistentes têm suporte no momento. Os assistentes podem ser usados na versão 2024-02-15-preview e posterior da API de inferência do Azure OpenAI Preview. Uma lista completa das versões de API anteriores pode ser encontrada em GitHub.
Tipos de arquivo com suporte
| Formato de arquivo | Tipo MIME | Interpretador de Código |
|---|---|---|
| .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 | texto/sem formatação | ✅ |
| .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 | ✅ |
Ferramentas
Dica
Adicionamos suporte para o tool_choice parâmetro que pode ser usado para forçar o uso de uma ferramenta específica (como file_search, code_interpreterou um function) em uma execução específica.
Um assistente individual pode acessar até 128 ferramentas, incluindo interpretador de código e pesquisa de arquivos, mas você também pode definir suas próprias ferramentas personalizadas por meio de funções.
Arquivos
Os arquivos podem ser carregados por meio do Studio ou programaticamente. O file_ids parâmetro é necessário para fornecer ferramentas como code_interpreter acesso a arquivos. Ao usar o endpoint de upload de arquivo, é necessário que o purpose esteja definido para assistants ser utilizado com a API de Assistentes.
Componentes de assistentes
| Componente | Descrição |
|---|---|
| Assistente | IA personalizada que usa modelos Azure OpenAI junto com ferramentas. |
| Tópico | Uma sessão de conversa entre um assistente e um usuário. Os threads armazenam mensagens e manipulam automaticamente o truncamento para ajustar o conteúdo ao contexto de um modelo. |
| Mensagem | Uma mensagem criada por um assistente ou um usuário. As mensagens podem incluir texto, imagens e outros arquivos. As mensagens são armazenadas como uma lista no Thread. |
| Executar | Ativação de um Assistente para começar a ser executado com base no conteúdo do Thread. O Assistente usa sua configuração e as Mensagens do Thread para executar tarefas chamando modelos e ferramentas. Como parte de uma execução, o Assistente acrescenta mensagens ao Thread. |
| Executar Etapa | Uma lista detalhada das etapas que o Assistente tomou como parte de um processo. Um Assistente pode chamar ferramentas ou criar Mensagens durante sua execução. Examinar as etapas de execução permite que você entenda como o Assistente está chegando aos resultados finais. |
Configurando seu primeiro Assistente
Criar um assistente
Para este exemplo, criaremos um assistente que grava código para gerar visualizações usando os recursos da code_interpreter ferramenta. Os exemplos a seguir devem ser executados sequencialmente em um ambiente como 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.
)
Há alguns detalhes que você deve observar na configuração acima:
- Habilitamos esse assistente para acessar o interpretador de código com a linha
tools=[{"type": "code_interpreter"}],. Isso fornece ao modelo acesso a um ambiente Python isolado para executar código e ajudar a formular respostas para perguntas de usuários. - Nas instruções, lembramos o modelo de que ele pode executar o código. Às vezes, o modelo precisa de ajuda para guiá-lo para a ferramenta certa para resolver uma determinada consulta. Se você souber que deseja usar uma biblioteca específica para gerar uma determinada resposta que você sabe que faz parte do interpretador de código, pode ajudar a fornecer orientação dizendo algo como "Usar Matplotlib para fazer x".
- Como isso é Azure OpenAI, o valor inserido para
model=deve corresponder ao nome da implantação.
Em seguida, vamos imprimir o conteúdo do assistente que acabamos de criar para confirmar que a criação foi bem-sucedida:
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"
}
]
}
Criar um thread
Agora vamos criar um thread.
# Create a thread
thread = client.beta.threads.create()
print(thread)
Thread(id='thread_6bunpoBRZwNhovwzYo7fhNVd', created_at=1705972465, metadata={}, object='thread')
Um thread é essencialmente o registro da sessão de conversa entre o assistente e o usuário. É semelhante à matriz/lista de mensagens em uma chamada de API de conclusão de chat típica. Uma das principais diferenças é que, diferentemente de um array de mensagens de conclusão de chat, você não precisa acompanhar os tokens em cada chamada para garantir que permaneça abaixo do comprimento de contexto do modelo. Threads ocultam os detalhes de gerenciamento e comprimem o histórico dos threads sempre que necessário para que a conversa possa continuar. A capacidade dos threads de realizar isso em conversas maiores é aprimorada quando usados os modelos mais recentes, com tamanhos de contexto maiores e suporte para os recursos mais recentes.
Em seguida, crie a primeira pergunta do usuário a ser adicionada ao 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"
)
Listar mensagens 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
}
Executar 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
)
Também poderíamos passar um instructions parâmetro aqui, mas isso substituiria as instruções existentes que já fornecemos para o assistente.
Recuperar o status do 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
Dependendo da complexidade da consulta executada, o thread pode levar mais tempo para ser executado. Nesse caso, você pode criar um loop para monitorar o status de execução do thread com código como o exemplo abaixo:
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))
Quando uma execução está em in_progress ou em outros estados não terminais, a thread está bloqueada. Quando um thread está bloqueado, novas mensagens não podem ser adicionadas e novas execuções não podem ser criadas.
Listar mensagens de thread após a execução
Depois que o status de execução indicar a conclusão bem-sucedida, você poderá listar o conteúdo do thread novamente para recuperar a resposta do modelo e de qualquer ferramenta:
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
}
Recuperar ID do arquivo
Solicitamos que o modelo gerasse uma imagem de uma onda de seno. Para baixar a imagem, primeiro precisamos recuperar a ID do arquivo de imagens.
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
Baixar imagem
content = client.files.content(image_file_id)
image= content.write_to_file("sinewave.png")
Abra a imagem localmente depois que ela for baixada:
from PIL import Image
# Display the image in the default image viewer
image = Image.open("sinewave.png")
image.show()
Fazer uma pergunta de acompanhamento no thread
Como o assistente não seguiu nossas instruções e incluiu o código que foi executado na parte de texto de sua resposta, vamos pedir explicitamente essas informações.
# 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"
)
Novamente, precisaremos executar e recuperar o status do 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
Assim que o status da execução for alterado para 'concluído', listaremos as mensagens no thread novamente, que agora deverão incluir a resposta à nossa pergunta mais recente.
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
}
Para extrair apenas a resposta à nossa pergunta mais recente:
data = json.loads(messages.model_dump_json(indent=2))
code = data['data'][0]['content'][0]['text']['value']
print(code)
Certamente, aqui está o código que usei para gerar a visualização de onda de seno:
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()
Modo escuro
Vamos adicionar uma última pergunta ao thread para ver se o interpretador de código pode trocar o gráfico pelo modo escuro para nós.
# 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
}
Extraia a nova ID do arquivo de imagem e baixe e exiba a imagem:
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()
Referência adicional
Executar definições de status
| Status | Definição |
|---|---|
queued |
Quando as execuções são criadas pela primeira vez ou quando você conclui o required_action, elas são movidas para um status na fila. Eles devem se mudar quase imediatamente para in_progress. |
in_progress |
Enquanto em andamento, o Assistente usa o modelo e as ferramentas para executar etapas. Você pode visualizar o progresso do Processo examinando as Etapas do Processo. |
completed |
A execução foi concluída com sucesso! Agora você pode exibir todas as Mensagens que o Assistente adicionou ao Thread e todas as etapas que a Execução tomou. Você também pode continuar a conversa adicionando mais mensagens de usuário ao Thread e criando outra Execução. |
requires_action |
Ao usar a ferramenta de chamada de funções, a execução será movida para o estado required_action depois que o modelo determinar os nomes e argumentos das funções a serem chamadas. Em seguida, você deve executar essas funções e enviar as saídas antes que a execução prossiga. Se as saídas não forem fornecidas antes que a marca temporal expires_at passe (cerca de 10 minutos após a criação), a execução será definida como expirada. |
expired |
Isso acontece quando as saídas de chamada de função não foram enviadas antes de expires_at e a execução expira. Além disso, se as execuções levarem muito tempo para serem executadas e forem além do tempo indicado em expires_at, nossos sistemas expirarão a execução. |
cancelling |
Você pode tentar cancelar uma execução "in_progress" usando o endpoint Cancelar Execução. Depois que a tentativa de cancelar for bem-sucedida, o status da Execução mudará para cancelado. O cancelamento é tentado, mas não é garantido. |
cancelled |
A execução foi cancelada com sucesso. |
failed |
Você pode ver a razão da falha olhando o objeto last_error em Execução. O carimbo de data/hora da falha será registrado em failed_at. |
Anotações de mensagens
As anotações de mensagem do assistente são diferentes das anotações de filtragem de conteúdo que estão presentes nas respostas da API de conclusão e de conclusão do chat. As anotações do assistente podem ocorrer dentro da matriz de conteúdo do objeto. As anotações fornecem informações sobre como você deve anotar o texto nas respostas ao usuário.
Quando as anotações estiverem presentes na matriz de conteúdo de mensagem, você verá subcadeias de caracteres geradas por modelo ilegíveis no texto que você precisa substituir pelas anotações corretas. Essas cadeias de caracteres podem ser semelhantes 【13†source】 ou sandbox:/mnt/data/file.csv. Aqui está um snippet de código Python do OpenAI que substitui essas cadeias de caracteres pelas informações presentes nas anotações.
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)
| Anotação de mensagem | Descrição |
|---|---|
file_citation |
As citações de arquivo são criadas pela ferramenta de recuperação e definem referências a uma citação específica em um arquivo específico que foi carregado e usado pelo Assistente para gerar a resposta. |
file_path |
As anotações de caminho de arquivo são criadas pela ferramenta code_interpreter e contêm referências aos arquivos gerados pela ferramenta. |
Consulte também
- Saiba mais sobre assistentes e interpretador de código
- Saiba mais sobre assistentes e chamadas de função
- Exemplos de API do Azure OpenAI Assistants