The multi-agent setup added 3-4 seconds of latency and cost 40% more tokens with no measurable quality improvement. A single agent with a large context window delivered the same results more efficiently, which is why collapsing multi-agent architectures is worth considering before adding complexity.
Plan then Execute means first calling the LLM to generate a structured JSON plan of steps with tool names and inputs, validating that plan against a schema, and only then executing each step sequentially with full error handling. Separating planning from execution makes failures easier to catch early and prevents the agent from taking irreversible actions based on a malformed plan.
Implement a per-session tool call counter and abort the agent after a maximum number of calls — the post uses a limit of 20. Logging when a loop occurs is equally important because it typically signals either a broken tool or an impossible instruction that needs to be corrected.
Agents deliver genuine value for data aggregation, report generation, form and document processing, internal workflow automation, and personalized content generation with memory. They still struggle with external tools that have flaky APIs, multi-step financial transactions, and any scenario where the failure mode is catastrophic.
The post uses structured logging with a correlation ID that spans the entire agent turn, combined with Langfuse — an open-source LLM observability tool that captures trace data from LLM calls and tool executions. This combination makes it possible to trace exactly where in a workflow a failure occurred, which is critical because agent failures can happen at any step.
2025 has been the year everyone talked about AI agents, and the year most AI agent projects failed in production. I've built two agent workflows — one for my AI Gymbro fitness app and one as a DevOps automation experiment at Commsult. The honest truth: most AI agent hype is about demos that work perfectly in controlled conditions and break the moment a real user interacts with them. Here's what actually works.
The 2025 Stack Overflow Developer Survey found that 42% of developers had experimented with AI agents, but only 18% reported using them in production workloads. The gap between experimentation and production is real, and it's primarily an engineering problem, not a model capability problem.
For my AI Gymbro workout planning feature, I started with a multi-agent setup: one agent for exercise selection, one for periodization, one for user preferences synthesis. After two weeks, I collapsed it to a single agent with a large context window. The multi-agent approach added 3-4 seconds of latency and cost 40% more tokens with no measurable quality improvement.
Every agent workflow needs three things: retry logic for transient failures, hard timeouts so a stuck agent doesn't hang the user indefinitely, and fallback behavior when the agent can't complete the task. My production setup: 3 retries with exponential backoff, 30-second hard timeout per agent turn.
Production AI Agent Architecture (2025)
User Request
│
▼
┌─────────────────────────────────────┐
│ Orchestration Layer (Node.js) │
│ - State management │
│ - Retry logic (3x exp backoff) │
│ - 30s hard timeout per turn │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Plan-Validate-Execute Pattern │
│ │
│ 1. Generate Plan (LLM call) │
│ → [{tool, args}, ...] │
│ 2. Validate Plan (schema check) │
│ → Catch bad tool names early │
│ 3. Execute Steps (sequential) │
│ → Each step: tool + error hdlr │
└──────────────┬──────────────────────┘
│
┌───────┼───────┐
▼ ▼ ▼
Tool A Tool B Tool C
│ │ │
└───────┼───────┘
│
▼
┌─────────────────────────────────────┐
│ Observability (Langfuse) │
│ - Trace ID per session │
│ - Token counts per call │
│ - Tool success/failure rate │
└─────────────────────────────────────┘The most reliable agent workflow pattern I've found for 2025 is the 'Plan then Execute' approach: first call the LLM to generate a structured plan (a JSON array of steps with tool names and inputs), validate the plan against a schema before executing, then execute each step sequentially with full error handling.
The quality of your tools determines the quality of your agent. A well-designed tool is narrow in scope, has clear error messages, and validates its own inputs before execution. My tool design rules: every tool returns a structured JSON response with a 'success' field, error tools always include an 'error_code' and 'suggestion' field.
Agent workflows are notoriously hard to debug because the failure can happen anywhere. I use structured logging with a correlation ID that spans the entire agent turn. Langfuse (open-source) is excellent for this — it captures trace data from LLM calls and tool executions.
// Plan-then-Execute agent pattern — TypeScript
interface AgentStep {
tool: string
args: Record<string, unknown>
}
async function runAgent(userMessage: string, tools: Tool[]) {
// Step 1: Generate plan
const planResponse = await llm.generate({
prompt: `Given the tools available, create a step-by-step plan to: ${userMessage}
Return ONLY a JSON array: [{"tool": "tool_name", "args": {...}}, ...]`,
responseFormat: "json",
})
// Step 2: Validate plan
const steps: AgentStep[] = JSON.parse(planResponse)
const validTools = new Set(tools.map(t => t.name))
for (const step of steps) {
if (!validTools.has(step.tool)) {
throw new Error(`Unknown tool: ${step.tool}`)
}
}
// Step 3: Execute steps
const results: unknown[] = []
for (const step of steps) {
try {
const tool = tools.find(t => t.name === step.tool)!
const result = await tool.execute(step.args)
results.push({ step, result, success: true })
} catch (error) {
results.push({ step, error: String(error), success: false })
break // Stop on first failure
}
}
return results
}The most reliable agent workflows in 2025 include strategic checkpoints where the agent pauses and asks the user to confirm before proceeding. For destructive or expensive operations, always implement a confirmation step. In my AI Gymbro app, when the agent wants to replace a user's entire training plan, it shows a summary of changes and asks for confirmation.
Some models can get stuck in tool-calling loops — calling the same tool repeatedly with slightly different arguments. Always implement a per-session tool call counter and abort the agent after a maximum number of calls (I use 20). Log the loop when it happens — it usually indicates either a broken tool or an impossible instruction.
The architecture that's working in production: a thin orchestration layer (Node.js) that manages state and handles retries, a single primary LLM call per user turn, a set of 8-12 narrow well-typed tools, structured output enforcement via tool use/JSON mode, a plan-validate-execute pattern, and full observability via Langfuse.
The use cases where agents deliver genuine, reliable value: data aggregation and report generation, form and document processing, internal workflow automation, and personalized content generation with memory. The use cases that still struggle: anything requiring external tools with flaky APIs, multi-step financial transactions, and anything where the failure mode is catastrophic.