quick_start/v1/11_Assistant.ipynb (669 lines of code) (raw):
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Assistant (Preview)\n",
"\n",
"\n",
"Azure OpenAI Assistants (Preview) allows you to create AI assistants tailored to your needs through custom instructions and augmented by advanced tools like code interpreter, and custom functions. In this article we'll provide an in-depth walkthrough of getting started with the Assistants API.\n",
"\n",
"\n",
"## API Version: 2024-02-15-preview\n",
"Check availability: \n",
"\n",
"https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models#assistants-preview"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Creating an assisstant"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import json\n",
"from openai import AzureOpenAI\n",
"from dotenv import load_dotenv\n",
"\n",
"# Load the environment variables from the .env file\n",
"load_dotenv()\n",
" \n",
"client = AzureOpenAI(\n",
" api_key=os.getenv(\"AZURE_OPENAI_API_KEY_GPT4V\"), \n",
" api_version=\"2024-02-15-preview\",\n",
" azure_endpoint = os.getenv(\"AZURE_OPENAI_DEPLOYMENT_NAME_GPT4V\")\n",
" )\n",
"\n",
"# Create an assistant\n",
"assistant = client.beta.assistants.create(\n",
" name=\"Data Visualization\",\n",
" instructions=f\"You are a helpful AI assistant who makes interesting visualizations based on data.\" \n",
" f\"You have access to a sandboxed environment for writing and testing code.\"\n",
" f\"When you are asked to create a visualization you should follow these steps:\"\n",
" f\"1. Write the code.\"\n",
" f\"2. Anytime you write new code display a preview of the code to show your work.\"\n",
" f\"3. Run the code to confirm that it runs.\"\n",
" f\"4. If the code is successful display the visualization.\"\n",
" 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.\",\n",
" tools=[{\"type\": \"code_interpreter\"}],\n",
" model=\"gpt-4-1106-preview\" #You must replace this value with the deployment name for your model.\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"id\": \"asst_cePxLU8BToWgvKHAj3FZvGkU\",\n",
" \"created_at\": 1709151664,\n",
" \"description\": null,\n",
" \"file_ids\": [],\n",
" \"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.\",\n",
" \"metadata\": {},\n",
" \"model\": \"gpt-4-1106-preview\",\n",
" \"name\": \"Data Visualization\",\n",
" \"object\": \"assistant\",\n",
" \"tools\": [\n",
" {\n",
" \"type\": \"code_interpreter\"\n",
" }\n",
" ]\n",
"}\n"
]
}
],
"source": [
"print(assistant.model_dump_json(indent=2))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Creating a thread\n",
"\n",
"Thread is a conversation session between an Assistant and a user. Threads store Messages and automatically handle truncation to fit content into a model’s context."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Thread(id='thread_AWxF97wT3MiwlZw1UYKTmZoA', created_at=1709151665, metadata={}, object='thread')\n"
]
}
],
"source": [
"# Create a thread\n",
"thread = client.beta.threads.create()\n",
"print(thread)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# Add a user question to the thread\n",
"message = client.beta.threads.messages.create(\n",
" thread_id=thread.id,\n",
" role=\"user\",\n",
" content=\"Create a visualization of a sinewave\"\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"data\": [\n",
" {\n",
" \"id\": \"msg_OS6eZF2qwb5i7HzM8FglKrvU\",\n",
" \"assistant_id\": null,\n",
" \"content\": [\n",
" {\n",
" \"text\": {\n",
" \"annotations\": [],\n",
" \"value\": \"Create a visualization of a sinewave\"\n",
" },\n",
" \"type\": \"text\"\n",
" }\n",
" ],\n",
" \"created_at\": 1709151665,\n",
" \"file_ids\": [],\n",
" \"metadata\": {},\n",
" \"object\": \"thread.message\",\n",
" \"role\": \"user\",\n",
" \"run_id\": null,\n",
" \"thread_id\": \"thread_AWxF97wT3MiwlZw1UYKTmZoA\"\n",
" }\n",
" ],\n",
" \"object\": \"list\",\n",
" \"first_id\": \"msg_OS6eZF2qwb5i7HzM8FglKrvU\",\n",
" \"last_id\": \"msg_OS6eZF2qwb5i7HzM8FglKrvU\",\n",
" \"has_more\": false\n",
"}\n"
]
}
],
"source": [
"# list thread messages\n",
"thread_messages = client.beta.threads.messages.list(thread.id)\n",
"print(thread_messages.model_dump_json(indent=2))"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"# create a thread\n",
"# you can also use intructions here to override the default instructions\n",
"run = client.beta.threads.runs.create(\n",
" thread_id=thread.id,\n",
" assistant_id=assistant.id,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"queued\n"
]
}
],
"source": [
"# retrieve thread status\n",
"# Retrieve the status of the run\n",
"run = client.beta.threads.runs.retrieve(\n",
" thread_id=thread.id,\n",
" run_id=run.id\n",
")\n",
"\n",
"status = run.status\n",
"print(status)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Status: completed\n",
"Elapsed time: 0 minutes 22 seconds\n",
"{\n",
" \"data\": [\n",
" {\n",
" \"id\": \"msg_ERIdRIKeBVB5HHRyfaK4xIXd\",\n",
" \"assistant_id\": \"asst_cePxLU8BToWgvKHAj3FZvGkU\",\n",
" \"content\": [\n",
" {\n",
" \"image_file\": {\n",
" \"file_id\": \"assistant-BOfPBnFri7vKWiqGIRbdroqC\"\n",
" },\n",
" \"type\": \"image_file\"\n",
" },\n",
" {\n",
" \"text\": {\n",
" \"annotations\": [],\n",
" \"value\": \"Here is the visualization of a sine wave. The x-axis represents the values in radians, and the y-axis shows the sin(x) for those values. The plot displays a full cycle of a sine wave, from 0 to \\\\(2\\\\pi\\\\) radians.\"\n",
" },\n",
" \"type\": \"text\"\n",
" }\n",
" ],\n",
" \"created_at\": 1709151679,\n",
" \"file_ids\": [],\n",
" \"metadata\": {},\n",
" \"object\": \"thread.message\",\n",
" \"role\": \"assistant\",\n",
" \"run_id\": \"run_PcMAxg4JkeXdlePUWm7ntNW5\",\n",
" \"thread_id\": \"thread_AWxF97wT3MiwlZw1UYKTmZoA\"\n",
" },\n",
" {\n",
" \"id\": \"msg_OS6eZF2qwb5i7HzM8FglKrvU\",\n",
" \"assistant_id\": null,\n",
" \"content\": [\n",
" {\n",
" \"text\": {\n",
" \"annotations\": [],\n",
" \"value\": \"Create a visualization of a sinewave\"\n",
" },\n",
" \"type\": \"text\"\n",
" }\n",
" ],\n",
" \"created_at\": 1709151665,\n",
" \"file_ids\": [],\n",
" \"metadata\": {},\n",
" \"object\": \"thread.message\",\n",
" \"role\": \"user\",\n",
" \"run_id\": null,\n",
" \"thread_id\": \"thread_AWxF97wT3MiwlZw1UYKTmZoA\"\n",
" }\n",
" ],\n",
" \"object\": \"list\",\n",
" \"first_id\": \"msg_ERIdRIKeBVB5HHRyfaK4xIXd\",\n",
" \"last_id\": \"msg_OS6eZF2qwb5i7HzM8FglKrvU\",\n",
" \"has_more\": false\n",
"}\n"
]
}
],
"source": [
"# check the status of the run\n",
"import time\n",
"from IPython.display import clear_output\n",
"\n",
"start_time = time.time()\n",
"\n",
"status = run.status\n",
"\n",
"while status not in [\"completed\", \"cancelled\", \"expired\", \"failed\"]:\n",
" time.sleep(5)\n",
" run = client.beta.threads.runs.retrieve(thread_id=thread.id,run_id=run.id)\n",
" print(\"Elapsed time: {} minutes {} seconds\".format(int((time.time() - start_time) // 60), int((time.time() - start_time) % 60)))\n",
" status = run.status\n",
" print(f'Status: {status}')\n",
" clear_output(wait=True)\n",
"\n",
"messages = client.beta.threads.messages.list(\n",
" thread_id=thread.id\n",
") \n",
"\n",
"print(f'Status: {status}')\n",
"print(\"Elapsed time: {} minutes {} seconds\".format(int((time.time() - start_time) // 60), int((time.time() - start_time) % 60)))\n",
"print(messages.model_dump_json(indent=2))"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"data\": [\n",
" {\n",
" \"id\": \"msg_ERIdRIKeBVB5HHRyfaK4xIXd\",\n",
" \"assistant_id\": \"asst_cePxLU8BToWgvKHAj3FZvGkU\",\n",
" \"content\": [\n",
" {\n",
" \"image_file\": {\n",
" \"file_id\": \"assistant-BOfPBnFri7vKWiqGIRbdroqC\"\n",
" },\n",
" \"type\": \"image_file\"\n",
" },\n",
" {\n",
" \"text\": {\n",
" \"annotations\": [],\n",
" \"value\": \"Here is the visualization of a sine wave. The x-axis represents the values in radians, and the y-axis shows the sin(x) for those values. The plot displays a full cycle of a sine wave, from 0 to \\\\(2\\\\pi\\\\) radians.\"\n",
" },\n",
" \"type\": \"text\"\n",
" }\n",
" ],\n",
" \"created_at\": 1709151679,\n",
" \"file_ids\": [],\n",
" \"metadata\": {},\n",
" \"object\": \"thread.message\",\n",
" \"role\": \"assistant\",\n",
" \"run_id\": \"run_PcMAxg4JkeXdlePUWm7ntNW5\",\n",
" \"thread_id\": \"thread_AWxF97wT3MiwlZw1UYKTmZoA\"\n",
" },\n",
" {\n",
" \"id\": \"msg_OS6eZF2qwb5i7HzM8FglKrvU\",\n",
" \"assistant_id\": null,\n",
" \"content\": [\n",
" {\n",
" \"text\": {\n",
" \"annotations\": [],\n",
" \"value\": \"Create a visualization of a sinewave\"\n",
" },\n",
" \"type\": \"text\"\n",
" }\n",
" ],\n",
" \"created_at\": 1709151665,\n",
" \"file_ids\": [],\n",
" \"metadata\": {},\n",
" \"object\": \"thread.message\",\n",
" \"role\": \"user\",\n",
" \"run_id\": null,\n",
" \"thread_id\": \"thread_AWxF97wT3MiwlZw1UYKTmZoA\"\n",
" }\n",
" ],\n",
" \"object\": \"list\",\n",
" \"first_id\": \"msg_ERIdRIKeBVB5HHRyfaK4xIXd\",\n",
" \"last_id\": \"msg_OS6eZF2qwb5i7HzM8FglKrvU\",\n",
" \"has_more\": false\n",
"}\n"
]
}
],
"source": [
"messages = client.beta.threads.messages.list(\n",
" thread_id=thread.id\n",
")\n",
"\n",
"print(messages.model_dump_json(indent=2))"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"assistant-BOfPBnFri7vKWiqGIRbdroqC\n"
]
}
],
"source": [
"# show the file name\n",
"data = json.loads(messages.model_dump_json(indent=2)) # Load JSON data into a Python object\n",
"image_file_id = data['data'][0]['content'][0]['image_file']['file_id']\n",
"\n",
"print(image_file_id) # Outputs: assistant-1YGVTvNzc2JXajI5JU9F0HMD"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"# download the file\n",
"content = client.files.content(image_file_id)\n",
"\n",
"image= content.write_to_file(\"sinewave.png\")"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"# rewrite the code to display the image in jupyter notebook\n",
"\n",
"from PIL import Image\n",
"\n",
"# Display the image in the default image viewer\n",
"image = Image.open(\"sinewave.png\")\n",
"image.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Ask follow up questions"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"# Add a new user question to the thread\n",
"message = client.beta.threads.messages.create(\n",
" thread_id=thread.id,\n",
" role=\"user\",\n",
" content=\"Show me the generated code you used to generate the sinewave\"\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"queued\n"
]
}
],
"source": [
"run = client.beta.threads.runs.create(\n",
" thread_id=thread.id,\n",
" assistant_id=assistant.id,\n",
" #instructions=\"New instructions\" #You can optionally provide new instructions but these will override the default instructions\n",
")\n",
"\n",
"# Retrieve the status of the run\n",
"run = client.beta.threads.runs.retrieve(\n",
" thread_id=thread.id,\n",
" run_id=run.id\n",
")\n",
"\n",
"status = run.status\n",
"print(status)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"data\": [\n",
" {\n",
" \"id\": \"msg_BwYX22Cke4ZKfkF3SQkmgG7A\",\n",
" \"assistant_id\": \"asst_cePxLU8BToWgvKHAj3FZvGkU\",\n",
" \"content\": [\n",
" {\n",
" \"text\": {\n",
" \"annotations\": [],\n",
" \"value\": \"Certainly! Below 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# Prepare the data for a sinewave\\nx = np.linspace(0, 2 * np.pi, 1000) # x values from 0 to 2*pi\\ny = np.sin(x) # sin(x) for the y values\\n\\n# Create the plot for the sine wave\\nplt.figure(figsize=(10, 5))\\nplt.plot(x, y)\\nplt.title('Sine Wave')\\nplt.xlabel('x values (radians)')\\nplt.ylabel('sin(x)')\\nplt.grid(True)\\nplt.show()\\n```\"\n",
" },\n",
" \"type\": \"text\"\n",
" }\n",
" ],\n",
" \"created_at\": 1709151696,\n",
" \"file_ids\": [],\n",
" \"metadata\": {},\n",
" \"object\": \"thread.message\",\n",
" \"role\": \"assistant\",\n",
" \"run_id\": \"run_7gKBsbRdRj22xVtwk8yTpZ51\",\n",
" \"thread_id\": \"thread_AWxF97wT3MiwlZw1UYKTmZoA\"\n",
" },\n",
" {\n",
" \"id\": \"msg_gj8xcCmKXRWLz2BF5HjkYn3E\",\n",
" \"assistant_id\": null,\n",
" \"content\": [\n",
" {\n",
" \"text\": {\n",
" \"annotations\": [],\n",
" \"value\": \"Show me the generated code you used to generate the sinewave\"\n",
" },\n",
" \"type\": \"text\"\n",
" }\n",
" ],\n",
" \"created_at\": 1709151695,\n",
" \"file_ids\": [],\n",
" \"metadata\": {},\n",
" \"object\": \"thread.message\",\n",
" \"role\": \"user\",\n",
" \"run_id\": null,\n",
" \"thread_id\": \"thread_AWxF97wT3MiwlZw1UYKTmZoA\"\n",
" },\n",
" {\n",
" \"id\": \"msg_ERIdRIKeBVB5HHRyfaK4xIXd\",\n",
" \"assistant_id\": \"asst_cePxLU8BToWgvKHAj3FZvGkU\",\n",
" \"content\": [\n",
" {\n",
" \"image_file\": {\n",
" \"file_id\": \"assistant-BOfPBnFri7vKWiqGIRbdroqC\"\n",
" },\n",
" \"type\": \"image_file\"\n",
" },\n",
" {\n",
" \"text\": {\n",
" \"annotations\": [],\n",
" \"value\": \"Here is the visualization of a sine wave. The x-axis represents the values in radians, and the y-axis shows the sin(x) for those values. The plot displays a full cycle of a sine wave, from 0 to \\\\(2\\\\pi\\\\) radians.\"\n",
" },\n",
" \"type\": \"text\"\n",
" }\n",
" ],\n",
" \"created_at\": 1709151679,\n",
" \"file_ids\": [],\n",
" \"metadata\": {},\n",
" \"object\": \"thread.message\",\n",
" \"role\": \"assistant\",\n",
" \"run_id\": \"run_PcMAxg4JkeXdlePUWm7ntNW5\",\n",
" \"thread_id\": \"thread_AWxF97wT3MiwlZw1UYKTmZoA\"\n",
" },\n",
" {\n",
" \"id\": \"msg_OS6eZF2qwb5i7HzM8FglKrvU\",\n",
" \"assistant_id\": null,\n",
" \"content\": [\n",
" {\n",
" \"text\": {\n",
" \"annotations\": [],\n",
" \"value\": \"Create a visualization of a sinewave\"\n",
" },\n",
" \"type\": \"text\"\n",
" }\n",
" ],\n",
" \"created_at\": 1709151665,\n",
" \"file_ids\": [],\n",
" \"metadata\": {},\n",
" \"object\": \"thread.message\",\n",
" \"role\": \"user\",\n",
" \"run_id\": null,\n",
" \"thread_id\": \"thread_AWxF97wT3MiwlZw1UYKTmZoA\"\n",
" }\n",
" ],\n",
" \"object\": \"list\",\n",
" \"first_id\": \"msg_BwYX22Cke4ZKfkF3SQkmgG7A\",\n",
" \"last_id\": \"msg_OS6eZF2qwb5i7HzM8FglKrvU\",\n",
" \"has_more\": false\n",
"}\n"
]
}
],
"source": [
"messages = client.beta.threads.messages.list(\n",
" thread_id=thread.id\n",
")\n",
"\n",
"print(messages.model_dump_json(indent=2))"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Certainly! Below is the code I used to generate the sine wave visualization:\n",
"\n",
"```python\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"# Prepare the data for a sinewave\n",
"x = np.linspace(0, 2 * np.pi, 1000) # x values from 0 to 2*pi\n",
"y = np.sin(x) # sin(x) for the y values\n",
"\n",
"# Create the plot for the sine wave\n",
"plt.figure(figsize=(10, 5))\n",
"plt.plot(x, y)\n",
"plt.title('Sine Wave')\n",
"plt.xlabel('x values (radians)')\n",
"plt.ylabel('sin(x)')\n",
"plt.grid(True)\n",
"plt.show()\n",
"```\n"
]
}
],
"source": [
"# Print the code\n",
"data = json.loads(messages.model_dump_json(indent=2))\n",
"code = data['data'][0]['content'][0]['text']['value']\n",
"print(code)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "openai_v1",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "0.0.0"
}
},
"nbformat": 4,
"nbformat_minor": 2
}