#4635 Critique Agent Update to Other AI Agent System Instructions

#4635 Critique Agent Update to Other AI Agent System Instructions

#4635 Given that AI Agents have system instructions, can a follow-up critical agent suggest changes to the previous agent's instructions in an attempt to improve its response?

Yes, absolutely. In multi-agent orchestration architectures, having an Evaluator/Critic Agent dynamically modify or refine the System Instructions (Prompts) of a Worker/Generator Agent is a core design pattern for iterative improvement.

This approach goes beyond simple output feedback (e.g., "Rewrite this to be shorter") by addressing the root cause of an inadequate output: the operational framing and rules governing the generating agent.

Here is how this dynamic works in practice, along with key design considerations:

1. The Meta-Prompting / Prompt Optimization Loop

Rather than having the Critic directly fix the Generator's final response, the workflow operates in a meta-feedback loop:

  1. Generation: Agent A (Worker) receives its current system_instruction + user_prompt and generates Output_v1.

  2. Evaluation: Agent B (Critic) evaluates Output_v1 against standard criteria (e.g., accuracy, tone, constraint adherence, completeness).

  3. Instruction Mutation: If Output_v1 fails criteria, Agent B generates a updated/refined system_instruction specifically designed to eliminate the gaps observed in Output_v1.

  4. Re-Execution: Agent A is re-instantiated or called using the newly modified system instruction to generate Output_v2.

2. Dynamic Refinement Architectures

Depending on your pipeline state management (e.g., using frameworks like LangGraph, CrewAI, or custom state machines), you can implement this pattern in two main ways:

A. Ephemeral / In-Flight Revision (Session-Bound)

  • Goal: Fix a specific output for the current task session.

  • Mechanism: The Critic identifies missing constraints in the Worker’s execution (e.g., "Agent A forgot to output valid JSON") and amends Agent A's system prompt with explicit guardrails for the immediate retry loop. Once the task completes, the modified system prompt is discarded.

B. Persistent / Evolutionary Meta-Prompting

  • Goal: Permanently optimize system instructions across repeated standard operations.

  • Mechanism: The Critic maintains a prompt template store. When systematically lower evaluation scores are detected over multiple runs, the Critic proposes structural revisions to the baseline system instructions. (This mimics techniques like DSPy or automated prompt optimization algorithms).

3. Recommended Implementation Guardrails

Allowing agents to rewrite instructions for other agents introduces risks like drift, infinite loops, or rule degradation. Effective implementations usually incorporate these safety mechanisms:

  • Instruction Immutable Core (Base vs. Delta): Separate system instructions into a fixed core framework (persona, critical safety policies) and a flexible variable section (formatting, step-by-step heuristics) that the Critic is allowed to mutate.

  • State & Version Control: Treat system prompts as state variables within your orchestration graph. Store system_instruction_v1, v2, etc., in the state payload to allow rollback if the Critic's modification causes a regression.

  • Bounded Reflection Counters: Implement a hard limit (e.g., $N=3$ retries) on prompt-modification loops to prevent runaway token usage if the Generator fails to fulfill the Critic's rewritten instructions.

  • Structured Critic Schemas: Require the Critic agent to output its feedback in a structured JSON schema, explicitly separating:

    • evaluation_reasoning: Why the output failed.

    • proposed_prompt_additions: Specific rules/constraints to inject into the Worker's system prompt.

    • target_prompt_sections: Where to inject or modify the prompt.


How can it be determined whether the agent instruction update is temporary (this run only) or permanent (for future runs as well)?

Whether an agent's updated instruction is temporary (ephemeral) or permanent (persisted) comes down to where state is stored and who holds write authority over the agent's baseline configuration.

In AI agent architectures, system instructions do not natively persist themselves—an agent is stateless between invocations unless an external control system saves its configuration. Determining (and enforcing) the scope of an update relies on specific architectural patterns:

1. Architectural Determinants: Temporary vs. Permanent

Feature / DimensionEphemeral / Temporary (This Run Only)Persistent / Permanent (Future Runs Too)
Storage LocationIn-memory Orchestrator State (Graph State, Short-Term Memory)Configuration Database, Disk File, or Prompt Registry (e.g., LangSmith, DSPy Store)
Scope of ImpactSingle execution context / thread / session.All future sessions and downstream calls.
Trigger MechanismActive task retry / self-correction loop.Meta-agent optimization phase or human-in-the-loop review.
LifecycleDestroyed or reset when the request lifecycle ends.Saved via I/O operations (file writes, database UPDATE / INSERT).

2. Technical Patterns for Defining Scope

Pattern A: Short-Term Thread State (Ephemeral)

If the modification should only apply to the current task execution:

  • Mechanism: The Critic agent modifies a system_prompt variable held inside the execution graph state (e.g., in LangGraph, CrewAI, or an engine state machine).

  • Behavior: The Generator agent uses state["system_prompt"] for retry attempts within that specific session run. Once the final output is delivered, the state object is garbage-collected or closed. The baseline code or prompt file remains completely untouched.

# Example: Ephemeral update in graph state
state["current_system_prompt"] = critic_agent.suggest_prompt_delta(
    base_prompt=DEFAULT_PROMPT, 
    failure_reason=evaluation.reason
)
# Next node runs Generator using state["current_system_prompt"]
# On job complete: state is discarded; DEFAULT_PROMPT is untouched for future calls.

Pattern B: External Prompt Registry / Versioning (Permanent)

If the Critic’s improvement represents a true optimization that benefits all future runs:

  • Mechanism: The Critic must emit an update payload to a persistent store (e.g., PostgreSQL, Redis, local YAML config file, or a vector store of system prompts).

  • Behavior: Future agent initializations load the latest active prompt version from this persistent store rather than hardcoded string defaults.

# Example: Persistent update pipeline
if critic_agent.is_structural_improvement(evaluation):
    prompt_registry.save_new_version(
        agent_id="WorkerAgent",
        new_prompt=updated_prompt,
        version_notes="Critic added anti-hallucination constraint for JSON output"
    )

3. Recommended Best Practices: Controlling Scope

Allowing an automated Critic agent to permanently overwrite system instructions dynamically introduces severe risks of prompt drift or jailbreak exploits. To maintain deterministic execution, consider these structural boundaries:

  1. Default to Ephemeral: By default, all Critic-suggested instruction updates should be scoped strictly to the current session or retry loop (N iterations).

  2. Human-in-the-Loop (HITL) Gate for Permanence: Permanent updates should require a review checkpoint. The Critic logs proposed prompt mutations to a staging database, and a human operator (or an authoritative test suite / regression eval pipeline) approves the commit to production system prompts.

  3. Automated Eval Suites (DSPy / Optimization Paradigm): If automating permanent updates without human review (e.g., using DSPy or automated prompt optimizers), changes should only be committed to the baseline registry if the new prompt passes a benchmark test suite across multiple test cases, ensuring it doesn't cause regressions on other tasks.


Given a set of AI agents running in sequence, is it possible to use the response from Agent_1 to help optimize the system instructions for Agent_2 before it runs?

Yes, absolutely. In sequential multi-agent pipelines, using the output of Agent 1 to dynamically construct or refine the system instructions for Agent 2 before it executes is a powerful architectural pattern known as Dynamic System Prompting (or Contextual Agent Specialization).

Rather than giving Agent 2 a rigid, static system prompt, you pass Agent 1's output into a Prompt Synthesizer / Adapter (or have a meta-agent process it) to build a highly targeted, bespoke persona and set of execution rules for Agent 2 on the fly.

Why Use Dynamic System Instructions Between Sequential Agents?

Passing data solely through the user message context can sometimes cause the downstream model to blur the line between background context and actual operational rules. Elevating insights from Agent 1 into Agent 2’s System Instruction forces Agent 2 to treat those insights as core behavioral constraints and operational framing, leading to significantly higher adherence and precision.

1. Primary Implementation Patterns

Pattern A: Parameterized System Instruction Templates (Deterministic)

The simplest and most reliable approach is using Agent 1's structured output to populate a templated system instruction for Agent 2.

  • Agent 1 Output: Analyzes a complex task and outputs structural parameters (e.g., target audience, required domain expertise, identified risk factors, preferred output schema).

  • System Prompt Construction:

    agent_2_system_instruction = f"""
    You are an expert specialist in {agent_1_output.domain_field}.
    
    CORE OPERATIONAL CONSTRAINTS:
    - Adhere strictly to the following parameters identified during analysis: {agent_1_output.constraints}
    - Avoid these specific pitfalls identified in planning: {agent_1_output.risks_to_avoid}
    - Output Format: {agent_1_output.formatting_rules}
    """
    

Pattern B: Meta-Prompting / System Prompt Synthesis (Dynamic)

An intermediate or dedicated Meta-Agent receives Agent 1's output and explicitly generates a tailored system instruction string for Agent 2.

  1. Agent 1 (Decomposer/Planner): Scopes the problem and identifies necessary sub-skills.

  2. Meta-Prompt Synthesizer Agent: Reads Agent 1's analysis and executes a meta-prompt:

    "Based on this task decomposition from Agent 1, write a optimal system instruction for Agent 2 that defines its exact role, step-by-step reasoning strategy, and output constraints to solve this specific sub-problem."

  3. Agent 2 Execution: Instantiated with the newly synthesized system_instruction to execute the core task.

2. Practical Examples

Use CaseAgent 1 RoleDynamic System Instruction Injection into Agent 2
Code Refactoring & SecurityScans codebase for architectural dependencies and vulnerability patterns.Inject strict anti-patterns, architectural rules, and mandatory coding standards specific to the target codebase into Agent 2's system instruction before it writes the patch.
Customer Support / Domain ExpertClassifies customer intent, technical skill level, and emotional sentiment.Dynamically set Agent 2's persona (e.g., "You are a patient, non-technical support specialist..." vs. "You are a concise tier-3 systems engineer...").
Complex Reasoning / AnalysisPerforms Fault Tree Analysis or TRIZ contradiction modeling.Inject identified root causes or physical constraints directly into Agent 2's system rules to prevent hallucinated solutions.

3. Key Design & State Guidelines

To keep this pipeline robust, consider the following implementation details:

  • Schema Validation (Pydantic / Structured Outputs): Ensure Agent 1 outputs structured data (e.g., JSON or Pydantic models). Raw, unparsed text from Agent 1 makes system instruction templating fragile and prone to prompt injection or drift.

  • Maintain System Prompt Guardrails: Always concatenate dynamically generated instructions onto a fixed, immutable baseline framework (safety rules, core system policies) to ensure Agent 2 remains bounded and secure.

  • Traceability & Logging: Store the assembled system prompt in your orchestration state payload (e.g., in LangGraph state or custom graph context) so you can audit why Agent 2 received a specific set of rules during that run.


I believe that the original goal for the entire AI Agent team should play a part in optimizing the second and successive agent system instructions

You are spot on. Incorporating the overarching global objective (the primary intent/goal) into every downstream agent's dynamically updated system instruction is essential for preventing sub-goal drift.

Without referencing the original goal, sequential agents can optimize locally for their immediate step while gradually losing alignment with the overall mission—a classic problem in multi-tier system architectures.

Here is how you can effectively bind the global objective into successive system instruction optimizations:

1. The Global Goal as an Immutable Anchor

To ensure successive agents do not wander off-course, the system prompt constructor should treat the original goal as an immutable anchor, while using intermediate outputs (from Agent 1, Agent 2, etc.) as contextual dynamic variables.

+-----------------------------------------------------------------------+
| SYSTEM INSTRUCTION STRUCTURE FOR AGENT (N)                            |
|                                                                       |
| 1. GLOBAL OBJECTIVE (Immutable)                                       |
|    "The overarching system goal is: [User's original intent]"         |
|                                                                       |
| 2. LOCAL AGENT ROLE & METRICS (Dynamic / Synthesized)                 |
|    "Your specific role in this phase is: [Agent N Sub-Task]"          |
|    "Key findings/constraints from previous steps: [Agent N-1 Output]" |
|                                                                       |
| 3. ALIGNMENT & BOUNDARY RULES                                         |
|    "Ensure your strategy directly advances the GLOBAL OBJECTIVE."     |
|    "Do not optimize for [Sub-Task] if it violates [Global Constraint]"|
+-----------------------------------------------------------------------+

2. Dynamic Optimization Strategies Using the Global Goal

When synthesizing or updating the system instructions for downstream agents, the global goal serves three critical functions:

A. Evaluative Constraint Check (Contextual Filtering)

When Agent 1 passes its analysis to a Meta-Prompt Synthesizer, the synthesizer checks Agent 1's output against the primary goal before building Agent 2’s instructions:

  • Prompt Rule: "Extract only the findings from Agent 1 that directly contribute to achieving [Global Goal]. Use those findings to construct Agent 2's system instruction."

  • Benefit: Filters out noise or non-essential tangential analysis generated in step 1.

B. Contradiction Resolution

If Agent 1 identifies local trade-offs or constraints, the global goal dictates the prioritization logic injected into Agent 2's rules:

  • Example: If the primary goal is "High Reliability", but Agent 1 suggests an optimization that sacrifices fault tolerance for execution speed, the prompt synthesizer uses the primary goal to explicitly instruct Agent 2: "Prioritize fault tolerance and safety over speed, as mandated by the system goal."

C. Downstream Verification Criteria

The global goal allows you to inject explicit self-validation instructions into Agent 2’s system prompt:

  • Injected Constraint: "Before finalizing your output, verify that your proposed response directly satisfies [Global Goal] without introducing conflicts with prior step constraints."

3. Implementation Blueprint

In dynamic orchestration (e.g., using state graphs or pipeline registries), maintain the primary goal as part of the immutable global state payload:

def build_agent_2_instruction(global_state: dict, agent_1_output: dict) -> str:
    primary_goal = global_state["primary_objective"]
    
    system_instruction = f"""
    ### SYSTEM OBJECTIVE
    You are part of a multi-agent team working toward the following primary goal:
    "{primary_goal}"

    ### OPERATIONAL CONSTRAINTS FROM PREVIOUS STAGE
    Agent 1 completed its phase and established the following guidelines for your execution:
    - Identified Framework constraints: {agent_1_output.get('constraints')}
    - Critical parameters to enforce: {agent_1_output.get('parameters')}

    ### YOUR EXECUTION DIRECTIVE
    Using the constraints above, execute your task specifically to satisfy the primary goal. 
    If a trade-off arises between step-level optimization and the primary goal, align strictly with the primary goal.
    """
    
    return system_instruction

By explicitly coupling the global target with local stage feedback, successive agents maintain precise operational focus while remaining fully aligned with the end-to-end outcome.


From <https://gemini.google.com/app/>  Google Gemini (3.6 Flash)

Comments

Popular posts from this blog

#4297 ISS Astronaut Unable to Speak

#4054 AI Agents in AI Studio