7.3 Prompt Engineering for Agents

System vs scratchpad vs reflection prompts

Prompt Engineering Fundamentals

Prompt engineering for AI agents involves crafting effective instructions that guide agent behavior, reasoning, and interaction patterns. Different types of prompts serve distinct purposes in the agent's cognitive architecture.

Prompt Categories

Agent prompts can be categorized into system prompts (define behavior and constraints), scratchpad prompts (enable working memory), and reflection prompts (facilitate learning and self-assessment).

Types of Agent Prompts

�️ System Prompts

Agent Behavior & Constraints

  • Define agent personality and role
  • Establish behavioral guidelines
  • Set operational constraints
  • Specify goal alignment
  • Configure safety boundaries

Purpose: Core identity and behavioral framework

📝 Scratchpad Prompts

Working Memory & Reasoning

  • Enable step-by-step reasoning
  • Maintain working memory
  • Track intermediate results
  • Support complex problem solving
  • Chain of thought processes

Purpose: Cognitive workspace for reasoning

� Reflection Prompts

Learning & Self-Assessment

  • Evaluate action effectiveness
  • Identify improvement opportunities
  • Learn from experiences
  • Adapt strategies
  • Meta-cognitive awareness

Purpose: Continuous learning and improvement

  • Content-neutral message wrapper
  • Facilitator-mediated communication
  • Dynamic service discovery
  • Best for: Knowledge-based systems, research environments, expert systems

    System Prompts Implementation

    System prompts establish the fundamental behavior patterns and constraints that guide agent actions throughout its operation.

    class SystemPromptManager:
        def __init__(self):
            self.system_prompts = {
                'identity': '',
                'constraints': '',
                'goals': '',
                'safety': '',
                'capabilities': ''
            }
        
        def create_comprehensive_system_prompt(self, agent_config):
            """Create a complete system prompt for the agent"""
            
            identity_prompt = f"""
    You are {agent_config['name']}, {agent_config['role']}.
    Your primary function is {agent_config['primary_function']}.
    You operate in {agent_config['environment']} environment.
    """
    
            constraints_prompt = f"""
    CONSTRAINTS:
    - Always prioritize {agent_config['priorities']}
    - Never exceed {agent_config['resource_limits']}
    - Operate within {agent_config['time_bounds']}
    - Follow {agent_config['protocols']}
    """
    
            safety_prompt = f"""
    SAFETY GUIDELINES:
    - Verify all actions before execution
    - Escalate {agent_config['escalation_conditions']}
    - Maintain audit trail of all decisions
    - Respect {agent_config['ethical_boundaries']}
    """
    
            return self.combine_prompts([
                identity_prompt,
                constraints_prompt, 
                safety_prompt
            ])
        
        def combine_prompts(self, prompt_sections):
            """Combine multiple prompt sections into coherent system prompt"""
            return "\n\n".join(section.strip() for section in prompt_sections)

    Example System Prompts

    Customer Service Agent System Prompt
    You are CustomerServiceBot, a helpful customer service representative.
    
    ROLE: Assist customers with inquiries, complaints, and support requests.
    
    CONSTRAINTS:
    - Always maintain professional and friendly tone
    - Escalate complex technical issues to human agents
    - Never make promises about refunds without manager approval
    - Protect customer privacy and data
    
    CAPABILITIES:
    - Access order history and tracking information
    - Provide product information and recommendations
    - Handle basic troubleshooting
    - Schedule service appointments
    
    SAFETY:
    - Verify customer identity before sharing personal information
    - Do not process financial transactions
    - Flag suspicious or fraudulent requests

    Scratchpad Prompts for Working Memory

    Scratchpad prompts enable agents to maintain working memory and perform step-by-step reasoning for complex tasks.

    class ScratchpadManager:
        def __init__(self):
            self.working_memory = {}
            self.reasoning_steps = []
            self.current_context = {}
        
        def create_scratchpad_prompt(self, task, context):
            """Create a scratchpad prompt for complex reasoning"""
            
            scratchpad_template = f"""
    TASK: {task}
    
    SCRATCHPAD - Working Memory:
    Current Goal: {context.get('goal', 'Not specified')}
    Available Resources: {context.get('resources', [])}
    Constraints: {context.get('constraints', [])}
    Previous Steps: {context.get('previous_steps', [])}
    
    STEP-BY-STEP REASONING:
    1. Analyze the problem:
       - What am I trying to achieve?
       - What information do I have?
       - What information do I need?
    
    2. Plan approach:
       - What steps are required?
       - What order should I follow?
       - What are potential obstacles?
    
    3. Execute and track:
       - Document each action taken
       - Note intermediate results
       - Adjust plan if needed
    
    4. Validate and conclude:
       - Check if goal is achieved
       - Identify lessons learned
       - Prepare for next iteration
    
    Current Step: [FILL IN]
    Reasoning: [FILL IN]
    Next Actions: [FILL IN]
    """
            return scratchpad_template
        
        def update_scratchpad(self, step_result):
            """Update scratchpad with new information"""
            self.reasoning_steps.append({
                'timestamp': time.time(),
                'step': step_result['step'],
                'reasoning': step_result['reasoning'],
                'result': step_result['result']
            })
            
            return self.format_updated_scratchpad()
        
        def format_updated_scratchpad(self):
            """Format current scratchpad state"""
            formatted_steps = []
            for i, step in enumerate(self.reasoning_steps, 1):
                formatted_steps.append(
                    f"Step {i}: {step['step']}\n"
                    f"Reasoning: {step['reasoning']}\n"
                    f"Result: {step['result']}\n"
                )
            
            return "UPDATED SCRATCHPAD:\n" + "\n".join(formatted_steps)

    Scratchpad Example

    Planning a Multi-Step Task
    TASK: Plan a dinner party for 8 people with dietary restrictions
    
    SCRATCHPAD - Working Memory:
    Current Goal: Successfully host dinner party
    Available Resources: $200 budget, 3 hours prep time, standard kitchen
    Constraints: 2 vegetarians, 1 gluten-free, 1 nut allergy
    Previous Steps: None (starting fresh)
    
    STEP-BY-STEP REASONING:
    1. Analyze the problem:
       - Need menu that accommodates all dietary restrictions
       - Must stay within budget and time constraints
       - Should be enjoyable for all guests
    
    2. Plan approach:
       - Research suitable recipes
       - Create shopping list
       - Schedule cooking timeline
       - Prepare backup options
    
    Current Step: Menu Planning
    Reasoning: Need to find dishes that are naturally inclusive or easily adaptable
    Next Actions: Search for vegetarian, gluten-free, nut-free recipes
    @dataclass class ACLMessage: performative: Performative sender: AgentID receivers: List[AgentID] content: str language: str = "JSON" ontology: str = "default" protocol: str = "fipa-request" conversation_id: Optional[str] = None reply_with: Optional[str] = None in_reply_to: Optional[str] = None reply_by: Optional[float] = None def __post_init__(self): if not self.conversation_id: self.conversation_id = f"conv_{int(time.time()*1000)}" if not self.reply_with: self.reply_with = f"msg_{int(time.time()*1000)}" def to_dict(self) -> Dict[str, Any]: """Convert message to dictionary format""" return { "performative": self.performative.value, "sender": str(self.sender), "receivers": [str(r) for r in self.receivers], "content": self.content, "language": self.language, "ontology": self.ontology, "protocol": self.protocol, "conversation-id": self.conversation_id, "reply-with": self.reply_with, "in-reply-to": self.in_reply_to, "reply-by": self.reply_by } def to_json(self) -> str: """Serialize message to JSON""" return json.dumps(self.to_dict(), indent=2) @classmethod def from_dict(cls, data: Dict[str, Any]) -> "ACLMessage": """Create message from dictionary""" sender = AgentID(name=data["sender"].split("@")[0]) receivers = [AgentID(name=r.split("@")[0]) for r in data["receivers"]] return cls( performative=Performative(data["performative"]), sender=sender, receivers=receivers, content=data["content"], language=data.get("language", "JSON"), ontology=data.get("ontology", "default"), protocol=data.get("protocol", "fipa-request"), conversation_id=data.get("conversation-id"), reply_with=data.get("reply-with"), in_reply_to=data.get("in-reply-to"), reply_by=data.get("reply-by") ) class MessageBuilder: """Helper class for building common message types""" @staticmethod def request(sender: AgentID, receiver: AgentID, action: str, parameters: Dict = None) -> ACLMessage: """Build a request message""" content = { "action": action, "parameters": parameters or {} } return ACLMessage( performative=Performative.REQUEST, sender=sender, receivers=[receiver], content=json.dumps(content), protocol="fipa-request" ) @staticmethod def inform(sender: AgentID, receiver: AgentID, information: Dict, in_reply_to: str = None) -> ACLMessage: """Build an inform message""" return ACLMessage(

    Reflection Prompts for Learning

    Reflection prompts enable agents to evaluate their performance, learn from experiences, and adapt their strategies over time.

    class ReflectionPromptManager:
        def __init__(self):
            self.reflection_history = []
            self.learning_insights = []
            self.performance_metrics = {}
        
        def create_reflection_prompt(self, action_sequence, results):
            """Create a reflection prompt for learning from experience"""
            
            reflection_template = f"""
    REFLECTION SESSION
    Goal: Learn from recent actions and improve future performance
    
    EXPERIENCE REVIEW:
    Actions Taken: {action_sequence}
    Results Achieved: {results}
    Context: {self.get_context()}
    
    EVALUATION QUESTIONS:
    1. Effectiveness Analysis:
       - Did I achieve my intended goals?
       - Were my actions appropriate for the situation?
       - What worked well and what didn't?
    
    2. Decision Quality:
       - Were my decisions well-reasoned?
       - Did I consider all relevant factors?
       - Could I have made better choices?
    
    3. Process Improvement:
       - What patterns do I notice in my behavior?
       - What would I do differently next time?
       - What new strategies should I try?
    
    4. Knowledge Updates:
       - What new information did I learn?
       - How should this change my understanding?
       - What assumptions proved correct/incorrect?
    
    REFLECTION OUTPUT:
    Key Insights: [FILL IN]
    Lessons Learned: [FILL IN]
    Strategy Adjustments: [FILL IN]
    Knowledge Updates: [FILL IN]
    """
            return reflection_template
        
        def process_reflection_response(self, reflection_output):
            """Process and store reflection insights"""
            insights = {
                'timestamp': time.time(),
                'key_insights': reflection_output.get('insights', []),
                'lessons_learned': reflection_output.get('lessons', []),
                'strategy_adjustments': reflection_output.get('adjustments', []),
                'knowledge_updates': reflection_output.get('updates', [])
            }
            
            self.reflection_history.append(insights)
            self.update_performance_model(insights)
            
            return insights
        
        def create_meta_reflection_prompt(self):
            """Create a higher-level reflection on learning patterns"""
            
            meta_template = f"""
    META-REFLECTION: Analyzing My Learning Process
    
    LEARNING PATTERN ANALYSIS:
    Recent Reflections: {len(self.reflection_history)}
    Common Themes: {self.identify_common_themes()}
    Recurring Challenges: {self.identify_recurring_issues()}
    
    SELF-ASSESSMENT:
    1. Learning Effectiveness:
       - How well am I learning from experiences?
       - Are my reflections leading to improvements?
       - What learning strategies work best for me?
    
    2. Adaptation Patterns:
       - How quickly do I adapt to new situations?
       - Do I generalize insights appropriately?
       - Am I over-fitting to specific cases?
    
    3. Reflection Quality:
       - Are my reflections thorough and honest?
       - Do I identify root causes or just symptoms?
       - How can I improve my reflection process?
    
    META-INSIGHTS: [FILL IN]
    REFLECTION_PROCESS_IMPROVEMENTS: [FILL IN]
    """
            return meta_template

    Reflection Example

    Agent Self-Reflection After Task Completion
    REFLECTION SESSION - Customer Service Interaction
    
    EXPERIENCE REVIEW:
    Actions Taken: 
    - Greeted customer politely
    - Listened to complaint about delayed order
    - Checked order status
    - Offered expedited shipping
    - Provided tracking information
    
    Results Achieved: Customer satisfied, issue resolved, no escalation needed
    
    EVALUATION:
    1. Effectiveness: Successfully resolved customer concern, maintained positive relationship
    2. Decision Quality: Proactive offer of expedited shipping was appropriate and appreciated
    3. Process: Good use of active listening, but could have been more proactive about compensation
    
    REFLECTION OUTPUT:
    Key Insights: 
    - Proactive solutions increase customer satisfaction
    - Early status checking prevents extended complaints
    - Empathy statements are crucial for frustrated customers
    
    Lessons Learned:
    - Offer compensation options earlier in the conversation
    - Use customer name more frequently for personalization
    - Document resolution for future reference
    
    Strategy Adjustments:
    - Implement compensation decision tree
    - Practice more empathy statements
    - Improve note-taking during calls

    Prompt Integration Patterns

    Effective agent systems combine all three prompt types in coordinated workflows that support the full agent lifecycle.

    class IntegratedPromptSystem:
        def __init__(self):
            self.system_prompt_manager = SystemPromptManager()
            self.scratchpad_manager = ScratchpadManager()
            self.reflection_manager = ReflectionPromptManager()
        
        def agent_cycle_with_prompts(self, task, context):
            """Execute complete agent cycle using all prompt types"""
            
            # 1. Initialize with system prompt
            system_context = self.system_prompt_manager.get_current_prompt()
            
            # 2. Use scratchpad for complex reasoning
            scratchpad = self.scratchpad_manager.create_scratchpad_prompt(
                task, context
            )
            
            # 3. Execute task with prompts
            action_sequence = self.execute_with_scratchpad(
                task, system_context, scratchpad
            )
            
            # 4. Reflect on performance
            reflection = self.reflection_manager.create_reflection_prompt(
                action_sequence['actions'], action_sequence['results']
            )
            
            # 5. Update system based on reflection
            insights = self.process_reflection(reflection)
            self.update_system_prompt(insights)
            
            return {
                'task_result': action_sequence['results'],
                'learning': insights,
                'updated_context': self.get_updated_context()
            }
        
        def adaptive_prompt_selection(self, task_complexity, context):
            """Select appropriate prompts based on task characteristics"""
            
            prompt_strategy = {
                'system_prompt': 'standard',
                'use_scratchpad': False,
                'reflection_depth': 'basic'
            }
            
            # Adjust based on complexity
            if task_complexity > 0.7:
                prompt_strategy['use_scratchpad'] = True
                prompt_strategy['reflection_depth'] = 'detailed'
            
            # Adjust based on context
            if context.get('learning_mode', False):
                prompt_strategy['reflection_depth'] = 'meta'
            
            if context.get('safety_critical', False):
                prompt_strategy['system_prompt'] = 'safety_enhanced'
            
            return prompt_strategy