"""
Pattern 191: Prompt Engineering Pattern
Systematic design and optimization of prompts for LLMs.
Implements multiple prompt engineering techniques for effective LLM interaction.
"""
from typing import Dict, Any, List, Optional, Callable
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
class PromptTechnique(Enum):
"""Prompt engineering techniques."""
ZERO_SHOT = "zero_shot"
FEW_SHOT = "few_shot"
CHAIN_OF_THOUGHT = "chain_of_thought"
ROLE_BASED = "role_based"
TEMPLATE = "template"
STRUCTURED = "structured"
@dataclass
class PromptExample:
"""Example for few-shot learning."""
input: str
output: str
explanation: Optional[str] = None
@dataclass
class PromptTemplate:
"""Prompt template with variables."""
name: str
technique: PromptTechnique
system_message: str
user_template: str
variables: List[str]
examples: List[PromptExample] = field(default_factory=list)
output_format: Optional[str] = None
@dataclass
class PromptResult:
"""Result of prompt execution."""
prompt_used: str
technique: PromptTechnique
response: str
metadata: Dict[str, Any] = field(default_factory=dict)
timestamp: datetime = field(default_factory=datetime.now)
class PromptEngineer:
"""Engineer with multiple prompt techniques."""
def __init__(self, model_name: str = "gpt-4", temperature: float = 0.7):
self.llm = ChatOpenAI(model=model_name, temperature=temperature)
self.templates: Dict[str, PromptTemplate] = {}
self.results: List[PromptResult] = []
def create_zero_shot_prompt(self, task: str, context: Optional[str] = None) -> str:
"""Create zero-shot prompt."""
if context:
return f"Context: {context}\n\nTask: {task}\n\nProvide a clear and comprehensive answer."
return f"Task: {task}\n\nProvide a clear and comprehensive answer."
def create_few_shot_prompt(self, task: str, examples: List[PromptExample]) -> str:
"""Create few-shot prompt with examples."""
prompt_parts = ["Here are some examples:\n"]
for i, ex in enumerate(examples, 1):
prompt_parts.append(f"\nExample {i}:")
prompt_parts.append(f"Input: {ex.input}")
prompt_parts.append(f"Output: {ex.output}")
if ex.explanation:
prompt_parts.append(f"Why: {ex.explanation}")
prompt_parts.append(f"\n\nNow, apply the same pattern:")
prompt_parts.append(f"Input: {task}")
prompt_parts.append("Output:")
return "\n".join(prompt_parts)
def create_chain_of_thought_prompt(self, task: str) -> str:
"""Create chain-of-thought prompt."""
return (f"{task}\n\n"
f"Let's approach this step-by-step:\n"
f"1. First, identify the key components\n"
f"2. Then, analyze the relationships\n"
f"3. Finally, synthesize the answer\n\n"
f"Think through each step carefully:")
def create_role_based_prompt(self, task: str, role: str, expertise: List[str]) -> str:
"""Create role-based prompt."""
expertise_text = ", ".join(expertise)
return (f"You are a {role} with expertise in {expertise_text}. "
f"Use your specialized knowledge to address this:\n\n{task}")
def execute_prompt(self, prompt: str, technique: PromptTechnique,
system_message: Optional[str] = None) -> PromptResult:
"""Execute prompt and return result."""
messages = []
if system_message:
messages.append(("system", system_message))
messages.append(("human", prompt))
chat_prompt = ChatPromptTemplate.from_messages(messages)
chain = chat_prompt | self.llm | StrOutputParser()
response = chain.invoke({})
result = PromptResult(
prompt_used=prompt,
technique=technique,
response=response,
metadata={"system_message": system_message}
)
self.results.append(result)
return result
def register_template(self, template: PromptTemplate):
"""Register a reusable prompt template."""
self.templates[template.name] = template
def use_template(self, template_name: str, **kwargs) -> PromptResult:
"""Use a registered template with variables."""
if template_name not in self.templates:
raise ValueError(f"Template '{template_name}' not found")
template = self.templates[template_name]
# Substitute variables
prompt = template.user_template
for var in template.variables:
if var in kwargs:
prompt = prompt.replace(f"{{{var}}}", str(kwargs[var]))
# Add examples if few-shot
if template.technique == PromptTechnique.FEW_SHOT and template.examples:
prompt = self.create_few_shot_prompt(prompt, template.examples)
# Add output format if specified
if template.output_format:
prompt += f"\n\nOutput format: {template.output_format}"
return self.execute_prompt(prompt, template.technique, template.system_message)
class PromptEngineeringPattern:
"""
Prompt Engineering Pattern - Systematic prompt design and optimization.
Provides multiple techniques for crafting effective prompts including
zero-shot, few-shot, chain-of-thought, and role-based prompting.
"""
def __init__(self, model_name: str = "gpt-4"):
self.engineer = PromptEngineer(model_name)
self.technique_usage: Dict[PromptTechnique, int] = {t: 0 for t in PromptTechnique}
def zero_shot(self, task: str, context: Optional[str] = None) -> PromptResult:
"""Execute zero-shot prompting."""
prompt = self.engineer.create_zero_shot_prompt(task, context)
result = self.engineer.execute_prompt(prompt, PromptTechnique.ZERO_SHOT)
self.technique_usage[PromptTechnique.ZERO_SHOT] += 1
return result
def few_shot(self, task: str, examples: List[PromptExample]) -> PromptResult:
"""Execute few-shot prompting."""
prompt = self.engineer.create_few_shot_prompt(task, examples)
result = self.engineer.execute_prompt(prompt, PromptTechnique.FEW_SHOT)
self.technique_usage[PromptTechnique.FEW_SHOT] += 1
return result
def chain_of_thought(self, task: str) -> PromptResult:
"""Execute chain-of-thought prompting."""
prompt = self.engineer.create_chain_of_thought_prompt(task)
result = self.engineer.execute_prompt(
prompt,
PromptTechnique.CHAIN_OF_THOUGHT,
"You are a careful thinker who explains reasoning step-by-step."
)
self.technique_usage[PromptTechnique.CHAIN_OF_THOUGHT] += 1
return result
def role_based(self, task: str, role: str, expertise: List[str]) -> PromptResult:
"""Execute role-based prompting."""
prompt = self.engineer.create_role_based_prompt(task, role, expertise)
result = self.engineer.execute_prompt(prompt, PromptTechnique.ROLE_BASED)
self.technique_usage[PromptTechnique.ROLE_BASED] += 1
return result
def create_template(self, name: str, technique: PromptTechnique,
system_message: str, user_template: str,
variables: List[str], **kwargs) -> PromptTemplate:
"""Create and register a prompt template."""
template = PromptTemplate(
name=name,
technique=technique,
system_message=system_message,
user_template=user_template,
variables=variables,
examples=kwargs.get('examples', []),
output_format=kwargs.get('output_format')
)
self.engineer.register_template(template)
return template
def get_statistics(self) -> Dict[str, Any]:
"""Get usage statistics."""
total = sum(self.technique_usage.values())
return {
"total_prompts": total,
"techniques_used": {t.value: count for t, count in self.technique_usage.items() if count > 0},
"unique_templates": len(self.engineer.templates),
"avg_response_length": sum(len(r.response) for r in self.engineer.results) / max(len(self.engineer.results), 1)
}
# Example usage
if __name__ == "__main__":
print("=== Prompt Engineering Pattern Demo ===\n")
# Create pattern
print("1. Creating prompt engineering pattern...")
pattern = PromptEngineeringPattern()
# Test zero-shot
print(f"\n{'='*70}")
print("š Zero-Shot Prompting")
print(f"{'='*70}\n")
result = pattern.zero_shot(
"Explain the concept of 'emergence' in complex systems",
context="Focus on practical examples"
)
print(f"Task: Explain emergence")
print(f"Technique: {result.technique.value}")
print(f"Response: {result.response[:200]}...\n")
# Test few-shot
print(f"\n{'='*70}")
print("š Few-Shot Prompting")
print(f"{'='*70}\n")
examples = [
PromptExample(
input="What is photosynthesis?",
output="Photosynthesis is the process plants use to convert light energy into chemical energy (glucose).",
explanation="Simple, clear definition with key components"
),
PromptExample(
input="What is mitosis?",
output="Mitosis is cell division that produces two identical daughter cells from one parent cell.",
explanation="Concise explanation of the core process"
)
]
result = pattern.few_shot("What is osmosis?", examples)
print(f"Task: What is osmosis?")
print(f"Technique: {result.technique.value}")
print(f"Examples provided: {len(examples)}")
print(f"Response: {result.response[:200]}...\n")
# Test chain-of-thought
print(f"\n{'='*70}")
print("š Chain-of-Thought Prompting")
print(f"{'='*70}\n")
result = pattern.chain_of_thought(
"If a store has a 20% discount and then adds 8% sales tax, "
"how much would a $50 item cost?"
)
print(f"Task: Calculate final price with discount and tax")
print(f"Technique: {result.technique.value}")
print(f"Response: {result.response[:300]}...\n")
# Test role-based
print(f"\n{'='*70}")
print("š Role-Based Prompting")
print(f"{'='*70}\n")
result = pattern.role_based(
"How should I optimize database queries for a high-traffic application?",
role="Senior Database Administrator",
expertise=["SQL optimization", "indexing strategies", "query planning"]
)
print(f"Task: Database optimization advice")
print(f"Technique: {result.technique.value}")
print(f"Role: Senior Database Administrator")
print(f"Response: {result.response[:200]}...\n")
# Create and use template
print(f"\n{'='*70}")
print("š Template-Based Prompting")
print(f"{'='*70}\n")
template = pattern.create_template(
name="code_review",
technique=PromptTechnique.STRUCTURED,
system_message="You are an expert code reviewer focusing on best practices.",
user_template="Review this {language} code for {aspect}:\n\n{code}",
variables=["language", "aspect", "code"],
output_format="1. Issues found\n2. Recommendations\n3. Severity"
)
result = pattern.engineer.use_template(
"code_review",
language="Python",
aspect="performance and readability",
code="def calc(x):\n return [i*2 for i in range(x)]"
)
print(f"Template: {template.name}")
print(f"Response: {result.response[:200]}...\n")
# Statistics
print(f"\n{'='*70}")
print("š Usage Statistics")
print(f"{'='*70}")
stats = pattern.get_statistics()
print(f" Total prompts executed: {stats['total_prompts']}")
print(f" Unique templates created: {stats['unique_templates']}")
print(f" Avg response length: {stats['avg_response_length']:.0f} chars")
print(f"\n Techniques used:")
for technique, count in stats['techniques_used'].items():
print(f" - {technique}: {count} times")
print("\nā Prompt engineering pattern demonstrated multiple techniques!")
Agentic Architecture Pattern: Prompt Engineering
Pattern 191: 191 Prompt Engineering Pattern – Line-by-Line Explanation
Overview
Pattern 191: Prompt Engineering Pattern
Systematic design and optimization of prompts for LLMs. Implements multiple prompt engineering techniques for effective LLM interaction.
Code Structure Analysis
File Information
- Pattern Number: 191
- Pattern Name: 191 Prompt Engineering Pattern
- File Path:
patterns\llm_specific\191_prompt_engineering_pattern.py - Total Lines: 341
Detailed Code Explanation
Module Docstring
"""
Pattern 191: Prompt Engineering Pattern
Systematic design and optimization of prompts for LLMs.
Implements multiple prompt engineering techniques for effective LLM interaction.
"""
Explanation: This module docstring describes the purpose and key features of the 191 Prompt Engineering Pattern pattern.
Imports Section
from typing import Dict, Any, List, Optional, Callable
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI # First 20 imports shown
Explanation: The module imports necessary dependencies:
– from typing import Dict, Any, List, Optional, Callable: Type hints for better code documentation
– from dataclasses import dataclass, field: Data class decorators for clean data structures
– from datetime import datetime: Date and time utilities
– from enum import Enum: Enumeration support for fixed sets of values
– from langchain_core.prompts import ChatPromptTemplate, PromptTemplate: LangChain framework integration
– from langchain_core.output_parsers import StrOutputParser: LangChain framework integration
– from langchain_openai import ChatOpenAI: LangChain framework integration
Enumerations
PromptTechnique (Line 17)
class PromptTechnique(Enum):
ZERO_SHOT
FEW_SHOT
CHAIN_OF_THOUGHT
ROLE_BASED
TEMPLATE
STRUCTURED
Purpose: Prompt engineering techniques.
Values:
– ZERO_SHOT: Represents zero shot
– FEW_SHOT: Represents few shot
– CHAIN_OF_THOUGHT: Represents chain of thought
– ROLE_BASED: Represents role based
– TEMPLATE: Represents template
– STRUCTURED: Represents structured
Classes
PromptTechnique (Line 17)
Description: Prompt engineering techniques.
PromptExample (Line 28)
Description: Example for few-shot learning.
PromptTemplate (Line 36)
Description: Prompt template with variables.
PromptResult (Line 48)
Description: Result of prompt execution.
PromptEngineer (Line 57)
Description: Engineer with multiple prompt techniques.
Methods:
__init__ (Line 60)
def __init__(self, model_name, temperature):
"""No method docstring."""
Purpose: No method docstring.
Parameters:
– self: Instance reference
– model_name: LLM model to use (e.g., “gpt-4”)
– temperature: Randomness in LLM responses (0.0-1.0)
create_zero_shot_prompt (Line 65)
def create_zero_shot_prompt(self, task, context):
"""Create zero-shot prompt."""
Purpose: Create zero-shot prompt.
Parameters:
– self: Instance reference
– task: Parameter for task
– context: Parameter for context
create_few_shot_prompt (Line 71)
def create_few_shot_prompt(self, task, examples):
"""Create few-shot prompt with examples."""
Purpose: Create few-shot prompt with examples.
Parameters:
– self: Instance reference
– task: Parameter for task
– examples: Parameter for examples
create_chain_of_thought_prompt (Line 88)
def create_chain_of_thought_prompt(self, task):
"""Create chain-of-thought prompt."""
Purpose: Create chain-of-thought prompt.
Parameters:
– self: Instance reference
– task: Parameter for task
create_role_based_prompt (Line 97)
def create_role_based_prompt(self, task, role, expertise):
"""Create role-based prompt."""
Purpose: Create role-based prompt.
Parameters:
– self: Instance reference
– task: Parameter for task
– role: Parameter for role
– expertise: Parameter for expertise
execute_prompt (Line 103)
def execute_prompt(self, prompt, technique, system_message):
"""Execute prompt and return result."""
Purpose: Execute prompt and return result.
Parameters:
– self: Instance reference
– prompt: Parameter for prompt
– technique: Parameter for technique
– system_message: Parameter for system_message
register_template (Line 128)
def register_template(self, template):
"""Register a reusable prompt template."""
Purpose: Register a reusable prompt template.
Parameters:
– self: Instance reference
– template: Parameter for template
use_template (Line 132)
def use_template(self, template_name):
"""Use a registered template with variables."""
Purpose: Use a registered template with variables.
Parameters:
– self: Instance reference
– template_name: Parameter for template_name
PromptEngineeringPattern (Line 156)
Description: Prompt Engineering Pattern – Systematic prompt design and optimization.
Provides multiple techniques for crafting effective prompts including zero-shot, few-shot, chain-of-thought, and role-based prompting.
Methods:
__init__ (Line 164)
def __init__(self, model_name):
"""No method docstring."""
Purpose: No method docstring.
Parameters:
– self: Instance reference
– model_name: LLM model to use (e.g., “gpt-4”)
zero_shot (Line 168)
def zero_shot(self, task, context):
"""Execute zero-shot prompting."""
Purpose: Execute zero-shot prompting.
Parameters:
– self: Instance reference
– task: Parameter for task
– context: Parameter for context
few_shot (Line 175)
def few_shot(self, task, examples):
"""Execute few-shot prompting."""
Purpose: Execute few-shot prompting.
Parameters:
– self: Instance reference
– task: Parameter for task
– examples: Parameter for examples
chain_of_thought (Line 182)
def chain_of_thought(self, task):
"""Execute chain-of-thought prompting."""
Purpose: Execute chain-of-thought prompting.
Parameters:
– self: Instance reference
– task: Parameter for task
role_based (Line 193)
def role_based(self, task, role, expertise):
"""Execute role-based prompting."""
Purpose: Execute role-based prompting.
Parameters:
– self: Instance reference
– task: Parameter for task
– role: Parameter for role
– expertise: Parameter for expertise
create_template (Line 200)
def create_template(self, name, technique, system_message, user_template, variables):
"""Create and register a prompt template."""
Purpose: Create and register a prompt template.
Parameters:
– self: Instance reference
– name: Identifier or label
– technique: Parameter for technique
– system_message: Parameter for system_message
– user_template: Parameter for user_template
– variables: Parameter for variables
get_statistics (Line 216)
def get_statistics(self):
"""Get usage statistics."""
Purpose: Get usage statistics.
Parameters:
– self: Instance reference
Design Patterns Used
- Strategy Pattern: Different execution strategies for various scenarios
- State Pattern: Managing different states in the workflow
- Chain of Responsibility: Sequential processing through workflow nodes
- Observer Pattern: Tracking and monitoring pattern execution
- Factory Pattern: Creating instances with proper configuration
Usage Example
# Initialize the pattern
pattern = PromptTechnique(name="example", model_name="gpt-4")
# Configure and execute
result = pattern.execute(data={"key": "value"})
# Check results
print(result)
Key Concepts
- LLM Integration: Uses LangChain/OpenAI for intelligent decision-making
- Workflow Orchestration: LangGraph manages execution flow through nodes
- State Management: TypedDict defines workflow state structure
- Error Handling: Comprehensive error handling and fallback mechanisms
- Extensibility: Designed for easy customization and extension
Extension Points
This pattern can be extended by: 1. Adding custom workflow nodes 2. Implementing additional validation logic 3. Integrating with external services 4. Customizing LLM prompts and responses 5. Adding monitoring and logging capabilities
Leave a Reply