Every agent framework treats every step the same way: send it to an LLM. Format a response, send it to an LLM. Merge two outputs, send it to an LLM. Pick which branch to take, send it to an LLM. You end up paying inference cost and inference latency for work a fifty-line function would do faster, cheaper, and deterministically.
This isn't a tooling gap. It's a missing primitive.
The problem: everything looks like a nail
Agent frameworks give you one hammer — the model call — and every step in a pipeline gets treated as a nail. Need to reshape a JSON payload before the next step consumes it? That's a prompt. Need to merge three upstream outputs into one? Also a prompt. Need to route a request to one of four downstream agents based on its content? Also a prompt.
The alternative isn't better prompting. It's hardcoding — a Python function wired directly into the pipeline that does the reshaping, the merging, the routing. That works until the pipeline needs to change, at which point you're back in code you have to ship and redeploy instead of an agent you can swap out.
Both options are wrong because they're solving a problem that doesn't need intelligence. Formatting, merging, routing, and validating are structural operations. They need a type system, not a reasoner. The work isn't "understand this and decide what to do" — it's "this shape goes to that shape." That's a job for deterministic code wrapped in an agent interface, not a model invocation.
Schema.org as a type system
The reason this gap exists is that most agent frameworks have no shared vocabulary for what's flowing between steps. Without typed inputs and outputs, every junction between two agents has to be mediated by something that can read unstructured text and figure out what's there — which is exactly the bottleneck that pushes you toward another LLM call.
Schema.org's @type vocabulary solves this for free. It's already a hierarchy of well-defined, widely-adopted types — Event, Place, Offer, Person, FlightReservation — with documented properties and nesting rules. If a glue agent declares it accepts schema:Event and emits schema:Offer, any other agent in the pipeline can check that contract before runtime, not during it.
This is what makes deterministic composition possible. Once every agent's input and output is a typed, JSON-LD-shaped object, the connective tissue between agents stops being a reasoning problem. A transform step that turns a schema:Event into a schema:Offer is a mapping function with a known source shape and a known target shape. No ambiguity, no inference required, no model in the loop.
This is also why we built PAP's DynamicAgentHandler to normalize every agent response into schema.org JSON-LD regardless of whether the underlying agent is an HTTP endpoint or an LLM call. The moment everything speaks the same typed vocabulary, the pipeline itself becomes inspectable — you can look at the wiring between two agents and know exactly what's allowed to flow through it.
The four patterns
Once inputs and outputs are typed, four patterns cover almost everything that used to get routed to a model unnecessarily.
Transform — reshape one typed object into another typed object. A schema:FlightReservation from an airline API gets transformed into a schema:Reservation your booking pipeline understands. Pure function: same input, same output, every time.
Reduce — merge multiple typed inputs into one. Three agents each return a schema:Offer for the same trip leg; a reduce agent picks the cheapest, or merges them into a schema:AggregateOffer. No interpretation needed — it's a comparison over known fields.
Route — inspect a typed object and decide which downstream agent gets it, without touching the payload. A schema:Event with a startDate in the past goes to an archival agent; one in the future goes to a booking agent. The decision is a predicate over a schema field, not a judgment call.
Probe — validate a typed object against a schema and pass or reject it. Before a schema:Offer proceeds to checkout, a probe agent confirms price, availability, and validThrough are all present and well-formed. Fails closed if they're not.
None of these four patterns require a model. They require an agent identity, a typed contract, and a small amount of code — which is exactly what a glue agent is.
Zero-disclosure by construction
This is where it stops being a performance optimization and becomes a security property.
In PAP, every agent operates under a mandate — a scoped, cryptographically signed grant of exactly what that agent is allowed to see and do. A booking agent's mandate might include access to payment credentials and calendar write access. A glue agent doing transform, reduce, route, or probe work needs none of that. It only ever touches the typed payload passed to it.
Because glue agents don't reason over content — they apply deterministic functions to typed shapes — they don't need a mandate scope that grants access to anything beyond the fields they're explicitly transforming. There's no prompt context that could leak a credential, because there's no prompt. There's no model that could be induced to disclose more than it was given, because there's no model in that step at all.
This is selective disclosure enforced by the architecture rather than the policy. You're not trusting a glue agent to behave — you've removed its ability to access anything it doesn't structurally need. Evidence, not faith.
The trip planner demo
Here's what this looks like end to end. A user asks for a weekend trip; the request becomes a schema:Action with a destination and date range.
- A route glue agent inspects the destination and sends it to one of several region-specific search agents — no model call, just a field check.
- Three search agents return flight, hotel, and activity options, each as typed
schema:Offerobjects. - A reduce glue agent merges them into a single
schema:AggregateOffer, deduplicating overlapping date ranges. - A probe glue agent validates the aggregate offer against required fields before it's shown to the user — price present, dates consistent, availability confirmed.
- A transform glue agent reshapes the validated
schema:AggregateOfferinto theschema:Reservationformat the checkout agent expects.
The only model call in this entire pipeline is the one that interpreted the user's original natural-language request. Everything after that is typed, deterministic, and auditable — four glue agents doing structural work that would otherwise have been four wasted inference calls, each one a new opportunity for hallucinated fields or scope creep.
What this unlocks
Composable pipelines built this way get three things at once that are usually in tension.
They're auditable, because every junction between agents is a typed contract you can inspect statically, not a black box you have to trust ran correctly. They're efficient, because the work that doesn't need a reasoner doesn't pay for one — no inference cost or latency on steps that are pure functions. And they're principal-safe, because glue agents carry no mandate scope beyond the payload they're explicitly handling, so there's nothing for them to leak even if something upstream goes wrong.
Delegation today is surrender — you hand a model your data and trust it to do the right thing with all of it. Glue agents are the alternative: give the reasoning steps a model, give the structural steps a typed contract, and stop paying intelligence-grade cost for plumbing-grade work.