Workflow vs Agent: Deterministic Orchestration & Dynamic Tool Selection
Quick Diagnosis
| Situation | Recommended approach | Why it fits |
|---|---|---|
| All steps known ahead of time (e.g., fetch data → prompt → parse → store) | Workflow | Immutable execution, easy testing, predictable token usage |
| Path depends on content or user intent (e.g., “answer any compliance question”) | Agent | Chooses tools at runtime, handles unknown sub‑tasks |
| Regulatory audit required (immutable logs, version‑controlled prompts) | Workflow | Deterministic runs produce repeatable audit trails |
| Live numeric value needed (credit score, market rate) | Tool call from workflow (authoritative API) | Guarantees freshness; does not rely on stale retrieval |
| Batch processing with tight cost budget | Workflow | One LLM call per step, predictable token usage |
| Real‑time, ad‑hoc question answering | Agent | Dynamic reasoning, on‑the‑fly tool selection |
| Mix of known skeleton + occasional live‑value request | Hybrid (workflow + runtime API/agent) | Keeps core deterministic, adds flexibility only where required |
Decision Flow
flowchart TD
A["Is the full execution path known ahead of time?"]
B["Can every required tool be enumerated?"]
C["Use a deterministic workflow"]
D["Is the request likely to need unknown sub‑tasks?"]
E["Add an agent layer for dynamic tool selection"]
F["Can live values be fetched via an API?"]
G["Expose API call from the workflow"]
H["Leave decision to the agent at runtime"]
A -->|Yes| B
B -->|Yes| C
B -->|No| D
D -->|Yes| E
D -->|No| F
F -->|Yes| G
F -->|No| H
Architectural Responsibilities
| Layer | Core duty | Typical implementation |
|---|---|---|
| Deterministic Orchestrator | Define the fixed sequence, validate inputs, enforce business rules, emit immutable logs | Azure Logic Apps, Temporal, Airflow, hand‑rolled Python DAG |
| Agent Core | Detect intent, decide which tool or retrieval source to invoke, manage ReAct‑style loops, handle fall‑backs | LLM prompting with function‑calling schema, structured reasoning templates |
| Tool / Retrieval Layer | Provide static knowledge (document store) or fresh data (authoritative API) | Azure Cognitive Search, public REST endpoints, token‑protected credit‑bureau API |
| Governance & Auditing | Record every step, version‑control prompts, certify compliance checks | Write‑once log storage, signed manifests, CI linting of workflow definitions |
| Cost & Latency Monitor | Track token usage, external‑API count, per‑step latency | OpenTelemetry exporters, custom metric dashboards |
Python Decision Helper (Teaching‑Only)
# decision_helper.py – pure stdlib, no external packages
import json
from pathlib import Path
from typing import Literal, TypedDict
class DecisionInput(TypedDict):
"""Minimal data required to pick workflow vs. agent."""
steps_known: bool # True if the entire sequence can be enumerated
tools_enumerated: bool # True if every tool can be listed up‑front
live_value_needed: bool # True if an authoritative API must be called
dynamic_subtasks: bool # True if request may spawn unknown sub‑tasks
def choose_strategy(data: DecisionInput) -> Literal["workflow", "agent", "hybrid"]:
"""
Return the recommended execution style.
* `workflow` – fully deterministic pipeline
* `agent` – pure agentic control
* `hybrid` – deterministic skeleton with optional runtime API or agent
"""
# Basic validation – fail fast if the contract is broken
assert isinstance(data["steps_known"], bool), "steps_known must be bool"
assert isinstance(data["tools_enumerated"], bool), "tools_enumerated must be bool"
assert isinstance(data["live_value_needed"], bool), "live_value_needed must be bool"
assert isinstance(data["dynamic_subtasks"], bool), "dynamic_subtasks must be bool"
if data["steps_known"] and data["tools_enumerated"]:
# All actions are known → deterministic flow
return "workflow"
if data["dynamic_subtasks"]:
# Content can generate new branches → need agentic reasoning
return "agent"
# Mixed case – known skeleton but may need live data or optional tool selection
return "hybrid"
# -------------------------------------------------
# Example usage (for teaching only – not part of production)
if __name__ == "__main__":
example = {
"steps_known": True,
"tools_enumerated": True,
"live_value_needed": False,
"dynamic_subtasks": False,
}
print(json.dumps({"strategy": choose_strategy(example)}))
Teaching‑Only Note – Production systems should encode this decision in a CI‑validated configuration file rather than an ad‑hoc script.
Architectural Decision Records (ADRs)
ADR 1 – Introducing an Agent for Policy Queries
Context
A fintech onboarding pipeline executes three fixed steps (identity → credit → welcome email). Occasionally, a regulator submits a policy_query that does not fit the fixed path.
Decision
Add an optional agent that is triggered only when the incoming payload contains a policy_query field. The agent will invoke a policy‑search tool, retrieve the relevant text, and attach it to the final output.
Consequences
- The core majority of requests remain in a deterministic workflow, preserving auditability.
- New logs capture the agent’s chosen tool, LLM prompt, and tool response, enabling traceability.
- Latency impact is limited to the subset of requests that require the agent.
Acceptance Criteria
- Agent‑enabled paths generate a log entry that records the selected tool, the exact prompt sent to the LLM, and the tool’s raw response.
- All agent‑generated outputs are stored with a cryptographic hash for integrity verification.
- CI pipeline includes unit tests for both “with query” and “without query” scenarios, and validates that the workflow remains deterministic when the agent is not invoked.
ADR 2 – Handling Live Credit‑Limit Values
Context
The onboarding flow must embed the applicant’s current credit limit, which changes frequently. A stale document store could return an outdated figure.
Decision
Expose a tool in the workflow that calls the credit‑bureau’s authoritative REST endpoint. The workflow pauses, fetches the live limit, and continues deterministically. No caching of the numeric value is permitted.
Consequences
- Guarantees freshness of a critical compliance datum.
- Introduces a single external API call per onboarding, which is observable in cost‑monitoring dashboards.
- Enables deterministic testing by mocking the API response within a test harness.
Acceptance Criteria
- Integration tests with a mock endpoint produce the same structural response shape as the real service.
- Production logs record request‑ID, endpoint URL, response timestamp, and the returned numeric value.
- Any failure to reach the API aborts the workflow with a defined error code and escalates to a human reviewer.
Evaluation & Maintenance Checklist
-
Functional correctness
- ✅ Deterministic steps produce identical output for identical inputs (regression suite).
- ✅ Agent‑enabled paths have mocked‑LLM tests covering tool selection logic.
-
Governance
- ✅ Prompt templates are version‑controlled, signed, and reviewed.
- ✅ Business rules (e.g., “identity verification before credit check”) live in code, not in LLM prompts.
-
Cost visibility
- ✅ Token usage per step logged to a cost‑center dashboard.
- ✅ External‑API call count tracked; alerts trigger on abnormal spikes.
-
Latency observability
- ✅ End‑to‑end latency recorded; thresholds defined per SLA.
- ✅ Separate latency metric for agent loops to bound their impact.
-
Knowledge freshness
- ✅ Retrieval index (Azure Cognitive Search) refreshed on a schedule aligned with policy updates.
- ✅ Live‑value endpoints re‑validated after any vendor version change.
-
Model updates
- ✅ Prompting is the first line of defence; LoRA fine‑tuning is applied only after a documented gap analysis shows prompting insufficient.
- ✅ When LoRA is applied, a full regression suite on pre‑existing deterministic tests is run; behavior preservation is not assumed.
-
Security & Auditing
- ✅ Secrets stored in a vault; never hard‑coded.
- ✅ Execution logs are immutable, encrypted, and retained per compliance window.
References
- Microsoft Retrieval‑Augmented Generation concepts – https://learn.microsoft.com/en-us/azure/foundry/concepts/retrieval-augmented-generation
- “LoRA: Low‑Rank Adaptation of Large Language Models” – https://arxiv.org/abs/2106.09685
Top comments (0)