Architecture · AI Systems · Agents · Workflows
If a Function Can Do It, Don't Make It an Agent
How to choose between AI agents and explicit workflows, why multi-agent is not a maturity badge, and how production systems mix both without losing control.
Janardhana Bandaru
· 7 min read
An agent is a model-driven loop: it takes a goal, can call real tools (such as search or refund), and repeatedly decides the next action until it stops (goal met, limit hit, or a human intervenes).
A workflow is a path you design: ordered steps (agents, plain functions, or human gates), join points, and rules for how work resumes after failure.
When the path is open, the model chooses the next move. When the process is known, you do. Together they give flexibility and control, but not free reliability, free auditability, or free cost control.
This article is about when to put the model above the process versus inside a step. It is for people learning AI agents, or evaluating Microsoft Agent Framework / multi-agent demos that now need a production date. It assumes service and API basics. It is not a package install guide or a full sample app.
Why this decision showed up everywhere at once
In the last couple of years many teams shipped chat demos quickly, then tried to hang real work on them: refunds, multi-step reviews, content pipelines, IT diagnostics. Microsoft describes Microsoft Agent Framework as the direct successor to AutoGen and Semantic Kernel. It brings multi-agent patterns together with production habits such as sessions, middleware, telemetry, graph workflows, checkpointing, and human-in-the-loop.
The product name will age. The decision will not.
If you can write a function to handle the task, do that instead of using an AI agent. That is not anti-AI. It is anti-theater.
Building blocks
When a function is not enough, you still need a clear cast. You will meet three roles:
- Agent — model-backed component that plans and may call tools
- Step / executor — a node in a graph (sometimes an agent, often a plain function)
- Workflow — ordered steps with edges you defined: sequence, fan-out, handoff, joins, checkpoints
Optional but production-shaped:
- Human-in-the-loop — pause for approval before a sensitive action
- Session / state — conversation or run state you can persist
- Middleware — intercept runs and tool calls for policy (logging, redaction, approval)
Together they let you compose systems that are partly judgment and partly procedure. They do not remove the need for contracts on every side effect. The smart component still hits the real world through ordinary APIs (same instinct as message consumers and dual-write).
A scenario that sorts teams in ten minutes
Suppose a support ticket arrives: “I was charged twice.”
Agent-only design. One agent with tools for billing search, refund, CRM note, and email. That can work on a good day. It can also refund twice if a retry or resumed run replays a tool that is not safe to call twice, or burn time chatting while the customer waits. Your audit trail is mostly a transcript unless you add structure yourself.
Workflow-first design.
- Classify (small model or rules) → chargeback vs duplicate vs confused invoice
- Enrich (deterministic functions) → pull invoices, payments, prior tickets
- Propose (agent) → draft resolution in structured form
- Approve (human or policy) for money movement
- Execute (safe-to-repeat service APIs) → refund once, write CRM, notify
The model still earns its keep in steps 1 and 3. The process stays fixed; it is not inventing the path under load.
That hybrid matches the control story vendors and regulated buyers emphasize: governance and observability around the edges, models where language and judgment help. It is a design pattern, not a claim that every enterprise already runs this exact flow.
Mental model
| Question | Lean agent | Lean workflow |
|---|---|---|
| Is the path known up front? | No / evolves mid-chat | Yes / mostly fixed stages |
| Who should choose the next step? | The model | Your graph (or policy) |
| Do you need resume after crash/deploy? | Session helps; still hard | Checkpointed graph is the point |
| Is the output mainly conversation? | Strong fit | Often overkill |
| Multiple specialists must coordinate? | Possible (group/Magentic) | Sequential, concurrent, handoff graphs |
| Irreversible money / ACL / delete? | Only with hard gates | Prefer explicit approve + execute nodes |
Punchline contract:
Use an agent when the path is not known. Use a workflow when the path is known and the model is a specialist inside a step.
Multi-agent patterns such as handoff, group chat, and Magentic-style managers (a manager agent that keeps a shared plan) put more next-step choice in model-driven coordination. They are strong for open research and analysis. They are a weaker default when you needed a fixed compliance path. Prefer them for open-ended work; wrap irreversible effects in workflow gates and tool approval.
What people get wrong
God-agent with forty tools. One brain, every system credential, one prompt. Latency and failure modes compound. Specialists plus handoff or sequential nodes usually beat a kitchen-sink agent.
Multi-agent as a maturity badge. Three agents debating a password reset is not sophistication. It is three failure domains and a larger bill. Start with one model call or one agent; split when a role boundary is real (triage vs policy vs executor).
Workflow theater for chatty Q&A. Not every FAQ needs a graph. A single agent with a small tool set and session memory is fine for open conversation.
Autonomy confused with reliability. Retries, durable execution, and checkpoints do not fix a refund tool without an idempotency key. If you have already internalized at-least-once delivery, apply the same instinct: side effects must tolerate replay.
Skipping the function test. If a senior engineer can write a boring function with clear inputs and outputs, start there. Add a model only where language or incomplete specification requires judgment.
When to use which
Prefer an agent when:
- The user conversation is open-ended
- Which tool to call depends on natural language
- Drafting, research, or analysis steps emerge mid-task
- You are embedding judgment inside one workflow node
Prefer a workflow when:
- Stages are known (classify → enrich → decide → act)
- Multiple agents or services must coordinate with a defined order or join
- You need checkpoints, human approval, or audit of which path ran
- Cost and latency must be bounded by topology, not hope
Prefer neither (plain code) when:
- CRUD, reports, simple API composition
- Fixed schema classification you can unit test without an agent runtime
- You have no budget for evaluation, tracing, or tool security
Production constraints (design review checklist)
Use this in reviews whether the stack is Microsoft Agent Framework or something else:
- Can a function do this step? If yes, it is not an agent node.
- What is the stop condition? Max steps, max tool calls, deadline.
- Which tools are irreversible? Approval middleware or HITL node required.
- Are tool effects idempotent under retry and durable replay?
- What is the durable state? Session only, or workflow checkpoint with correlation id.
- How do we resume after deploy or process death?
- What does success look like in metrics? Not “tokens used,” but tickets resolved, false refunds, human override rate.
- Is multi-agent earning its complexity? Name the role boundary or delete an agent.
Close
Agents are how software absorbs ambiguity. Workflows are how software keeps promises. Production systems need both, in that order of honesty: ambiguity where the world is messy, graphs where the business already knows the stages.
Microsoft Agent Framework is one concrete way to express that split on .NET and Python, with deep Azure and Foundry integration and multi-provider options documented by Microsoft. The framework is not the lesson. The lesson is knowing when the model should plan the path, and when your graph should.
If you only remember one line: put the model inside the step, not above the process, unless the process truly cannot be named yet.
Where next
- Coming next in this series: tool-calling boundaries (side effects need contracts), and agent middleware as a production control plane.
- Related on this site: exactly-once is the wrong default goal, outbox pattern design, MediatR pipeline behaviors.