2-notebooks/2-agent_service/2-code_interpreter.ipynb (380 lines of code) (raw):
{
"cells": [
{
"cell_type": "markdown",
"id": "fun-fit-intro",
"metadata": {},
"source": [
"# š Health Calculator Agent Tutorial š\n",
"\n",
"Welcome to the **Health Calculator Agent** tutorial, where we'll showcase how to:\n",
"1. **Initialize** a project and use the Azure AI Foundry ecosystem\n",
"2. **Create an Agent** with **Code Interpreter** capabilities\n",
"3. **Perform BMI calculations** and **analyze nutritional data** with sample CSV files\n",
"4. **Generate** basic health insights and disclaimers\n",
"\n",
"> #### Ensure you have completed the [`1-basics.ipynb`](./1-basics.ipynb) notebook before starting this one.\n",
"\n",
"## Let's Dive In\n",
"We'll walk step-by-step, similar to our **Fun & Fit** sample, but with a focus on using **Code Interpreter** for numeric calculations and data analysis. Let's begin!\n",
"\n",
"<img src=\"./seq-diagrams/2-code-interpreter.png\" width=\"30%\"/>\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "init-setup",
"metadata": {},
"source": [
"## 1. Initial Setup\n",
"We'll start by importing libraries, loading environment variables, and initializing an **AIProjectClient**. We'll also create a sample CSV for demonstration.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "init-code",
"metadata": {},
"outputs": [],
"source": [
"# Import required libraries\n",
"import os\n",
"import time\n",
"from pathlib import Path\n",
"\n",
"import pandas as pd\n",
"from dotenv import load_dotenv\n",
"from azure.identity import DefaultAzureCredential\n",
"from azure.ai.projects import AIProjectClient\n",
"from azure.ai.projects.models import CodeInterpreterTool, FilePurpose, MessageTextContent\n",
"\n",
"# Load environment variables from the parent directory's .env\n",
"notebook_path = Path().absolute()\n",
"parent_dir = notebook_path.parent\n",
"load_dotenv(parent_dir.parent / '.env')\n",
"\n",
"# Initialize AIProjectClient\n",
"try:\n",
" project_client = AIProjectClient.from_connection_string(\n",
" credential=DefaultAzureCredential(),\n",
" conn_str=os.environ[\"PROJECT_CONNECTION_STRING\"],\n",
" )\n",
" print(\"ā
Successfully initialized AIProjectClient\")\n",
"except Exception as e:\n",
" print(f\"ā Error initializing client: {str(e)}\")\n",
"\n",
"# Create sample CSV data for demonstration\n",
"def create_sample_data():\n",
" try:\n",
" data = {\n",
" 'Date': pd.date_range(start='2024-01-01', periods=7),\n",
" 'Calories': [2100, 1950, 2300, 2050, 1900, 2200, 2150],\n",
" 'Protein_g': [80, 75, 85, 78, 72, 82, 79],\n",
" 'Carbs_g': [250, 230, 270, 245, 225, 260, 255],\n",
" 'Fat_g': [70, 65, 75, 68, 63, 73, 71],\n",
" 'Fiber_g': [25, 22, 28, 24, 21, 26, 23]\n",
" }\n",
" df = pd.DataFrame(data)\n",
" filename = \"nutrition_data.csv\"\n",
" df.to_csv(filename, index=False)\n",
" print(f\"š Created sample data file: {filename}\")\n",
" return filename\n",
" except Exception as e:\n",
" print(f\"ā Error creating sample data: {e}\")\n",
" return None\n",
"\n",
"sample_file = create_sample_data()"
]
},
{
"cell_type": "markdown",
"id": "create-agent",
"metadata": {},
"source": [
"## 2. Create Health Calculator Agent š©š»\n",
"We'll upload our sample CSV and then create an agent with **Code Interpreter** enabled. This agent can read the file, run Python code, and return results and visualizations.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "create-agent-code",
"metadata": {},
"outputs": [],
"source": [
"def create_health_calculator(file_path):\n",
" \"\"\"Create an agent with code interpreter for health/nutrition calculations.\"\"\"\n",
" try:\n",
" uploaded_file = project_client.agents.upload_file_and_poll(\n",
" file_path=file_path,\n",
" purpose=FilePurpose.AGENTS\n",
" )\n",
" print(f\"ā
Uploaded CSV file, ID: {uploaded_file.id}\")\n",
"\n",
" # Create a Code Interpreter tool referencing the uploaded file\n",
" code_tool = CodeInterpreterTool(file_ids=[uploaded_file.id])\n",
"\n",
" # Create the agent with instructions to do basic calculations\n",
" agent = project_client.agents.create_agent(\n",
" model=os.environ.get(\"MODEL_DEPLOYMENT_NAME\", \"gpt-4o-mini\"),\n",
" name=\"health-calculator-agent\",\n",
" instructions=\"\"\"\n",
" You are a health calculator agent that can:\n",
" 1. Calculate and interpret BMI\n",
" 2. Analyze provided nutrition data\n",
" 3. Generate charts/plots\n",
" 4. Include disclaimers that you are not a medical professional\n",
" \"\"\",\n",
" tools=code_tool.definitions,\n",
" tool_resources=code_tool.resources\n",
" )\n",
" print(f\"š Created health calculator agent, ID: {agent.id}\")\n",
" return agent, uploaded_file\n",
" except Exception as e:\n",
" print(f\"ā Error creating health calculator agent: {e}\")\n",
" return None, None\n",
"\n",
"health_agent, uploaded_file = None, None\n",
"if sample_file:\n",
" health_agent, uploaded_file = create_health_calculator(sample_file)"
]
},
{
"cell_type": "markdown",
"id": "bmi-thread",
"metadata": {},
"source": [
"## 3. BMI Calculation with Code Interpreter\n",
"We'll create a thread for BMI calculations. We'll feed in the user's height/weight, and ask the agent to show how it calculates BMI, interpret the result, and always disclaim professional advice.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bmi-thread-code",
"metadata": {},
"outputs": [],
"source": [
"def calculate_bmi_with_agent(agent, height_inches, weight_pounds):\n",
" \"\"\"Calculate BMI using the code interpreter agent.\"\"\"\n",
" try:\n",
" # Create a new conversation thread\n",
" thread = project_client.agents.create_thread()\n",
" print(f\"š Created thread for BMI calculation, ID: {thread.id}\")\n",
"\n",
" # Construct user message requesting BMI calculation\n",
" user_text = (\n",
" f\"Calculate BMI for \\n\"\n",
" f\"Height: {height_inches} inches\\n\"\n",
" f\"Weight: {weight_pounds} pounds\\n\"\n",
" \"Please: \\n\"\n",
" \"1. Show calculation \\n\"\n",
" \"2. Interpret the result \\n\"\n",
" \"3. Include disclaimers \\n\"\n",
" )\n",
"\n",
" msg = project_client.agents.create_message(\n",
" thread_id=thread.id,\n",
" role=\"user\",\n",
" content=user_text\n",
" )\n",
" print(f\"ā Created BMI request message, ID: {msg.id}\")\n",
"\n",
" # Create and process the run, letting the agent handle code\n",
" run = project_client.agents.create_and_process_run(\n",
" thread_id=thread.id,\n",
" agent_id=agent.id\n",
" )\n",
" print(f\"š¤ BMI run finished with status: {run.status}\")\n",
" return thread, run\n",
" except Exception as e:\n",
" print(f\"ā Error during BMI calculation: {e}\")\n",
" return None, None\n",
"\n",
"if health_agent:\n",
" bmi_thread, bmi_run = calculate_bmi_with_agent(health_agent, 70, 180) # example: 5'10\" and 180 lbs\n"
]
},
{
"cell_type": "markdown",
"id": "nutrition-analysis",
"metadata": {},
"source": [
"## 4. Nutrition Analysis\n",
"We'll create another thread where the user can ask the agent to analyze the **`nutrition_data.csv`** we uploaded. The agent can read the file, compute macros, produce charts, and disclaim that it's not offering personalized medical advice.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "nutrition-analysis-code",
"metadata": {},
"outputs": [],
"source": [
"def analyze_nutrition_data(agent):\n",
" \"\"\"Ask the agent to analyze the uploaded nutrition data.\"\"\"\n",
" try:\n",
" thread = project_client.agents.create_thread()\n",
" print(f\"š Created thread for nutrition analysis, ID: {thread.id}\")\n",
"\n",
" user_text = (\n",
" \"Analyze the CSV file with daily nutrition data.\\n\"\n",
" \"1. Compute average daily macros (calories, protein, carbs, fat, fiber).\\n\"\n",
" \"2. Create a chart to show trends.\\n\"\n",
" \"3. Discuss any insights or disclaimers.\\n\"\n",
" )\n",
"\n",
" msg = project_client.agents.create_message(\n",
" thread_id=thread.id,\n",
" role=\"user\",\n",
" content=user_text\n",
" )\n",
" print(f\"ā Created nutrition request message, ID: {msg.id}\")\n",
"\n",
" run = project_client.agents.create_and_process_run(\n",
" thread_id=thread.id,\n",
" agent_id=agent.id\n",
" )\n",
" print(f\"š¤ Nutrition run finished with status: {run.status}\")\n",
" return thread, run\n",
" except Exception as e:\n",
" print(f\"ā Error analyzing nutrition data: {e}\")\n",
" return None, None\n",
"\n",
"if health_agent:\n",
" nutrition_thread, nutrition_run = analyze_nutrition_data(health_agent)"
]
},
{
"cell_type": "markdown",
"id": "view-results",
"metadata": {},
"source": [
"## 5. Viewing Results & Visualizations š\n",
"The agent may produce text insights, disclaimers, and even images with charts. Let's fetch them from our threads!\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "view-results-code",
"metadata": {},
"outputs": [],
"source": [
"def view_agent_responses(thread_id):\n",
" try:\n",
" messages = project_client.agents.list_messages(thread_id=thread_id)\n",
" print(\"\\nš Agent Responses:\")\n",
" for msg in messages.data:\n",
" if msg.role == \"assistant\" and msg.content:\n",
" for c in msg.content:\n",
" if hasattr(c, \"text\"):\n",
" print(\"Response:\", c.text.value, \"\\n\")\n",
"\n",
" # If images were generated, let's save them\n",
" for img in messages.image_contents:\n",
" file_id = img.image_file.file_id\n",
" outname = f\"chart_{file_id}.png\"\n",
" project_client.agents.save_file(file_id=file_id, file_name=outname)\n",
" print(f\"š¼ļø Saved image output: {outname}\")\n",
"\n",
" except Exception as e:\n",
" print(f\"ā Error viewing agent responses: {e}\")\n",
"\n",
"# Display BMI calculations\n",
"if bmi_thread and bmi_run:\n",
" print(\"\\n=== BMI Calculation Results ===\")\n",
" view_agent_responses(bmi_thread.id)\n",
"\n",
"# Display nutrition analyses\n",
"if nutrition_thread and nutrition_run:\n",
" print(\"\\n=== Nutrition Analysis Results ===\")\n",
" view_agent_responses(nutrition_thread.id)"
]
},
{
"cell_type": "markdown",
"id": "cleanup",
"metadata": {},
"source": [
"## 6. Cleanup & Best Practices\n",
"We can remove our agent and sample data if desired. In production, you might keep them for repeated usage.\n",
"\n",
"### Best Practices in a Nutshell\n",
"1. **Data Handling** – Validate input data, handle missing values, properly manage file attachments.\n",
"2. **Calculations** – Provide formula steps, disclaimers, limit scope to general wellness, remind user you're not a doctor.\n",
"3. **Visualizations** – Use clear labeling and disclaimers that charts are for educational demonstrations.\n",
"4. **Security** – Monitor usage, limit access to code interpreter if dealing with proprietary data.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cleanup-code",
"metadata": {},
"outputs": [],
"source": [
"def cleanup_all():\n",
" try:\n",
" # Delete the uploaded CSV file from the service\n",
" if 'uploaded_file' in globals() and uploaded_file:\n",
" project_client.agents.delete_file(uploaded_file.id)\n",
" print(\"šļø Deleted uploaded file from agent service.\")\n",
"\n",
" # Delete the agent if we created one\n",
" if 'health_agent' in globals() and health_agent:\n",
" project_client.agents.delete_agent(health_agent.id)\n",
" print(\"šļø Deleted health calculator agent.\")\n",
"\n",
" # Delete local CSV file\n",
" if 'sample_file' in globals() and sample_file and os.path.exists(sample_file):\n",
" os.remove(sample_file)\n",
" print(\"šļø Deleted local sample CSV file.\")\n",
"\n",
" except Exception as e:\n",
" print(f\"ā Error during cleanup: {e}\")\n",
"\n",
"cleanup_all()"
]
},
{
"cell_type": "markdown",
"id": "conclusion",
"metadata": {},
"source": [
"# Congratulations! š\n",
"You now have a **Health Calculator Agent** with the **Code Interpreter** tool that can:\n",
"- Perform **BMI calculations** and disclaim that it's not a doctor.\n",
"- **Analyze** simple CSV-based nutrition data and produce insights + charts.\n",
"- Return images (charts) and text-based insights.\n",
"\n",
"#### Let's proceed to [3-file-search.ipynb](3-file-search.ipynb)\n",
"\n",
"Happy (healthy) coding! šŖ\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"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": "3.11.11"
}
},
"nbformat": 4,
"nbformat_minor": 5
}