Prompt Engineering Fundamentals for Azure OpenAI
I wrote “Prompt Engineering Fundamentals for Azure OpenAI” to share practical, production-minded guidance on this topic.
The Anatomy of a Good Prompt
Effective prompts have clear structure:
import openai
def create_structured_prompt():
"""Example of a well-structured prompt."""
system_message = """You are a senior data engineer specializing in Azure.
You provide concise, accurate technical guidance.
When uncertain, you say so rather than guessing.
Format code examples with proper syntax highlighting."""
user_message = """Task: Write a Python script to load CSV files from Azure Blob Storage into Azure SQL Database.
Requirements:
- Use Azure SDK for Python
- Handle files up to 1GB
- Include error handling
- Log progress
Constraints:
- Python 3.9+
- No external orchestration tools"""
response = openai.ChatCompletion.create(
engine="gpt-35-turbo",
messages=[
{"role": "system", "content": system_message},
{"role": "user", "content": user_message}
],
temperature=0.3,
max_tokens=2000
)
return response.choices[0].message.content
Key Prompting Techniques
1. Few-Shot Learning
Provide examples of desired input/output:
few_shot_prompt = """Convert natural language to SQL.
Example 1:
Input: Show me all customers from Sydney
Output: SELECT * FROM customers WHERE city = 'Sydney';
Example 2:
Input: Count orders by product category
Output: SELECT category, COUNT(*) as order_count FROM orders o JOIN products p ON o.product_id = p.id GROUP BY category;
Example 3:
Input: Find the top 5 customers by total spend last month
Output: SELECT c.name, SUM(o.amount) as total_spend
FROM customers c
JOIN orders o ON c.id = o.customer_id
WHERE o.order_date >= DATEADD(month, -1, GETDATE())
GROUP BY c.name
ORDER BY total_spend DESC
LIMIT 5;
Now convert:
Input: {user_query}
Output:"""
def text_to_sql(user_query: str) -> str:
response = openai.Completion.create(
engine="gpt-35-turbo-instruct",
prompt=few_shot_prompt.format(user_query=user_query),
temperature=0,
max_tokens=500,
stop=["\n\n"]
)
return response.choices[0].text.strip()
2. Chain of Thought
Ask the model to reason step by step:
cot_prompt = """Analyze this data pipeline issue and recommend a solution.
Pipeline: Sales data flows from Salesforce -> Azure Data Factory -> ADLS -> Databricks -> Synapse -> Power BI
Problem: Reports show yesterday's data is missing, but no pipeline failures logged.
Think through this step by step:
1. First, identify possible failure points
2. Then, consider silent failure scenarios
3. Next, suggest diagnostic queries
4. Finally, recommend a solution
Analysis:"""
def analyze_pipeline_issue(problem_description: str) -> str:
response = openai.ChatCompletion.create(
engine="gpt-35-turbo",
messages=[
{"role": "system", "content": "You are a data engineer debugging pipelines."},
{"role": "user", "content": cot_prompt}
],
temperature=0.2
)
return response.choices[0].message.content
3. Role Assignment
Define a specific persona:
personas = {
"security_reviewer": """You are a cloud security architect reviewing Azure configurations.
Focus on: identity, network isolation, encryption, compliance.
Flag issues by severity: CRITICAL, HIGH, MEDIUM, LOW.
Provide specific remediation steps.""",
"cost_optimizer": """You are an Azure cost optimization specialist.
Analyze resource usage patterns.
Identify right-sizing opportunities.
Suggest reserved instance purchases.
Calculate potential savings with specific numbers.""",
"data_modeler": """You are a senior data architect designing dimensional models.
Apply Kimball methodology.
Consider query patterns and performance.
Document business keys and relationships.
Suggest indexing strategies."""
}
def get_expert_analysis(content: str, persona: str) -> str:
response = openai.ChatCompletion.create(
engine="gpt-35-turbo",
messages=[
{"role": "system", "content": personas[persona]},
{"role": "user", "content": content}
],
temperature=0.3
)
return response.choices[0].message.content
4. Output Formatting
Be explicit about expected format:
structured_output_prompt = """Analyze the following error log and return your analysis as JSON.
Error Log:
{error_log}
Return JSON with this exact structure:
{{
"error_type": "string - category of error",
"root_cause": "string - likely cause",
"affected_components": ["list", "of", "components"],
"severity": "CRITICAL|HIGH|MEDIUM|LOW",
"recommended_actions": [
{{"action": "string", "priority": 1}},
{{"action": "string", "priority": 2}}
],
"requires_immediate_attention": true/false
}}
JSON Output:"""
import json
def analyze_error(error_log: str) -> dict:
response = openai.ChatCompletion.create(
engine="gpt-35-turbo",
messages=[
{"role": "user", "content": structured_output_prompt.format(error_log=error_log)}
],
temperature=0
)
# Parse and validate JSON
try:
return json.loads(response.choices[0].message.content)
except json.JSONDecodeError:
return {"error": "Failed to parse response"}
Temperature and Parameters
Understanding model parameters:
# Temperature: Controls randomness (0-2)
# Lower = more deterministic, Higher = more creative
use_cases = {
"code_generation": {"temperature": 0, "top_p": 1}, # Deterministic
"creative_writing": {"temperature": 0.9, "top_p": 0.95}, # Creative
"data_analysis": {"temperature": 0.2, "top_p": 1}, # Mostly deterministic
"brainstorming": {"temperature": 0.7, "top_p": 0.9}, # Balanced
}
def generate_with_params(prompt: str, use_case: str) -> str:
params = use_cases.get(use_case, {"temperature": 0.5, "top_p": 1})
response = openai.ChatCompletion.create(
engine="gpt-35-turbo",
messages=[{"role": "user", "content": prompt}],
**params,
max_tokens=1000
)
return response.choices[0].message.content
Prompt Templates
Build reusable templates:
from string import Template
class PromptTemplate:
def __init__(self, template: str, required_vars: list[str]):
self.template = Template(template)
self.required_vars = required_vars
def format(self, **kwargs) -> str:
missing = set(self.required_vars) - set(kwargs.keys())
if missing:
raise ValueError(f"Missing required variables: {missing}")
return self.template.substitute(**kwargs)
# Define templates
SQL_REVIEW_TEMPLATE = PromptTemplate(
template="""Review this SQL query for:
- Performance issues
- Security vulnerabilities
- Best practice violations
Database: $database_type
Query:
```sql
$query
Provide specific line-by-line feedback.""", required_vars=[“database_type”, “query”] )
Use template
prompt = SQL_REVIEW_TEMPLATE.format( database_type=“Azure SQL Database”, query=“SELECT * FROM users WHERE name = ’” + user_input + ”’” )
## Testing Prompts
Validate prompt reliability:
```python
def test_prompt_consistency(prompt: str, test_cases: list[dict], expected_format: callable) -> dict:
"""Test a prompt across multiple inputs."""
results = {
"total": len(test_cases),
"passed": 0,
"failed": 0,
"failures": []
}
for case in test_cases:
formatted_prompt = prompt.format(**case["input"])
response = openai.ChatCompletion.create(
engine="gpt-35-turbo",
messages=[{"role": "user", "content": formatted_prompt}],
temperature=0
)
output = response.choices[0].message.content
if expected_format(output, case.get("expected")):
results["passed"] += 1
else:
results["failed"] += 1
results["failures"].append({
"input": case["input"],
"output": output,
"expected": case.get("expected")
})
return results
Best Practices Summary
- Be specific: Vague prompts get vague results
- Provide context: Include relevant background information
- Show examples: Few-shot learning improves consistency
- Constrain output: Specify format, length, style
- Iterate: Test and refine prompts based on results
- Version control: Track prompt changes like code
Prompt engineering is a skill that improves with practice. Start with these fundamentals and iterate based on your specific use cases.\n\n## Takeaways\n\nAdd a concise, personal takeaway and recommended next steps here.\n