Skip to content
AI

Strands Agents Steering Plugins — How Just-in-Time Guidance Beats Prompts and Workflows

Strands Agents plugins let you intercept every decision in the agentic loop. Steering hooks achieved 100% accuracy across 600 evaluation runs — where prompt engineering scored 82.5% and graph workflows 80.8%.

Alexandre Agius

Alexandre Agius

AWS Solutions Architect

8 min read
Share:

Most agent frameworks give you two levers: the system prompt and the tool list. Strands Agents adds a third — plugins that intercept every decision point in the agentic loop. The steering plugin, in particular, achieved 100% accuracy across 600 evaluation runs where prompt engineering scored 82.5%. This post breaks down why.

The Problem

You’ve built an AI agent. It works great in demos. Then you deploy it to production and edge cases start creeping in — the agent calls tools with wrong parameters, ignores business rules, or gets manipulated by adversarial inputs.

The standard response is to add more instructions to the system prompt. “Always validate the card number before renewing.” “Never extend a loan beyond 14 days.” “If the user asks something unrelated, politely decline.” The prompt grows, rules contradict each other, and accuracy plateaus around 80-85%.

You’ve hit the instruction scaling wall. The more rules you add to a system prompt, the less reliably the model follows any individual one. The context is there — the model just doesn’t prioritize it at the right moment.

Graph-based workflows (think LangGraph or Step Functions for agents) solve this by removing autonomy entirely. Every decision is a predetermined node. But rigid graphs can’t handle the messy, unpredictable nature of real user conversations. You end up with a state machine pretending to be an agent.

What you actually need is a way to enforce rules at the exact moment they matter — not upfront in a prompt, not in a rigid graph, but right when the agent is about to make a tool call or return a response.

The Solution

Strands Agents SDK solves this with plugins — modular components that hook into the agentic loop at specific lifecycle events. The steering plugin specifically intercepts tool calls and model responses, validates them against business rules, and forces corrections before they reach the user.

Agentic loop with steering hook injection points — before/after model calls and before/after tool calls

The key insight: instead of hoping the LLM remembers rule #47 from a 3,000-token system prompt, you check and enforce that rule programmatically at the exact point it applies.

How It Works

The Plugin System

Plugins in Strands are classes that extend a Plugin base. They attach to an agent at initialization and get wired into the agentic loop through four lifecycle hooks:

HookWhen it firesUse case
BeforeModelCallEventBefore each LLM invocationInject context, modify system prompt
AfterModelCallEventAfter the LLM respondsValidate output, request revision
BeforeToolCallEventBefore a tool executesValidate parameters, block dangerous calls
AfterToolCallEventAfter a tool returnsTransform results, trigger follow-ups

A plugin declares a name, registers hooks (via decorators in Python, manual registration in TypeScript), and can optionally provide additional tools to the agent.

from strands.agent.plugins import Plugin, hook
from strands.types.event import BeforeToolCallEvent

class AuditPlugin(Plugin):
    name = "audit"

    @hook
    def on_before_tool(self, event: BeforeToolCallEvent):
        logger.info(f"Tool: {event.tool_name}, Params: {event.tool_params}")

Plugins are composable — stack an audit plugin, a steering plugin, and a cost-tracking plugin on the same agent, each handling its own concern.

Steering: The Accuracy Plugin

The steering plugin is a specific plugin pattern that uses hooks to enforce behavioral rules. It operates at two interception points:

Before tool calls — inspect the tool name and parameters. Is the agent about to call renew_book with a 90-day extension when the maximum is 21? Reject the call and tell the model why.

After model responses — evaluate the output against business rules. Did the agent reveal internal system details? Did it comply with the required tone? If not, force a revision before the response reaches the user.

Handlers can be pure Python logic (deterministic checks) or use a secondary LLM call as a judge (for subjective evaluations like tone or completeness). The choice depends on whether the rule is binary or nuanced.

from strands.agent.plugins import Plugin, hook
from strands.types.event import BeforeToolCallEvent

class RenewalSteeringPlugin(Plugin):
    name = "renewal_steering"

    @hook
    def validate_renewal(self, event: BeforeToolCallEvent):
        if event.tool_name == "renew_book":
            days = event.tool_params.get("extension_days", 0)
            if days > 21:
                event.reject(
                    reason=f"Extension of {days} days exceeds the 21-day maximum. "
                           f"Use 21 days instead."
                )

When a hook rejects a call, the agent receives the rejection reason as feedback and retries with corrected parameters. No user intervention needed.

The Benchmark: 600 Evaluation Runs

Clare Liguori from the Strands team tested four approaches on a library book renewal agent across six scenarios: happy path, excessive renewal periods, recalled books, mismatched card numbers, adversarial tone, and informational queries. Each scenario ran 100 times.

ApproachPass RateInput TokensOutput Tokens
Steering hooks100%3,346598
SOPs (structured prompts)99.8%9,879459
Simple instructions82.5%2,329430
Graph workflow80.8%3,1161,125

Three things stand out:

  1. Steering hooks hit 100% with moderate token cost. Not the cheapest (simple instructions use fewer tokens), but far more efficient than SOPs which need 3x the input tokens for 99.8%.

  2. Graph workflows scored worse than simple instructions. Rigid state machines struggle with conversational edge cases — the agent has no flexibility to handle unexpected inputs gracefully.

  3. SOPs are a strong middle ground if you can afford the tokens. Structured natural-language documents using RFC 2119 keywords (MUST, SHOULD, MAY) get you to 99.8% — but at nearly 10K input tokens per request, that’s expensive at scale.

When to Use What

The four approaches aren’t mutually exclusive. Think of them as layers in a defense-in-depth strategy:

Start with simple instructions. For prototyping and low-stakes agents, a well-written system prompt gets you to ~80%. Fast to iterate, easy to understand.

Add SOPs for complex procedures. When you have well-defined business processes with many conditional branches, structured natural-language documents scale better than bullet points. But budget for the token cost.

Deploy steering for critical accuracy. When 99% isn’t good enough — financial transactions, healthcare, compliance-sensitive workflows — steering hooks give you programmatic enforcement at every decision point.

Combine them. Use simple instructions for general behavior, SOPs for complex procedures the agent needs to reference, and steering hooks for non-negotiable rules. Each layer catches what the previous one misses.

Building Your Own Steering Plugin

The pattern is straightforward:

  1. Identify your critical rules. What are the things the agent must never get wrong? These are your steering candidates.

  2. Classify each rule. Is it a binary check (parameter within range, required field present) or a subjective evaluation (appropriate tone, complete answer)? Binary checks use deterministic Python. Subjective checks use an LLM judge.

  3. Map rules to hooks. Parameter validation goes in BeforeToolCallEvent. Output quality checks go in AfterModelCallEvent. Context injection goes in BeforeModelCallEvent.

  4. Keep handlers fast. Deterministic checks add microseconds. LLM judge calls add seconds and cost. Use LLM judges sparingly — only for rules that genuinely require language understanding.

  5. Test with adversarial inputs. Steering hooks shine in edge cases. Build evaluation suites that specifically target the scenarios your simple instructions get wrong.

What I Learned

  • Instruction scaling has a ceiling around 80-85%. No matter how carefully you write a system prompt, adding more rules doesn’t improve accuracy linearly. At some point, rules compete for the model’s attention and compliance drops. Programmatic enforcement at decision points breaks through this ceiling.

  • Just-in-time guidance is more effective than upfront context. The model doesn’t need to remember rule #47 from the system prompt if a hook enforces it at the exact moment it matters. This is the same principle behind guardrails in software engineering — validate at the boundary, not in the middle.

  • Rigidity kills conversational agents. Graph workflows scored lower than simple instructions because real conversations don’t follow predetermined paths. Agents need autonomy to handle unexpected inputs — steering gives them guardrails without removing that autonomy.

Do It Yourself

Key takeaways:

  • Instruction scaling hits a ceiling around 80-85% — No matter how carefully you write a system prompt, adding more rules doesn’t improve accuracy linearly. At some point, rules compete for the model’s attention. Programmatic enforcement at decision points breaks through this ceiling.
  • Just-in-time guidance beats upfront context — The model doesn’t need to remember rule #47 from a 3,000-token system prompt if a hook enforces it at the exact moment it matters. Steering hooks apply rules precisely when they’re relevant.
  • Combine layers for defense in depth — Simple instructions for general behavior, SOPs for complex procedures, steering hooks for non-negotiable rules. Each layer catches what the previous one misses. 100% accuracy isn’t about picking one approach — it’s about layering them intelligently.

Try it now:

  1. Install Strands and build your first agent — Follow the Strands Agents quick start to create a basic agent with Claude on Bedrock. Start with simple instructions and test it on 10-20 real-world scenarios from your domain.
  2. Add a steering plugin for your critical rule — Identify one business rule your agent must never violate. Write a steering plugin that validates it at the BeforeToolCallEvent hook using deterministic Python logic (no LLM judge needed). Test with adversarial inputs designed to break the rule.
  3. Benchmark accuracy across approaches — Run the same 50 test cases through four configurations: simple instructions only, simple instructions + SOPs, simple instructions + steering, and all three combined. Measure pass rate to quantify which layer catches which failure modes.
Alexandre Agius

Alexandre Agius

AWS Solutions Architect

Passionate about AI & Security. Building scalable cloud solutions and helping organizations leverage AWS services to innovate faster. Specialized in Generative AI, serverless architectures, and security best practices.

Never miss a post

Get notified when I publish new articles about AI, Cloud, and AWS.

No spam, unsubscribe anytime.

Comments

Sign in to leave a comment

Related Posts