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 }