I have read a lot of agent architecture content over the last two years, and
almost all of it is about the same layer: how the agent thinks. Prompt
chaining, routing, orchestrator-workers, evaluator-optimizer, ReAct, plan-and-
execute. That layer is genuinely well served, and I am not going to add to it.
Here is the uncomfortable thing I keep running into instead. The incidents I
have seen and reviewed did not come from picking the wrong orchestration
pattern. They came from an agent that was allowed to do something nobody had
decided it could do.
A support agent with read access to the orders database escalating from SELECT
to DELETE, because a customer wrote “I was double-charged, sort it out.” A
contractor asking a policy chatbot about executive severance and getting a
correct, well-cited answer from a document they were never permitted to see. An
accounts-payable agent paying a $4,200 invoice, getting killed mid-run by a pod
eviction, and paying it again on the retry.
None of those is a reasoning failure. In every case the model did something
defensible. They are architecture failures, and they all live in the two layers
underneath the framework.
TL;DR
An AI agent has three layers, and most content covers only the first:
Layer Decides Examples Well covered? Framework how the agent thinks LangGraph, CrewAI, Agent Framework Yes — go read Anthropic and Gulli Harness how the agent acts the loop, budgets, sandboxing, compaction, retries Barely Governance what the agent is allowed to do policy, identity, approval, audit, redaction Barely, and usually as vendor marketingAgent = Model + Harness. The model proposes; the harness disposes. A tool
call is a request, not an action, and everything that makes it safe to honour
lives outside the model. This series is 18 patterns for those two layers, each
one backed by code that runs, with the failure it prevents included as a program
you can execute.
The code is at
github.com/shashikanth-gs/agent-harness-patterns
— 314 tests, runs offline with no API keys.
The framework layer is not the problem
I want to be specific about what I am not claiming, because “frameworks don’t
matter” is the kind of statement that gets quoted without its qualifier.
The framework layer is well covered, and you should read that work. Anthropic’s
Building Effective Agents
is the best short treatment of the workflow patterns — prompt chaining, routing,
parallelisation, orchestrator-workers, evaluator-optimizer — and its central
advice (“use the simplest thing that works, add agentic behaviour only when it
pays”) is correct and widely ignored. Antonio Gulli’s Agentic Design Patterns
catalogues 21 patterns with runnable code across LangChain, CrewAI, and Google
ADK. Between them, that layer has a canon.
What I am claiming is narrower and, I think, harder to argue with: your choice
between LangGraph and CrewAI will not determine whether you have an incident.
Your answer to “who decided this agent could issue refunds, and what stops it
issuing one it shouldn’t?” will.
I tested this claim rather than asserting it. Every pattern in this series is
written as a plain-Python hook, then mounted — unchanged — on both LangGraph
and Microsoft Agent Framework, with tests asserting the denial messages come out
byte-for-byte identical because they come from the same code. That is in
the adapters article.
The patterns port. The framework is plumbing.
What a harness actually is
The LLM is a reasoning engine. It reads text and produces text, including text
that says “call issue_refund with these arguments.” It cannot execute
anything. Everything between that proposal and a refund actually reaching a
customer’s card is the harness:
user goal ──▶ ┌────────────────────── HARNESS ──────────────────────┐
│ │
│ before_model ─▶ ┌───────┐ ─▶ after_model │
│ │ MODEL │ │
│ └───────┘ │
│ │ tool call (a request!) │
│ ▼ │
│ before_tool ──▶ allow / deny / pause │
│ │ │
│ ▼ │
│ execute ──▶ after_tool ──▶ result back to model │
│ │
│ on_event ◀── every step, narrated │
└─────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode
Those five seams are the whole architecture. Every pattern in this series mounts
on one or two of them:
before_model
context compaction, memory injection, budget checks
after_model
output guardrails, citation verification
before_tool
privilege broker, approval gate, identity, budgets, sandboxing — returns ALLOW / DENY / PAUSE
after_tool
redaction, untrusted-content quarantine
on_event
audit trail, cost metering, circuit breakers
And these are not my invention. They are what production frameworks already
expose under different names: Microsoft Agent Framework calls them
middleware,
LangGraph exposes node wrappers and interrupt, Claude Code calls them hooks. If
your harness has these seams, every pattern here ports to it. If it doesn’t, that
is the finding.
Five design rules that do most of the work
These come out of building all 18 patterns, and they matter more than any
individual pattern:
A tool call is a request, not an action. The model never executes
anything. If your framework’s tool decorator calls the function directly, you
do not have a governance boundary — you have a hope.Fail closed. An unregistered tool, a missing policy, an unknown token, an
exhausted budget: all resolve to denial. Registration is not authorization.Denials must be visible to the model. A denied call returns
DENIED by policy: <reason>as a tool result, so the agent re-plans —
escalates to a human, tries a permitted route, or reports honestly. A silent
refusal produces an agent that stalls or hallucinates success.Policy in code, never in the prompt. “You must never modify customer
data” in a system prompt is advisory. Models under pressure ignore it, and
models under prompt injection are instructed to ignore it. A deterministic
check cannot be argued with.Most restrictive wins, and order is about cost, not safety. When several
controls disagree, DENY beats PAUSE beats ALLOW regardless of ordering. Order
determines how much you spend before refusing and how good the error message
is. Getting the order wrong should cost you a worse message, not a breach.
The 18 patterns
Governance — what the agent is allowed to do
Pattern Prevents OWASP Identity Propagation The confused deputy: one service account with everyone’s permissions ASI03, ASI07 Tool Privilege Broker An authorized tool used in an unauthorized way ASI02, ASI03 Goal Integrity Indirect prompt injection rewriting the agent’s objective ASI01, ASI06 HITL Approval Gate Irreversible actions taken without judgment ASI02, ASI05, ASI09 Redaction Boundary Sensitive data crossing the wrong boundary ASI02, ASI06 RAG Access Control Retrieval that ignores who is asking ASI03, ASI06 Memory Isolation An injection that persists into tomorrow’s session ASI01, ASI06 Decision Trace & Audit Being unable to answer “what did it do, and on whose authority?” ASI10 Agent Evaluations Scoring the answer instead of the trajectory cross-cutting CI/CD Evaluation Gates Shipping a config change that removes a control cross-cutting Agent Lifecycle Profile Agents accumulating with no owner and no expiry ASI04, ASI10Harness — how the agent acts
Then the capstone: all of them on
one agent, and the gap that composing them revealed.
Scope, stated honestly
Real enterprise governance spans API management, network policy, cloud IAM,
secrets management, and a security operations centre. None of that fits in a
repository, and I am not going to pretend otherwise. If someone sells you
“complete AI governance” as a library, they are selling you a subset with
confident branding.
What this series covers is the part that belongs in the agent’s own design —
the seams where policy meets the loop, the decisions you make in code review
rather than in Terraform. Where a pattern needs infrastructure to be real, I say
so: the sandboxing article is explicit that a Python function is not isolation
and a container is, and the audit article is explicit that tamper-evidence only
becomes proof when the chain head is published somewhere the agent cannot reach.
That boundary is the most useful thing I can offer. Most agent governance
content is vague about it, which is how teams end up believing a regex is a
sandbox.
Frequently asked questions
Is the “agent harness” a real term or industry jargon?
It has become standard over the past year. Databricks, Fiddler AI, and Firecrawl
all published on agent harnesses in 2026, and Microsoft’s Agent Framework and
Agent Governance Toolkit implement the concept under the names “middleware” and
“Agent OS.” The underlying idea — that the runtime around the model is a distinct
architectural layer with its own concerns — is older than the label.
Do I need all 18 patterns?
No, and adopting all of them on a low-stakes agent would be a mistake. Every
article has a “when NOT to use it” section that is as long as the “when to use”
section, because the honest answer for a read-only documentation bot is “you need
about two of these.” Start with identity propagation and the privilege broker if
your agent touches a system of record; start with cost budgeting if it has an
unbounded loop.
Does this replace my framework?
No. The reference harness in the repository exists so the patterns can be read
and tested in isolation — about 150 lines. In production you mount the same
patterns on whatever framework you already run, which is what the adapters
demonstrate on LangGraph and Microsoft Agent Framework.
Why OWASP ASI identifiers rather than general security language?
Because “ASI01” is checkable and “follows security best practices” is not. The
OWASP Top 10 for Agentic Applications 2026
went through peer review with more than a hundred practitioners, and citing it by
ID means a reader can verify whether my claim about a risk matches the standard’s.
That is a habit worth adopting generally: prefer claims someone can check.
References
- OWASP GenAI Security Project, Top 10 for Agentic Applications 2026 — ASI01–ASI10
- Anthropic, Building Effective Agents
- Microsoft, Agent Framework overview and the Agent Governance Toolkit
- OpenAI, A Practical Guide to Building Agents
- Antonio Gulli, Agentic Design Patterns — the framework-layer catalogue this series deliberately does not duplicate
Next in this series: the confused deputy —
the most common architectural flaw in enterprise agent deployments, and the one
that looks like good engineering the entire time you are building it.
답글 남기기