{ "cells": [ { "cell_type": "markdown", "id": "9ad133d1", "metadata": {}, "source": [ "# πŸ” Agentic RAG with Azure AI Foundry (Python)\n", "\n", "## πŸ“‹ Learning Objectives\n", "\n", "This notebook demonstrates how to build intelligent Retrieval-Augmented Generation (RAG) systems using the Microsoft Agent Framework with Azure AI Foundry. You'll learn to create agents that can search through documents and provide accurate, grounded responses based on uploaded content.\n", "\n", "**Key RAG Capabilities You'll Build:**\n", "- πŸ“š **Document Upload**: Upload and process documents for agent access\n", "- πŸ” **Vector Store Creation**: Create searchable vector stores for semantic retrieval\n", "- πŸ€– **Grounded Responses**: Build agents that only answer from document content\n", "- πŸ›‘οΈ **Source Attribution**: Ensure responses are traceable to source documents\n", "\n", "## 🎯 RAG Architecture Concepts\n", "\n", "### Core RAG Components\n", "- **Document Processing**: Upload files to Azure AI Foundry for indexing\n", "- **Vector Store**: Semantic search capability for relevant content retrieval\n", "- **File Search Tool**: Agent tool that queries the vector store\n", "- **Grounded Generation**: AI responses based only on retrieved context\n", "\n", "### Technical Flow\n", "```python\n", "Document Upload β†’ Vector Store Creation β†’ Agent Configuration\n", " ↓ ↓\n", "User Query β†’ File Search Tool β†’ Retrieved Context β†’ Grounded Response\n", "```\n", "\n", "## πŸ—οΈ Technical Architecture\n", "\n", "### Microsoft Agent Framework Integration\n", "- **FoundryChatClient**: Primary client for Azure AI Foundry integration with built-in file search\n", "- **Agent**: Core agent class for building intelligent conversational agents\n", "- **client.client**: Access to underlying Azure AI client for file/vector store operations\n", "- **get_file_search_tool()**: Built-in method to create file search tools\n", "\n", "### Agent Behavior\n", "- Only answers questions using information from uploaded documents\n", "- Clearly indicates when questions cannot be answered from available content\n", "- Provides explicit citations to source documents\n", "- Avoids general knowledge responses outside document scope\n", "\n", "## βš™οΈ Prerequisites & Setup\n", "\n", "**Required Dependencies:**\n", "```bash\n", "pip install agent-framework-core agent-framework-foundry azure-identity -U\n", "```\n", "\n", "**Azure Configuration:**\n", "- Azure subscription with AI Foundry access\n", "- Azure CLI authentication configured\n", "- Environment variables in `.env` file:\n", " ```env\n", " FOUNDRY_PROJECT_ENDPOINT=your_project_endpoint\n", " FOUNDRY_MODEL=your_model_deployment\n", " ```\n", "\n", "**Authentication:**\n", "```bash\n", "az login --tenant \n", "```\n", "\n", "## πŸ“Š Use Cases\n", "\n", "### Knowledge Management\n", "- Corporate document Q&A systems\n", "- Policy and procedure guidance\n", "- Technical documentation assistants\n", "- Training material search\n", "\n", "### Customer Support\n", "- Product documentation queries\n", "- Troubleshooting guide search\n", "- FAQ and knowledge base systems\n", "- Support ticket assistance\n", "\n", "## πŸš€ Getting Started\n", "\n", "Follow the cells below to:\n", "1. Install required dependencies and import libraries\n", "2. Create a vector store with sample documents\n", "3. Configure an agent with file search capabilities\n", "4. Query the agent and receive grounded responses\n", "\n", "Let's build an intelligent document-aware assistant! πŸ“–βœ¨" ] }, { "cell_type": "code", "execution_count": 1, "id": "3a7e1e59", "metadata": {}, "outputs": [], "source": [ "# ! pip install -r ../../../Installation/requirements.txt -U" ] }, { "cell_type": "code", "execution_count": 2, "id": "97f08567", "metadata": {}, "outputs": [], "source": [ "import contextlib\n", "from azure.identity import AzureCliCredential\n", "from dotenv import load_dotenv\n", "\n", "from agent_framework import Agent\n", "from agent_framework.foundry import FoundryChatClient" ] }, { "cell_type": "markdown", "id": "19259437", "metadata": {}, "source": [ "## πŸ“¦ Import Required Libraries\n", "\n", "Import Microsoft Agent Framework core components and Azure authentication libraries:\n", "- `Agent`: Core agent class for building intelligent agents\n", "- `FoundryChatClient`: Azure AI Foundry chat client with file search capabilities\n", "- `AzureCliCredential`: Authentication via Azure CLI" ] }, { "cell_type": "code", "execution_count": 3, "id": "2a3bcf9d", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "load_dotenv()" ] }, { "cell_type": "markdown", "id": "8caecdc0", "metadata": {}, "source": [ "## πŸ”§ Load Environment Variables\n", "\n", "Load Azure AI Foundry configuration from the `.env` file." ] }, { "cell_type": "code", "execution_count": 4, "id": "3d3ca050", "metadata": {}, "outputs": [], "source": [ "# Define the query for the agent\n", "query = \"What's GraphRAG?\"" ] }, { "cell_type": "markdown", "id": "b83d09cc", "metadata": {}, "source": [ "## ❓ Define Query\n", "\n", "Set up the question to ask the RAG agent about the uploaded document." ] }, { "cell_type": "code", "execution_count": 5, "id": "0aef5316", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Uploading file from: ../files/demo.md\n", "Uploaded file, file ID: assistant-NngmEZ6fUPdtnr8pKyvz9X\n", "Created vector store, vector store ID: vs_eqlGLmi8xDsN93OuCU15YRPm\n", "File successfully added to vector store\n", "\n", "# User: 'What's GraphRAG?'\n", "# Agent: GraphRAG is an AI-based content interpretation and search capability that uses LLMs to parse data, build a knowledge graph, and answer questions about a user-provided private dataset. \n", "\n", "In the uploaded document, it’s described as especially useful when answers span many documents or when the questions are more thematic or abstract than simple keyword or vector search can handleβ€”for example, finding connections across a large corpus or identifying top themes in a dataset. \n", "\n", "A few key points from the doc:\n", "- It connects information across large volumes of text using a knowledge graph. \n", "- It’s intended for analysis and information discovery in complex, noisy, domain-specific corpora. \n", "- Human review is still important: the document says domain experts should verify and augment GraphRAG’s responses. \n", "\n", "If you want, I can also explain how GraphRAG differs from standard RAG in simple terms.\n", "\n", "Deleted vector store: vs_eqlGLmi8xDsN93OuCU15YRPm\n", "Deleted file: assistant-NngmEZ6fUPdtnr8pKyvz9X\n" ] } ], "source": [ "file_id = None\n", "vector_store_id = None\n", "\n", "# Initialize the Foundry chat client\n", "client = FoundryChatClient(credential=AzureCliCredential())\n", "\n", "try:\n", " # 1. Upload file and create vector store\n", " file_path = '../files/demo.md' # Path to the file to be uploaded\n", " print(f\"Uploading file from: {file_path}\")\n", " \n", " # Read file content\n", " with open(file_path, 'rb') as f:\n", " file_content = f.read()\n", " \n", " # Upload file to Foundry\n", " file = await client.client.files.create(\n", " file=(\"demo.md\", file_content),\n", " purpose=\"assistants\"\n", " )\n", " file_id = file.id\n", " print(f\"Uploaded file, file ID: {file_id}\")\n", " \n", " # Create vector store with expiry\n", " vector_store = await client.client.vector_stores.create(\n", " name=\"rag_knowledge_base\",\n", " expires_after={\"anchor\": \"last_active_at\", \"days\": 1}\n", " )\n", " vector_store_id = vector_store.id\n", " print(f\"Created vector store, vector store ID: {vector_store_id}\")\n", " \n", " # Add file to vector store\n", " result = await client.client.vector_stores.files.create_and_poll(\n", " vector_store_id=vector_store_id,\n", " file_id=file_id\n", " )\n", " \n", " if result.last_error is not None:\n", " raise Exception(f\"Vector store file processing failed: {result.last_error.message}\")\n", " \n", " print(\"File successfully added to vector store\")\n", " \n", " # 2. Create file search tool using the client's method\n", " file_search_tool = client.get_file_search_tool(vector_store_ids=[vector_store_id])\n", " \n", " # 3. Create an agent with file search capabilities\n", " agent = Agent(\n", " client=client,\n", " name =\"PythonRAGAgent\",\n", " instructions=(\n", " \"You are an AI assistant that helps people find information in a set of documents. Use the File Search tool to look up relevant information from the files when needed to answer user questions. If you don't know the answer, just say you don't know. Do not make up answers.\"\n", " ),\n", " tools=[file_search_tool],\n", " )\n", " \n", " # 4. Query the agent\n", " print(f\"\\n# User: '{query}'\")\n", " response = await agent.run(query)\n", " print(f\"# Agent: {response}\\n\")\n", " \n", "finally:\n", " # 5. Cleanup: Delete the vector store and file to prevent orphaned resources\n", " if vector_store_id:\n", " with contextlib.suppress(Exception):\n", " await client.client.vector_stores.delete(vector_store_id)\n", " print(f\"Deleted vector store: {vector_store_id}\")\n", " if file_id:\n", " with contextlib.suppress(Exception):\n", " await client.client.files.delete(file_id)\n", " print(f\"Deleted file: {file_id}\")" ] } ], "metadata": { "kernelspec": { "display_name": "agentdev", "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.12.10" }, "polyglot_notebook": { "kernelInfo": { "defaultKernelName": "csharp", "items": [ { "aliases": [], "name": "csharp" } ] } } }, "nbformat": 4, "nbformat_minor": 5 }