Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Aplica-se apenas a:Portal Foundry (clássico). Este artigo não está disponível para o novo portal da Foundry.
Saiba mais sobre o novo portal.
Nota
Os links neste artigo podem abrir conteúdo na nova documentação do Microsoft Foundry em vez da documentação do Foundry (clássico) que está a ver agora.
Nota
A API dos Assistentes está obsoleta e será retirada a 26 de agosto de 2026. Use o serviço geralmente disponível Microsoft Foundry Agents. Siga o guia de migração para atualizar as suas cargas de trabalho. Saiba mais.
O Azure OpenAI Assistants (Preview) permite-lhe criar assistentes de IA adaptados às suas necessidades através de instruções personalizadas e complementados por ferramentas avançadas como interpretadores de código e funções personalizadas. Neste artigo, fornecemos uma explicação detalhada sobre como começar com a API dos Assistentes.
Apoio aos assistentes
Suporte para região, modelo e API
A página de modelos contém a informação mais atualizada sobre regiões/modelos onde os Assistentes são suportados atualmente. Os assistentes podem ser usados na versão 2024-02-15-preview e posteriores da API de pré-visualização do Azure OpenAI de inferência. Uma lista completa das versões anteriores da API pode ser encontrada em GitHub.
Tipos de ficheiros suportados
| Formato de ficheiro | Tipo MIME | Interpretador de Código |
|---|---|---|
| .c | Texto/X-C | ✅ |
| .cpp | Texto/X-C++ | ✅ |
| .csv | Application/CSV | ✅ |
| .docx | application/vnd.openxmlformats-officedocument.wordprocessingml.document | ✅ |
| .html | text/html | ✅ |
| .java | Text/X-Java | ✅ |
| .json | application/json | ✅ |
| .md | Texto/Markdown | ✅ |
| Aplicação/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 simples | ✅ |
| .css | text/css | ✅ |
| .jpeg | image/jpeg | ✅ |
| .jpg | image/jpeg | ✅ |
| .js | Texto/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 "Texto/XML" | ✅ |
| .zip | application/zip | ✅ |
Ferramentas
Dica
Adicionámos 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_interpreter, ou um function) numa determinada execução.
Um assistente individual pode aceder a até 128 ferramentas, incluindo interpretador de código e pesquisa de ficheiros, mas também pode definir as suas próprias ferramentas personalizadas através de funções.
Ficheiros
Os ficheiros podem ser carregados via Studio ou programaticamente. O file_ids parâmetro é necessário para dar ferramentas como code_interpreter acesso a ficheiros. Ao usar o endpoint de upload de ficheiros, deve ter purpose definido para assistants para ser usado com a API dos Assistentes.
Componentes de assistentes
| Componente | Descrição |
|---|---|
| Assistente | IA personalizada que utiliza modelos Azure OpenAI em conjunto com ferramentas. |
| Tópico | Uma sessão de conversa entre um Assistente e um utilizador. Os Threads armazenam Mensagens e tratam automaticamente o truncamento para encaixar o conteúdo no contexto de um modelo. |
| Mensagem | Uma mensagem criada por um Assistente ou um utilizador. As mensagens podem incluir texto, imagens e outros ficheiros. As mensagens são armazenadas como uma lista na Thread. |
| Corre | Ativação de um Assistente para iniciar a execução com base no conteúdo do Tópico. O Assistente utiliza a sua configuração e as Mensagens do Thread para realizar tarefas, chamando modelos e ferramentas. Como parte de uma execução, o Assistente acrescenta mensagens ao thread. |
| Executar Passo | Uma lista detalhada dos passos que o Assistente deu como parte de uma Corrida. Um Assistente pode chamar ferramentas ou criar Mensagens durante a execução. Examinar os passos de execução permite compreender como o Assistente está a alcançar os seus resultados finais. |
Configurar o seu primeiro Assistente
Crie um assistente
Neste exemplo, vamos criar um assistente que escreve código para gerar visualizações usando as capacidades da code_interpreter ferramenta. Os exemplos abaixo destinam-se a ser executados sequencialmente num ambiente como o 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 deve ter em conta na configuração acima:
- Permitimos que este assistente aceda ao interpretador de código com a linha
tools=[{"type": "code_interpreter"}],. Isto dá ao modelo acesso a um ambiente python sand-box para executar e executar código que ajude a formular respostas à pergunta do utilizador. - Nas instruções lembramos o modelo que ele pode executar código. Por vezes, o modelo precisa de ajuda para o orientar para a ferramenta certa para resolver uma determinada consulta. Se sabes que queres usar uma determinada biblioteca para gerar uma resposta que sabes que faz parte do code interpreter, pode ajudar dar orientações dizendo algo como "Usa o Matplotlib para fazer x."
- Como isto é Azure OpenAI, o valor que introduzir para
model=deve corresponder ao nome de implementação.
De seguida, vamos imprimir o conteúdo do assistente que acabámos 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"
}
]
}
Crie um tópico
Agora vamos criar um tópico.
# Create a thread
thread = client.beta.threads.create()
print(thread)
Thread(id='thread_6bunpoBRZwNhovwzYo7fhNVd', created_at=1705972465, metadata={}, object='thread')
Um thread é essencialmente o registo da sessão de conversa entre o assistente e o utilizador. É semelhante ao array/lista de mensagens numa chamada típica de API de completamento de chat. Uma das principais diferenças é que, ao contrário de um array de mensagens de conclusão de chat, não é necessário acompanhar os tokens a cada chamada para garantir que se mantém abaixo do comprimento de contexto do modelo. Os threads abstraem este detalhe de gestão e comprimem o histórico do thread conforme necessário para permitir que a conversa continue. A capacidade dos threads para realizarem isto em conversas maiores é aumentada ao usar os modelos mais recentes, que têm comprimentos de contexto maiores e suporte para as funcionalidades mais recentes.
De seguida, crie a primeira pergunta do utilizador para adicionar ao tópico.
# 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 da 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
}
Execução da 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 isto sobrepor-se-ia às instruções existentes que já fornecemos para o assistente.
Recuperar o estado 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 que executa, o thread pode demorar mais tempo a ser executado. Nesse caso, pode criar um ciclo para monitorizar o estado de execução do thread com código como no 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 é bloqueada. Quando um thread é bloqueado, não podem ser adicionadas novas mensagens e não podem ser criadas novas execuções.
Mensagens do tópico da lista após a execução
Assim que o estado da execução indicar conclusão bem-sucedida, pode listar novamente o conteúdo do tópico 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 ficheiro
Solicitámos que o modelo gerasse uma imagem de uma onda senoidal. Para descarregar a imagem, primeiro precisamos de recuperar o ID do ficheiro da 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']
print(image_file_id) # Outputs: assistant-1YGVTvNzc2JXajI5JU9F0HMD
Descarregar imagem
content = client.files.content(image_file_id)
image= content.write_to_file("sinewave.png")
Abra a imagem localmente assim que estiver descarregada:
from PIL import Image
# Display the image in the default image viewer
image = Image.open("sinewave.png")
image.show()
Faça uma pergunta de seguimento no tópico
Como o assistente não seguiu bem as nossas instruções e não incluiu o código executado na parte de texto da resposta, vamos pedir explicitamente essa informação.
# 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, teremos de executar e recuperar o estado da 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
Quando o estado da execução estiver concluído, vamos listar novamente as mensagens no tópico, que agora deverão incluir a resposta à nossa última pergunta.
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 última pergunta:
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 da onda senoidal:
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 acrescentar uma última pergunta ao tópico para ver se o code interpreter consegue mudar o gráfico para o 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
}
Extrai o novo ID do ficheiro de imagem e descarrega e mostra 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
Definições do estado de execução
| Estado | Definição |
|---|---|
queued |
Quando as Corridas são criadas pela primeira vez ou quando completas a ação requerida, são movidas para um estado em fila. Devem mudar-se quase imediatamente para in_progress. |
in_progress |
Enquanto em progresso, o Assistente usa o modelo e as ferramentas para executar as etapas. Pode ver o progresso feito pela Corrida ao examinar os Passos da Corrida. |
completed |
A Corrida concluída com sucesso! Agora pode ver todas as mensagens que o Assistente adicionou à Thread e todos os passos que a Run deu. Também pode continuar a conversa adicionando mais Mensagens de utilizador à Thread e criando outra Run. |
requires_action |
Ao usar a ferramenta de chamada de funções, a Run passa para um estado de required_action assim que o modelo determina os nomes e argumentos das funções a chamar. Deve então executar essas funções e submeter as saídas antes de a execução prosseguir. Se as saídas não forem fornecidas antes de a marca de tempo expires_at passar (cerca de 10 minutos após a criação), o estado da execução será alterado para expirado. |
expired |
Isto acontece quando as saídas da função chamadas não foram submetidas antes de "expires_at" e a execução expira. Além disso, se as execuções demorarem demasiado tempo e ultrapassarem o tempo indicado em expires_at, os nossos sistemas expiram a execução. |
cancelling |
Você pode tentar cancelar uma execução em andamento usando o endpoint Cancel Run. Quando a tentativa de cancelar é bem-sucedida, o estado da Run passa para cancelado. O cancelamento é tentado, mas não é garantido. |
cancelled |
A corrida foi cancelada com sucesso. |
failed |
Pode ver a razão da falha verificando o objeto last_error na execução. O carimbo temporal da falha será registado no campo failed_at. |
Anotações de mensagens
As anotações de mensagens assistentes são diferentes das anotações de filtragem de conteúdo presentes nas respostas da API de completamento e conclusão de chat. As anotações assistentes podem ocorrer dentro do array de conteúdo do objeto. As anotações fornecem informações sobre como deve anotar o texto nas respostas ao utilizador.
Quando há anotações no array de conteúdo da Message, verá substrings ilegíveis geradas por modelos no texto que precisa substituir pelas anotações corretas. Estas cadeias de caracteres podem parecer-se com algo como 【13†source】 ou sandbox:/mnt/data/file.csv. Aqui está um excerto de código em Python da OpenAI que substitui estas cadeias pela informação presente 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 mensagens | Descrição |
|---|---|
file_citation |
As citações do ficheiro são criadas pela ferramenta de recuperação e definem referências a uma citação específica num ficheiro específico que foi carregado e usado pelo Assistente para gerar a resposta. |
file_path |
As anotações do caminho do ficheiro são criadas pela ferramenta code_interpreter e contêm referências aos ficheiros gerados pela ferramenta. |
Ver também
- Saiba mais sobre Assistentes e Intérpretes de Código
- Saiba mais sobre Assistentes e chamadas de funções
- Azure Exemplos da API OpenAI Assistants