Skip to main content
← Back to Insights

Enterprise AI Workflow Patterns: Autonomy vs Control

· 41 min read
Jitender Sharma
Advisor & Technical Leader · Enterprise AI & Platforms

Enterprise AI workflow patterns: single inference, autonomous loop, deterministic chain, and guided hybrid stages

When designing enterprise AI systems, the hard question is not "should we use an agent?" It is how much autonomy the model gets versus how much control the business process requires. Four patterns cover most production designs, starting with a baseline that is not an agent at all: a single inference call through the agentic service. Pick wrong and you either overbuild an agent runtime for summarize/Q&A, lose auditability on an open loop, or waste a flexible model on a fixed pipeline.

This is a decision guide: Pattern 0 (single inference), Pattern 1 (fully autonomous), Pattern 2 (deterministic), and Pattern 3 (guided hybrid), with comparison criteria and JSON-shaped contracts. The reference design is the Agents Blueprint. Route row fields live in Route contract reference. It also builds on How to Design an Intent Router and Policy-Governed Agent Runtime.

THE CLAIM

Not every LLM feature is an agent. Start at single inference. Escalate only when you need tools, fixed multi-step process, or staged autonomy. Fix the business stages when process control matters; give the LLM autonomy inside each stage only when exploration is the product.

The bottom line first

  • Four patterns, one axis: who decides the next step (nobody beyond one call, the LLM, the workflow designer, or both at different layers).
  • Pattern 0 is one LLM call through the agentic app (summarize, Q&A, extract). No tool loop. Not an agent.
  • Pattern 1 fits research, coding, and investigation when the path is unknown.
  • Pattern 2 fits payments, KYC, claims, and any flow where order and side effects must be fixed.
  • Pattern 3 fits contract review, regulatory analysis, and enterprise copilots: fixed stages, flexible tools inside a stage.
  • Governance lives in contracts and checkpoints, not in hoping the prompt "behaves." See Route contract reference for the row fields.
  • RAG is orthogonal: same retrieve action on every pattern. deterministic_prefetch vs tool only changes who starts it. See RAG across patterns.
  • Memory is route policy + session state, not a workflow step; long-term facts are retrieved, not stuffed into the prompt.
  • Ingress (UI, API, event) is orthogonal to Patterns 0-3; pick the pattern for autonomy vs control, then choose how the route starts and resumes.
  • Default is one agentic app with many routes (including multiple autonomous ones). Split into another agent or agentic app only when execution boundaries diverge.
  • Regulated default (bank): Pattern 0 for talk and Q&A; Pattern 2 for money movement and account changes; Pattern 3 for mandated-process advice; Pattern 1 stays behind the firewall unless the manifest is read-only and the budget is tiny.

The autonomy vs control spectrum


LayerPattern 0Pattern 1Pattern 2Pattern 3
Business processOne stepOpenFixedFixed
Tool sequenceNoneLLM choosesDesigner choosesFixed stages; LLM chooses inside a stage
Is it an agent?NoYesWorkflow + LLM stepsHybrid agent
Primary riskThin context / hallucinationUnpredictable pathBrittlenessExtra architecture

Use the tabs under each pattern. Every pattern has two examples. Each example uses Route plus the artifacts it references (Workflow, Manifest, Prompt, Output, Eval, and Trace when useful).

Pattern 0: Single inference (not an agent)

How it works

The intent router (if present) selects a route contract. The agentic app assembles the prompt (plus optional context), makes one LLM call, and returns the completion. There is no Observe → Decide → Tool cycle and no multi-stage workflow. The model does not choose the next action. Clients do not call the LLM API directly; the agentic service owns session, model profile, and output handling.


Optional RAG or deterministic pre/post processing can sit around the call in the agentic app without making this Pattern 1-3. Declare prefetch on the route row: retrieval: { "mode": "deterministic_prefetch", "scope": [...] }. RAG prefetch is not an agent: if the agentic app runs retrieval before the LLM and the model never chooses tools, you are still on Pattern 0 (or Pattern 2 if you model retrieve → generate as an explicit fixed two-stage workflow). Tool-mode retrieve on Patterns 1-3: RAG across patterns.

Examples

JobShape
Summarize this emailroute → agentic app → completion
Answer from a pasted policyroute → agentic app → completion
Extract fields from a formroute → agentic app → structured JSON
Rewrite tone / translateroute → agentic app → completion
Classify intent (cheap router model)route → agentic app → label

Contracts (JSON)

A route contract stays lean. Prompt, output schema, and offline eval suite are separate artifacts the agentic app loads by id.

Example A: email summarize

No tools. No stages. One inference via the agentic app.

{
"route_id": "email_summarize",
"intent": "summarize_email",
"model_profile": "fast-chat",
"tool_manifest": "none",
"policy_profile": "read_only_standard",
"prompt_id": "email_summarize_v2",
"output_schema_id": "exec_bullets_v1",
"eval_suite_id": "email_summarize_golden"
}

Example B: grounded Q&A with deterministic prefetch

Retrieval runs in the agentic app before the LLM call. The model does not choose tools.

{
"route_id": "policy_qa",
"intent": "policy_question",
"model_profile": "fast-chat",
"tool_manifest": "none",
"policy_profile": "read_only_standard",
"retrieval": { "mode": "deterministic_prefetch", "scope": ["policy-engine"] },
"prompt_id": "policy_qa_grounded_v1",
"output_schema_id": "cited_answer_v1",
"eval_suite_id": "policy_qa_golden"
}

Pros and cons

ProsCons
Cheapest, fastest, easiest to auditNo multi-step reasoning over tools
Easy to eval and cacheWeak when the task needs search + act
Clear SLOs and costHallucination risk if context is thin
Ideal behind an intent route that only needs textCannot perform side effects via LLM-chosen tools

Best use cases

Summarization · Q&A over provided context · Extraction · Classification · Rewriting · Simple generation · Cheap classifier inside an intent router

Pattern 1: Fully autonomous agent

How it works

The router (if any) selects a route and provides the allowed tools. The agentic app runs the loop; the LLM proposes the next action. The app executes tools, observes results, and feeds them back until the goal is met or the budget is exhausted.


The sequence of tool calls is not fixed. Two runs with the same goal can take different paths and both be valid. The agentic app owns the budget; the LLM only proposes.

Example: contract investigation (same goal, different paths)

RunPath
Run 1OCR → Clause Search → Policy Search → Memo
Run 2OCR → Policy Search → Risk Engine → Clause Search → Memo

Contracts (JSON)

Same route shape as Pattern 0, plus a tool manifest. Path order is not fixed; eval checks goal completion and policy, not a single tool sequence.

max_loop_steps is a run budget

max_loop_steps: 12 caps the whole autonomous loop (decide → tool → observe), across all tools combined. It is not “each tool may run 12 times.” One clause_search plus one policy_search counts as 2 steps toward 12. When the cap is hit, the agentic app stops even if the model wants another call. Pattern 3 uses max_tool_calls per stage for the same idea inside a fixed outer workflow.

Example A: contract investigation

{
"route_id": "contract_investigation",
"intent": "contract_investigate",
"model_profile": "reasoning-standard",
"tool_manifest": "contract_investigate_v1",
"policy_profile": "read_only_standard",
"retrieval": { "mode": "tool", "scope": ["clause-index", "legal-playbook"] },
"memory_profile": {
"conversation": "session",
"working": "session",
"loop": "checkpoint",
"long_term": "retrieve_only",
"ttl_hours": 24,
"isolation": ["tenant", "user", "session"]
},
"prompt_id": "contract_investigate_v1",
"output_schema_id": "risk_memo_v1",
"eval_suite_id": "contract_investigate_golden",
"max_loop_steps": 12
}

Example B: research assistant

{
"route_id": "research_assistant",
"intent": "research_topic",
"model_profile": "reasoning-standard",
"tool_manifest": "research_assistant_v1",
"policy_profile": "read_only_standard",
"prompt_id": "research_assistant_v1",
"output_schema_id": "research_brief_v1",
"eval_suite_id": "research_assistant_golden",
"max_loop_steps": 16
}

Pros and cons

ProsCons
Maximum flexibilityHarder to audit
Adapts to unexpected situationsHarder to predict
Strong for research and discoveryNeeds strong checkpointing
Handles unknown paths wellMore difficult to govern

Best use cases

Research assistants · Coding agents · Investigation · Data analysis · Document review (exploratory) · Knowledge discovery

Pattern 2: Deterministic AI workflow

How it works

The workflow is fixed. The agentic app advances stages from the workflow artifact; the LLM performs only the work assigned to a stage (llm_role). Every execution follows the same sequence.


There is no "LLM decides next action" between stages. Branching, if any, is explicit in the workflow definition (approval gates, error handlers), not inventable by the model. The agentic app owns stage order; the LLM never chooses the next step.

Contracts (JSON)

Route points at a fixed workflow_id. Stage order lives in the Workflow artifact; the Manifest holds tool schemas for PEP. The LLM does not pick the next tool.

No max_tool_calls here

Pattern 2 has no open tool-choice loop inside a stage. Each stage already names the tool (or a fixed branch), so the budget is the stage list itself, plus retries / timeouts. Use max_tool_calls on Pattern 3 (and max_loop_steps on Pattern 1), where the LLM can call several tools before a stage or goal completes.

Example A: MSA risk review

{
"route_id": "msa_risk_review",
"intent": "msa_risk_review",
"model_profile": "reasoning-standard",
"tool_manifest": "msa_risk_review_v1",
"policy_profile": "read_only_standard",
"retrieval": { "mode": "tool", "scope": ["clause-index", "legal-playbook"] },
"workflow_id": "msa_risk_review_v1",
"prompt_id": "msa_risk_review_v1",
"output_schema_id": "msa_memo_v1",
"eval_suite_id": "msa_risk_review_golden"
}

Example B: payment / KYC onboarding

Order and approvals matter. branch is a deterministic next-stage map from the risk score, not an LLM choice. Side-effect stages are gated.

{
"route_id": "kyc_onboarding",
"intent": "kyc_onboard",
"model_profile": "reasoning-standard",
"tool_manifest": "kyc_onboarding_v2",
"policy_profile": "high_risk_step_up",
"workflow_id": "kyc_onboarding_v2",
"prompt_id": "kyc_onboarding_v2",
"output_schema_id": "kyc_result_v1",
"eval_suite_id": "kyc_onboarding_golden"
}

Pros and cons

ProsCons
Easy to auditLess flexible
Easy to resumeCannot adapt easily
PredictableWorkflow changes need design changes
Excellent governanceWeak on unknown scenarios
Ideal for regulated industries

Best use cases

Payments · Loan processing · Insurance claims · Customer onboarding · Compliance workflows · KYC

Pattern 3: Guided agent (hybrid)

How it works

The workflow is fixed. The reasoning inside each step is flexible. The agentic app advances stages and exposes only the current stage allowlist; the LLM proposes which allowed tools to call and in what order. The process never invents new stages.


Example A (simple Analyse): Clause Search → Done

Example B (deeper Analyse): Clause Search → Policy Search → Risk Engine → Done

The outer workflow stays Extract → Analyse → Generate Report. Only the internal path changes. The agentic app owns outer stage order; the LLM owns tool choice only inside a stage.

Contracts (JSON)

Route picks the capability; Workflow fixes outer stages; Manifest holds tool schemas; each stage has an allowlist. Prompt / output / eval can be stage-scoped.

Example A: legal contract review

Outer workflow stays Extract → Analyse → Generate Report. Inside Analyse, tool order can vary.

{
"route_id": "legal_contract_review",
"intent": "contract_review",
"model_profile": "reasoning-standard",
"tool_manifest": "contract_review_staged_v3",
"policy_profile": "read_only_standard",
"retrieval": { "mode": "tool", "scope": ["clause-index", "legal-playbook"] },
"workflow_id": "contract_review_v3",
"memory_profile": {
"conversation": "session",
"working": "session",
"loop": "checkpoint",
"long_term": "retrieve_only",
"ttl_hours": 24,
"isolation": ["tenant", "user", "session"]
},
"prompt_id": "contract_review_v3",
"output_schema_id": "counsel_memo_v1",
"eval_suite_id": "contract_review_golden"
}

Example B: regulatory impact analysis

Same hybrid shape: fixed stages, flexible tools inside Analyse.

{
"route_id": "regulatory_impact",
"intent": "regulatory_analysis",
"model_profile": "reasoning-standard",
"tool_manifest": "regulatory_impact_v1",
"policy_profile": "read_only_standard",
"retrieval": { "mode": "tool", "scope": ["reg-index", "control-library"] },
"workflow_id": "regulatory_impact_v1",
"memory_profile": {
"conversation": "session",
"working": "session",
"loop": "checkpoint",
"long_term": "retrieve_only",
"ttl_hours": 24,
"isolation": ["tenant", "user", "session"]
},
"prompt_id": "regulatory_impact_v1",
"output_schema_id": "reg_impact_memo_v1",
"eval_suite_id": "regulatory_impact_golden"
}

Pros and cons

ProsCons
Strong governanceMore architecture
Flexible reasoningNeeds workflow + agent runtime
Easier auditing than Pattern 1Slightly more complex to implement
Good balance of control and autonomy
Enterprise friendly

Best use cases

Legal review · Contract review · Medical review · Financial advice · Regulatory analysis · Enterprise copilots

Choosing a pattern

Use this section to pick Pattern 0-3. Everything after it (RAG, memory, ingress, agent-to-agent, split) is orthogonal: it applies once you have a pattern, and does not change which pattern you chose.

Comparison matrix

CapabilityPattern 0: Single inferencePattern 1: AutonomousPattern 2: DeterministicPattern 3: Guided
Is an agentNoYesNo (fixed workflow)Yes (within stages)
Workflow fixedN/A (one step)NoYesYes
Tool sequence fixedN/A (no tools)NoYesNo (within a step)
LLM decides next actionNoYesNoYes (inside each step)
Easy to auditExcellentNoYesYes
Easy recoveryExcellent (retry call)MediumExcellentExcellent
FlexibilityLowHighLowMedium-High
Enterprise governanceExcellentMediumExcellentExcellent
ComplexityLowestMediumLowHigh
Agent-to-agent callsNoYes (dynamic)Yes (fixed handoffs only)Yes (stage-scoped)
RetrievalPrefetch before the one callTool; LLM chooses whenNamed retrieve stage; order fixedTool; only inside the current stage
MemoryOptional context for one callSession + loop; long-term via retrieveStage / working along fixed pathStage-scoped working; governed handoffs
Ingress affinityUI + sync APIUI or async / event for long loopsAPI + events (UI with gates)UI review + API / batch

Which should you choose?

Choose Pattern 0 if...

  • One reasoning pass is enough.
  • No tools (or only deterministic pre/post handled by the agentic app around the call).
  • No side effects driven by the LLM.
  • Latency and cost matter more than multi-step investigation.

Examples: summarization, Q&A over provided context, extraction, classification, rewriting.

Choose Pattern 1 if...

  • The problem is exploratory.
  • You do not know the execution path in advance.
  • The AI needs maximum autonomy.

Examples: research, coding, investigation, knowledge assistants.

Choose Pattern 2 if...

  • Every step is mandatory.
  • Order matters.
  • Compliance is critical.
  • Side effects (payments, writes) must be tightly controlled.

Examples: payments, loan approvals, insurance processing, KYC.

Choose Pattern 3 if...

  • The business process is fixed.
  • Reasoning within each stage is complex and varies.
  • You need both governance and AI flexibility.

Examples: contract review, regulatory compliance, due diligence, financial document analysis, enterprise legal assistants.

Quick filter:

SignalPrefer
One call is enough (summarize, Q&A, extract)Pattern 0
Unknown path is the productPattern 1
Side effects + mandatory orderPattern 2
Fixed stages, variable depth of analysisPattern 3

Escalate from Pattern 0 when the model needs to search, call APIs, or iterate (Pattern 1 or 3), or when the business requires mandatory ordered stages with side effects (Pattern 2).

Which should you choose in a regulated industry?

A retail-banking chatbot is the channel and session, not a pattern. The customer talks to one assistant. Each turn still picks a route, and the route picks Pattern 0-3. Do not map "we have a chatbot" to Pattern 1. Conversation is ingress. Autonomy is a property of the route.

Default mix in a bank: Pattern 0 for talk and Q&A. Pattern 2 for anything that moves money or changes an account. Pattern 3 for advice that has a mandated process. Pattern 1 stays behind the firewall (fraud investigation, coding, research) unless the tool manifest is read-only and the budget is tiny.


Same agentic app, many routes. Balance, transactions, statements, and card freeze share customer context. They do not share one autonomy contract.

Customer saysRoutePatternWhy
"Hi, what's my balance?"account_balance0One call plus a deterministic balance read. The model does not choose the next step.
"What's the overdraft fee?"policy_qa0Prefetch from the fee corpus, one grounded answer.
"Show last five transactions"account_history0 or 20 if it is read and format. 2 if you require a fixed auth → fetch → redact → present chain.
"Freeze my card" / "Send $500 to Acme"card_freeze / payment_initiate2Order, identity, limits, and side effects are non-negotiable. The model does not invent the next stage.
"Help me understand this loan offer"loan_explain3Fixed stages (extract → analyse vs policy → explain). Depth can flex inside Analyse.
"Why was I charged this? Dig around."usually not Pattern 12 or 3Investigation still needs a governed retrieve allowlist and no write tools. Open-loop research is for internal ops, not the customer chat.

Multi-turn chat is session memory plus stickiness, not an autonomous loop. Short replies ("yes", "$500") stay on the active route. A real new intent (balance question to card freeze) is a new pin, not more autonomy on the same run. See How to Design an Intent Router.

Quick filter for regulated work:

SignalPrefer
Talk, FAQ, grounded policy Q&A, read and formatPattern 0
Write path: pay, freeze, open, close, disputePattern 2
Mandated process, variable depth of analysisPattern 3
Open-ended path is the product (internal only)Pattern 1, read-only manifest + hard budget

If a step can write, the outer process is Pattern 2. The model may draft a confirmation or a query inside a stage. It does not choose whether activation happens. If a step is read plus explain, stay on Pattern 0 until you need tools or fixed stages.

Putting the whole bot on Pattern 1 is how you get an unauditable payment path with a friendly chat UI.

Across every pattern

These concerns cut across Patterns 0-3. Set them on the route and agentic app after you pick a pattern. They do not replace the autonomy-vs-control choice.

RAG: same action, who starts retrieve

RAG is not a fifth pattern. It is the same action on every route: fetch chunks from a corpus, pack them as context, then generate. Patterns 0-3 only change who starts retrieve and when. Declare it on the route as retrieval.

Two modes:

retrieval.modeWho starts retrieveFits
omit / noneNobodyChat or handoff with no knowledge path
deterministic_prefetchAgentic app, before the LLM. Model never sees retrieve tools.Pattern 0 Q&A. Pattern 2 if retrieve → generate is a named workflow.
toolLLM may propose retrieve inside scope. PEP still gates the action.Patterns 1-3. On Pattern 2 the workflow names the stage; the LLM does not choose when.

scope is the list of corpus / index ids the route may touch. More than one retrieve still uses one retrieval object: put every corpus in scope. Bind each Pattern 2 stage with corpus. Do not add a second retrieval key.


Route retrieval field (JSON)

Prefetch (Pattern 0). Two corpora: app packs each, then one LLM call.

{
"retrieval": {
"mode": "deterministic_prefetch",
"scope": ["policy-engine", "product-faq"]
}
}

Tool mode (Patterns 1-3). One object, two corpora. Each tool call or stage hits one corpus in scope.

{
"retrieval": {
"mode": "tool",
"scope": ["clause-index", "legal-playbook"]
}
}

How each pattern uses RAG

PatternModeWhat happensIn this article
0deterministic_prefetchApp retrieves, then one LLM call. Not an agent.Example B: policy_qa
1toolLLM may retrieve zero, one, or many times, in any order, mixed with other tools.Contract investigation: clause_search / policy_search
2Prefetch as a named stage, or tool with fixed orderWorkflow owns order. LLM may formulate the query (llm_role: query_formulation); it cannot skip or reorder retrieve.MSA risk review: clause_search then policy_search
3tool, stage-scopedOuter stages stay fixed. Retrieve only from the current stage allowlist.Contract review: Analyse allowlist
Pattern 0Pattern 1Pattern 2Pattern 3
Can skip retrieve?No, if prefetch is declaredYesNoYes, inside that stage only
Can retrieve twice?No (one pack, one call)YesOnly if the workflow has two retrieve stagesYes, until max_tool_calls

Pick the pattern from process control, then attach RAG. Prefetch Q&A is Pattern 0. Mandatory search-then-generate is Pattern 2. Exploratory multi-hop retrieve is Pattern 1. Fixed stages with flexible retrieve inside one stage is Pattern 3.

Long-term and episodic memory are also retrieval (long_term: "retrieve_only"). They do not pick the pattern. Load them in context assembly or via an allowlisted tool. See Memory.

Memory: route policy, session state

Memory is not a workflow step on the route row. The route (or its policy_profile / memory_profile) declares whether memory is allowed and under what isolation / TTL rules. Field dictionary: Route contract reference. How to build the store: Memory. The agentic app owns read, write, and assembly during the session. Treat memory like manifests and prompts: config and runtime, not another tool the LLM invents mid-path.

Split memory by lifecycle (same idea as G.A.I.N Agents):

KindWhat it holdsScoped toWho owns it
ConversationUser / assistant messagesSessionAgentic app (session store)
WorkingTask slots, route entities, stage outputsSession (pinned route)Agentic app
LoopStep count, proposals, observations, checkpointsSession / runAgentic app (checkpointer)
EpisodicSummaries of past sessionsUser / tenantYour memory service + retrieval
Long-termPrefs, durable factsUser / tenantYour memory service + retrieval

Session pin applies here too. At route decision, pin the route and manifest versions that define which tools and stages may run. Working and loop memory stay under that pin for the in-flight run. Do not swap mid-session memory contracts without explicit policy.

How each pattern uses memory

PatternTypical memoryWhat to avoid
0Optional short conversation or caller-supplied context for one callTreating chat history as an agent loop
1Conversation + working + loop state across Observe → Decide → ToolUnbounded history in the prompt; cross-session bleed
2Working / stage outputs along the fixed workflow; loop only inside LLM stagesLetting the model rewrite prior stage outputs as "memory"
3Stage-scoped working memory; clear handoff of allowed slots between stagesCarrying Stage A tool results into Stage B outside the allowlist

Long-term and episodic memory are retrieval, not free context. Load them in context assembly (What Is the Agentic Loop, coming soon) or via an allowlisted tool on the manifest. Do not dump every past session into the system prompt. Corpus RAG (prefetch vs tool) is a separate route field: RAG across patterns.

Route shape (optional)

Routes stay lean. Prefer a memory_profile (or fields on policy_profile) over embedding store credentials or raw history rules in the row. Full field list: Route contract reference.

Route memory_profile example (JSON)
{
"route_id": "legal_contract_review",
"intent": "contract_review",
"model_profile": "reasoning-standard",
"tool_manifest": "contract_review_staged_v3",
"policy_profile": "read_only_standard",
"retrieval": { "mode": "tool", "scope": ["clause-index", "legal-playbook"] },
"workflow_id": "contract_review_v3",
"memory_profile": {
"conversation": "session",
"working": "session",
"loop": "checkpoint",
"long_term": "retrieve_only",
"ttl_hours": 24,
"isolation": ["tenant", "user", "session"]
},
"prompt_id": "contract_review_v3",
"output_schema_id": "counsel_memo_v1",
"eval_suite_id": "contract_review_golden"
}
FieldMeaning
conversation / working / loopWhere that tier lives for this route (none, session, checkpoint)
long_termUsually retrieve_only or none; write paths need their own policy and tools
ttl_hoursSoft lifetime for session-scoped stores
isolationRequired partition keys so Session A cannot read Session B

When the row's memory_profile (or memory fields on policy_profile) change, treat it like any other route-row policy change: bump and pin per the route table lifecycle. Field dictionary: Route contract reference.

Ingress: UI, API, or event

Patterns 0-3 answer who decides the next step. They do not answer how the run is started. None of the patterns is UI-only or API/event-only. The same route_id can be invoked from a chat UI, a synchronous API, or an event worker. Ingress is a separate concern on the agentic app: latency SLO, sync vs async, human gates, idempotency, and how you wait or resume.

IngressWhat it isTypical fit
UIChat, copilot, form, review screenInteractive turns; streaming; human approval UX
APISync request/response (or async job start)Systems integration; clear request/response contracts
EventQueue, webhook, schedule, domain eventBackground work; retries; long runs; side-effect pipelines

Affinity by pattern (not a hard rule)

PatternTypical ingressWhy
0 Single inferenceUI + sync APIFast, one-shot; summarize, extract, classify
1 AutonomousUI copilots; sync or async jobsExploratory loops; long runs often better async / event
2 DeterministicAPI + events (UI with gates too)Fixed order and side effects; queues fit resume and retry
3 Guided hybridUI review + API / batchFixed stages; humans often in the loop for report or approve

Does ingress decide the pattern?

Mostly no. Choose Pattern 0-3 from process needs (tools? fixed order? stage autonomy?). Then bind the route to one or more ingress adapters without changing the autonomy contract.

When ingress does matter:

ConstraintImplication
Interactive UI, tight latencyCap loop/stage budgets hard; favor Pattern 0, or short Pattern 1 / 3; stream when you can
Long tool loops or heavy jobsPrefer async API or event start; do not block a browser on an open Pattern 1 loop
Event-driven side effectsPattern 2 (and long Pattern 1 / 3) shine: idempotent workers, checkpoint resume, no user waiting
Human approvalNeed a channel (UI or ticket); Pattern 2 / 3 already model human_gate

Do not map "UI = agent" or "API = workflow." Map the pattern to control; map UI / API / event to how you start, wait, and resume that route.

Agent-to-agent calls

Not every pattern supports one agent invoking another. The distinction matters when you split capabilities across specialist agents instead of tools.

Pattern 0: No. There is no agent loop. The agentic app makes one inference call and cannot delegate to another agent.

Pattern 1: Yes (dynamic). The running agent can treat another agent as a tool or sub-agent and decide when to invoke it. Any specialist may run in any order. Maximum flexibility, weakest predictability for which agents run.

Pattern 2: Yes (fixed orchestration only). You can wire agents as explicit workflow stages: Agent A completes, then Agent B runs. The workflow designer defines the handoff, not the model. Good for audit; no exploratory delegation.

Pattern 3: Yes (governed). The usual enterprise shape. A stage host agent may call specialist agents only if they are on that stage's allowlist, or each stage is owned by a dedicated agent with fixed handoffs between stages. Multi-agent capability without open-ended spawning.

NeedPrefer
Dynamic "call another agent when needed"Pattern 1
Fixed "stage 1 agent → stage 2 agent" pipelinePattern 2 or 3
Governed specialist delegation inside a stagePattern 3

Scaling the platform

Patterns answer how much autonomy. This section answers how many agentic apps and where versioning lives. Prefer routes on one runtime until boundaries force a split.

When to split into another agent or agentic app

Patterns 0-3 answer how much autonomy a capability gets. They do not answer how many agentic apps you need. Hundreds of routes, including several Pattern 1 autonomous routes and several Pattern 2 write workflows, can share one agentic app. A new use case is usually a new route, not a new agent.

TermWhat it is
RouteGoverned execution contract: tools, policy, model, prompt, workflow, budgets for this intent
Agentic app / runtimeShared service that loads the route and runs the matching pattern
Specialized agentSeparate reasoning and ownership boundary (own instructions, memory, evals, release cadence), often its own agentic app or hard isolation

Stay on one agentic app when...

  • The business domain is shared (same customer journey, same data owners).
  • Differences are mainly tools, prompts, workflows, or policy profiles.
  • One team owns prompts, evals, releases, and monitoring.
  • You need many Pattern 1 routes (research, investigation, coding) that still share session, observability, and PEP.
  • You need many Pattern 2 routes (pay, freeze, KYC, claims) that still share session and PEP. Fixed order lives in workflow_id on the route, not in a second app.

Same runtime, different route_id. Autonomy lives in the route contract (tool_manifest, workflow_id, max_loop_steps, model profile), not in a separate process.

Split into another agent or agentic app when...

SignalWhy a route is not enough
Different business domainsFinance vs HR vs Legal: different systems, policies, and mental models
Different data boundariesTenant, PII class, or system of record must not share session or retrieval scope
Different risk / compliancePayment or write-path isolation needs a harder boundary than a Pattern 2 route allowlist
Different ownershipSeparate teams need separate release, eval, and incident ownership
Different reasoning styleCitation-heavy legal review vs repo-bound coding are different cognitive products
Different memory contractsEpisodic or long-term memory must not bleed across domains

Mixed signals (same domain, but a high-risk write slice with a different compliance owner) usually mean: keep the bulk on shared routes; split only the high-risk slice.

What not to do

  • Do not create an agent per intent, chatbot, Pattern 1 route, or Pattern 2 workflow.
  • Do not equate "autonomous" or "deterministic write path" with "separate agentic app." Multiple Pattern 1 and Pattern 2 routes on one runtime is the default.
  • Do not start with an agent fleet. Grow: single app → capability routes → specialized agents when boundaries force it.

Quick filter:

QuestionPrefer
Same domain, owner, and data boundary; only tools or pattern differ?New route on the shared agentic app
Multiple exploratory / autonomous capabilities in that domain?Multiple Pattern 1 routes, same app
Multiple write / KYC / claims flows in that domain?Multiple Pattern 2 routes, same app
Domain, risk, data, ownership, or reasoning boundary diverges?New specialized agent / agentic app
Need one specialist to call another?Keep patterns from agent-to-agent calls; split only if boundaries require it
Related

For the deeper routes-vs-agents decision guide, see One Agent with Routes vs Specialized Agents.

Route versioning

All four patterns share one versioned route table. Workflows, manifests, prompts, schemas, and eval suites are separate artifacts the route references. Bump and session-pin rules are the same regardless of Pattern 0-3. For fields and when to bump route_table_version, see Route contract reference and Route table lifecycle.

Key takeaways

  • Choose on the autonomy axis, not on whether "agents are cool."
  • Pattern 0 when one call through the agentic app is enough; it is not an agent.
  • Pattern 1 when the path is the discovery; accept weaker predictability.
  • Pattern 2 when order and side effects are non-negotiable.
  • Pattern 3 when the process is fixed but stage-level reasoning must flex.
  • Agent-to-agent calls: Pattern 1 for dynamic delegation; Pattern 2 or 3 for fixed or governed multi-agent handoffs; Pattern 0 does not apply.
  • Split agents only for execution boundaries (domain, data, risk, ownership, reasoning), not for each autonomous route.
  • Encode contracts as JSON and only add agent or checkpoint machinery when the pattern needs it.
  • RAG: prefetch for Pattern 0 Q&A; tool-mode retrieve for Patterns 1-3; Pattern 2 names retrieve as a stage. Same retrieval field; who starts retrieve follows the pattern.
  • Memory: declare isolation and TTL on the route; keep working/loop state on the session; retrieve long-term memory, do not treat it as a free step in the path.
  • Ingress: UI, API, and events can all start the same route; pick the pattern for autonomy vs control, then choose start / wait / resume for the channel.
  • Regulated mix: the chatbot is the session, not the pattern. Pattern 0 for talk and Q&A, Pattern 2 for writes, Pattern 3 for mandated advice, Pattern 1 behind the firewall.