Skip to main content

Deploy Your First AI Agent on Azure

Build a production-ready AI agent in one day. No fluff, pure practical guidance.

💡 Optional: Case Study Context

Read the Contoso Case Study first if you want real-world business context. It shows why you'd make these architectural choices. But if you prefer learning by doing, jump straight in below.

Getting Started

Deploy an AI agent that's safe, stateful, and grounded in real data.

You want to deploy an AI agent on Azure. Where do you start? This guide walks you through the essentials: deployment decisions, safety setup, conversation memory, and knowledge grounding. By the end, you'll have a working blueprint.


🎯 The 30-Second Overview​

An AI agent needs four things:

LayerPurposeLearn More
DeploymentChoose infrastructure (scale, cost, compliance)5 Critical Decisions
SafetyPrevent jailbreaks, content filtering, tool approvalAgent Configuration
MemoryRemember conversations, build contextComing soon
KnowledgeGround responses in real data (RAG)Knowledge Grounding

🚀 Choose Your Deployment Approach​

Option A: 🎨 UI-Based (Azure Foundry Studio)​

Best for: Quick setup, visual interface, no coding

  1. Go to Azure Foundry Studio
  2. Create new project
  3. Select model (e.g., gpt-4o)
  4. Configure safety settings
  5. Click "Deploy"

No code needed. You get a working agent in minutes.

👉 See UI Tutorial (Microsoft Learn)


Option B: 💻 Code-Based (Python SDK)​

Best for: Production workflows, automation, complete control, integration with existing systems

This walkthrough shows Option B with Python SDK and async patterns for production readiness. All code is copy-paste ready and uses Managed Identity (no API keys needed).

Other Code Approaches
  • Azure CLI: Use az foundry commands for scripted deployment
  • Terraform/Bicep: Infrastructure-as-code for CI/CD pipelines
  • REST API: Direct Azure Resource Manager calls

See Deployment Types & Decisions for infrastructure patterns.


🚀 Option B: Code-Based Deployment with Python SDK​

Step 0: Prerequisites​

Before you start, you need:

# Install Python packages
pip install azure-ai-openai azure-identity azure-cosmos azure-search-documents

# Set environment variables (no API keys!)
export AZURE_OPENAI_ENDPOINT="https://your-openai.openai.azure.com/"
export AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4o"
export AZURE_COSMOS_ENDPOINT="https://your-cosmos.documents.azure.com:443/"
export AZURE_SEARCH_ENDPOINT="https://your-search.search.windows.net"

Step 1: Deploy & Connect to the Model​

Create and connect to Azure OpenAI using Managed Identity (no API keys):

from azure.ai.openai import AzureOpenAI
from azure.identity import DefaultAzureCredential

# ✅ Use Managed Identity - Azure handles auth automatically
credential = DefaultAzureCredential()

client = AzureOpenAI(
api_version="2024-08-01-preview",
endpoint="https://your-openai.openai.azure.com/", # Your region
credential=credential
)

# Test: Send a simple message
response = client.chat.completions.create(
model="gpt-4o", # Your deployed model name
messages=[
{"role": "user", "content": "Hello! What's 2+2?"}
]
)

print(f"✅ Model responded: {response.choices[0].message.content}")

What this does:

  • Connects to your Azure OpenAI resource
  • Uses Managed Identity (secure, no credentials in code)
  • Sends a test message and gets a response

Next level (detailed decisions): 5 Critical Deployment Decisions


Step 2: Add Safety Evaluation​

Before processing user input, evaluate it for safety:

# For learning: Here's a simple safety check pattern
# For production: See [Agent Configuration Overview](../agent-configuration/agent-configuration-overview)

def evaluate_user_input(user_message: str) -> dict:
"""
Simple safety evaluation pattern.
Production implementation uses Azure Content Safety service.
"""

# Pattern 1: Length check (prevent prompt injection)
if len(user_message) > 1000:
return {"safe": False, "reason": "input_too_long"}

# Pattern 2: Blocklist check
blocklist = ["password", "api_key", "credit_card"]
if any(term in user_message.lower() for term in blocklist):
return {"safe": False, "reason": "blocked_terms"}

# Pattern 3: Jailbreak pattern detection
jailbreak_patterns = ["ignore previous", "pretend you are", "act like"]
if any(pattern in user_message.lower() for pattern in jailbreak_patterns):
return {"safe": False, "reason": "jailbreak_attempt"}

return {"safe": True, "reason": "ok"}

# Use it
user_input = "What's the weather?"
safety_check = evaluate_user_input(user_input)

if safety_check["safe"]:
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": user_input}]
)
print(f"Response: {response.choices[0].message.content}")
else:
print(f"⚠️ Input blocked: {safety_check['reason']}")

What this does:

  • Checks for injection attempts
  • Blocks sensitive terms
  • Detects jailbreak patterns
  • Rejects unsafe input

For production safety (content filtering, jailbreak detection): Agent Configuration Overview


Step 3: Add Conversation Memory​

Store conversations so the agent remembers context:

from azure.cosmos.aio import CosmosClient
from azure.identity import DefaultAzureCredential
import uuid
from datetime import datetime
import asyncio

credential = DefaultAzureCredential()

async def init_cosmos():
"""Initialize Cosmos DB connection"""
cosmos_client = CosmosClient(
url="https://your-cosmos.documents.azure.com:443/",
credential=credential
)

# Get database and container
database = cosmos_client.get_database_client("agent_db")
container = database.get_container_client("conversations")

return container

async def save_conversation(container, customer_id: str, question: str, answer: str):
"""Save a conversation turn to memory"""

conversation_item = {
"id": str(uuid.uuid4()),
"customer_id": customer_id,
"timestamp": datetime.utcnow().isoformat(),
"question": question,
"answer": answer
}

await container.upsert_item(conversation_item)
print(f"✅ Saved conversation for customer {customer_id}")

async def get_conversation_history(container, customer_id: str, limit: int = 5):
"""Retrieve previous conversations for context"""

query = "SELECT * FROM c WHERE c.customer_id = @cid ORDER BY c.timestamp DESC"
items = container.query_items(
query=query,
parameters=[{"name": "@cid", "value": customer_id}]
)

history = []
async for item in items:
if len(history) >= limit:
break
history.append(item)

return list(reversed(history)) # Chronological order

# Use it
async def example_with_memory():
container = await init_cosmos()

customer_id = "customer_123"

# Get previous context
history = await get_conversation_history(container, customer_id)

# Build system prompt with context
system_prompt = "You are a helpful assistant. Remember: "
for conv in history:
system_prompt += f"Previously: {conv['question'][:30]}... "

# Get response
response = client.chat.completions.create(
model="gpt-4o",
system=system_prompt,
messages=[
{"role": "user", "content": "What did we discuss before?"}
]
)

answer = response.choices[0].message.content

# Save for next time
await save_conversation(
container,
customer_id,
"What did we discuss before?",
answer
)

# Run it
asyncio.run(example_with_memory())

What this does:

  • Connects to Cosmos DB (conversation store)
  • Saves each conversation turn
  • Retrieves previous context for personalization
  • Includes context in agent prompt

For detailed memory patterns: Coming soon - Memory & Conversation Topics


Step 4: Add Knowledge Grounding (RAG)​

Enable semantic search over your data:

from azure.search.documents.aio import SearchClient
from azure.search.documents.models import VectorizedQuery
import asyncio

async def search_knowledge_base(query: str, top_k: int = 3) -> list:
"""Find relevant information using semantic search"""

search_client = SearchClient(
endpoint="https://your-search.search.windows.net",
index_name="products", # Your index name
credential=credential
)

# For this example, using text search
# Production uses vector embeddings - see Knowledge Grounding article

results = await search_client.search(
search_text=query,
select=["content", "source"],
top=top_k
)

docs = []
async for result in results:
docs.append({
"content": result["content"],
"source": result["source"]
})

return docs

async def agent_with_knowledge():
"""Query agent with knowledge grounding"""

# User asks a question
user_question = "What's your warranty policy?"

# Retrieve relevant knowledge
knowledge_docs = await search_knowledge_base(user_question)

# Build context from knowledge
knowledge_context = "Based on our documentation:\n\n"
for doc in knowledge_docs:
knowledge_context += f"- {doc['content']}\n"

# Ask agent with grounding
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": f"Answer based ONLY on this information:\n{knowledge_context}"
},
{
"role": "user",
"content": user_question
}
]
)

print(f"✅ Grounded answer: {response.choices[0].message.content}")

# Run it
asyncio.run(agent_with_knowledge())

What this does:

  • Searches your knowledge base (AI Search index)
  • Retrieves relevant documents
  • Grounds agent response in real data
  • Reduces hallucinations

For complete RAG setup (embeddings, vector indexing, chunking): Knowledge Grounding Overview


Step 5: Bring It All Together​

async def full_agent_example():
"""Complete agent: deployment + safety + memory + knowledge"""

# Initialize
container = await init_cosmos()
customer_id = "customer_456"

# User input
user_message = "Do you have the blue widget in stock?"

# Step 1: Safety check
safety = evaluate_user_input(user_message)
if not safety["safe"]:
print(f"⚠️ Rejected: {safety['reason']}")
return

# Step 2: Get memory context
history = await get_conversation_history(container, customer_id, limit=3)

# Step 3: Search knowledge base
knowledge = await search_knowledge_base(user_message)

# Step 4: Build prompt with all context
knowledge_text = "\n".join([f"- {doc['content']}" for doc in knowledge])

system_prompt = f"""You are a helpful product assistant.
Use ONLY this knowledge base:
{knowledge_text}

Previous context:"""
for conv in history:
system_prompt += f"\n- User asked: {conv['question'][:40]}..."

# Step 5: Get response from model
response = client.chat.completions.create(
model="gpt-4o",
system=system_prompt,
messages=[
{"role": "user", "content": user_message}
]
)

answer = response.choices[0].message.content
print(f"Agent: {answer}")

# Step 6: Save to memory
await save_conversation(container, customer_id, user_message, answer)

# Run it
asyncio.run(full_agent_example())

✅ What You Just Built​

You now have a working agent with:

  • ✅ Model deployment (Azure OpenAI)
  • ✅ Safety evaluation (input validation)
  • ✅ Conversation memory (Cosmos DB)
  • ✅ Knowledge grounding (AI Search)
  • ✅ Secure auth (Managed Identity)

Each piece can be enhanced by reading the detailed articles.


📚 Next: Go Deeper​

TopicWhy ReadLevel
5 Critical Deployment DecisionsMake the right infrastructure choices for YOUR situationArchitecture
Agent ConfigurationProduction-grade safety, jailbreak detection, tool controlsDeep Dive
Knowledge GroundingVector embeddings, chunking strategies, semantic searchDeep Dive
Contoso Case Study (optional)See real-world enterprise requirementsContext

Last updated: 2026-09-28


🎓 Ready to Code?​

Pick a topic and dive in:

  1. 5 Critical Deployment Decisions → - Infrastructure choices for scale, cost & compliance
  2. Agent Configuration & Safety → - Building trustworthy agents
  3. Knowledge Grounding with RAG → - Ground agents in real data
  4. Security & Governance → - Identity, RBAC & compliance

Each guide is independent. Pick what you need.


Last updated: 2026-09-28
Questions? Explore the learning path or dive into specific topics.