{"slug": "agentic-workflows-that-survive-real-inputs", "title": "Agentic Workflows That Survive Real Inputs", "summary": "BizFlowAI engineer shares a production-tested pattern for building multi-agent workflows that survive real-world inputs. The key insight: decompose workflows into deterministic code steps and tightly scoped LLM calls, with strict input/output validation at every boundary. Tool selection accuracy drops from 96-99% with 3-5 tools to below 70% with 20+ tools, so the engineer recommends tool routing via a small dispatcher agent.", "body_md": "Most agent demos work because the demo input is clean. Real inputs are not. They arrive half-formed, with missing fields, contradictory context, PDFs that are actually images, and users who change their mind mid-thread. The gap between a working demo and a workflow that runs unattended for six months is almost entirely about how you decompose the problem and where you put the guardrails.\n\nI design multi-agent workflows daily at BizFlowAI, and the pattern below is the one I keep coming back to. It is not glamorous. It is the reason my content pipeline runs 24/7 without me babysitting it, and it is the reason my serverless AWS integrations hit SLA instead of paging me at 2am.\n\nBefore I touch an LLM SDK, I write the workflow as if agents did not exist. A boring sequence of functions with typed inputs and outputs. This is the single most useful exercise in agentic design, and it is the one most teams skip.\n\nHere is the decomposition I run on every new workflow:\n\nOn my ContentStudio pipeline, the flow looks like this:\n\n``` php\ntrigger (topic gap detected)\n  -> ResearchBrief        [LLM: judgment on angle + gap]\n  -> OutlineDraft         [LLM: judgment on structure]\n  -> DraftPost            [LLM: generation]\n  -> SEOAuditReport       [code: deterministic checks]\n  -> RevisedPost          [LLM: targeted rewrites only]\n  -> PublishPayload       [code: schema validation]\n  -> published (WordPress API)\n```\n\nNotice that four steps are code, three are LLM. In an earlier version I had the LLM doing the SEO audit and the publish payload assembly. It hallucinated slugs, invented canonical URLs, and once tried to publish to a site that did not exist. Moving those to deterministic code cut error rate to near zero and made the whole pipeline debuggable.\n\n**The rule I follow: an agent should be responsible for a decision, not for the plumbing around the decision.**\n\nTool selection is where most agent projects quietly go wrong. Teams give the agent 15 tools because \"more tools = more capable\" and then wonder why it picks the wrong one 30% of the time.\n\nMy working numbers, from actual production agents:\n\n| Tools available | Correct tool selection rate |\n|---|---|\n| 3-5 tools, tightly scoped | 96-99% |\n| 6-10 tools | 88-93% |\n| 11-20 tools | 70-82% |\n| 20+ tools | often below 70%, highly prompt-dependent |\n\nThese are directional numbers from my own pipelines, not a benchmark. But the pattern is real and it holds across model families. The mitigation is not a smarter model. It is **tool routing**: a small dispatcher agent that picks the sub-agent, and each sub-agent has 3-5 tools.\n\nWhen I write a tool spec, I treat it like a job description:\n\n`search_customer_by_email`\n\n, not `customer_lookup`\n\n.If you cannot write the \"when not to use it\" sentence, the tool is too broad. Split it.\n\nPrompt-level guardrails (\"do not make up customer names\", \"always validate the email\") are advisory at best. In production I treat them as backup, not primary defense. The primary defense is at the boundary of every step.\n\nThere are four boundary types where I always put guardrails:\n\n**1. Input validation on tool calls.** Every tool validates its input with a strict schema (I use Zod in TypeScript, Pydantic in Python) before doing anything else. If the agent hallucinates a field, the tool returns a structured error and the agent gets to retry with feedback. No exceptions, no silent coercion.\n\n**2. Output validation on LLM responses.** Every LLM call that produces structured output goes through a validator. If the structured output is required, I use the provider's structured output mode (Claude tool use, OpenAI response_format) and then re-validate. Belt and suspenders. I have caught model regressions this way.\n\n**3. Cost and loop caps.** Every workflow has a hard budget: max tokens, max tool calls, max wallclock. If it exceeds any of them, it fails loudly, writes to the dead-letter queue, and pages me. An agent that silently loops for 40 minutes and spends $80 is a bug you only find on the invoice.\n\n**4. Side-effect gates.** Any tool that writes to the real world (send email, publish post, create ticket, charge card) has a separate authorization check that is NOT part of the LLM prompt. It reads from a config or a feature flag. This is how you sleep at night when you give an agent write access.\n\nHere is a minimal side-effect gate pattern I use:\n\n```\nasync function publishPost(input: PublishInput, ctx: AgentContext) {\n  // 1. Schema validation\n  const parsed = PublishSchema.parse(input);\n\n  // 2. Authorization check (NOT in prompt)\n  if (!ctx.permissions.canPublishTo(parsed.siteId)) {\n    return { ok: false, error: \"unauthorized_site\" };\n  }\n\n  // 3. Idempotency: has this artifact already been published?\n  const existing = await db.publishedPosts.findOne({\n    contentHash: parsed.contentHash\n  });\n  if (existing) {\n    return { ok: true, alreadyPublished: existing.url };\n  }\n\n  // 4. Actual side effect, wrapped in retry with backoff\n  const result = await wpClient.publish(parsed);\n  await db.publishedPosts.insert({ ...parsed, url: result.url });\n  return { ok: true, url: result.url };\n}\n```\n\nFour things happen before we ever hit the WordPress API. Every one of them has caught a real bug in production.\n\nYou cannot debug an agent workflow by reading logs after the fact if you did not instrument it up front. And you will need to debug it, because real inputs will do things you did not predict.\n\nThe minimum I ship with every workflow:\n\n`grep`\n\non.I use a simple Postgres schema for this. Not because it is fancy, but because I can write SQL against it when something breaks. When a run fails, I can pull the entire history in one query and replay it.\n\nThe metric I actually watch, across every workflow I run:\n\n| Signal | Why it matters |\n|---|---|\n| Success rate per workflow version | Regressions after prompt changes |\n| p50 / p95 latency per step | Which step is the bottleneck |\n| Cost per run (tokens + tools) | Unit economics, budget alerts |\n| Tool call error rate by tool | Which tool spec is confusing the agent |\n| Retry rate per step | Silent flakiness |\n| Human-intervention rate | The honest measure of autonomy |\n\nThe last one is the one nobody wants to look at. If a workflow needs a human 15% of the time, it is not autonomous, it is assisted. Fine, but call it what it is and price the ROI accordingly.\n\nAfter building enough of these, the failure modes rhyme. Design against them from day one.\n\n**Confident-wrong outputs.** The agent produces something plausible but wrong. Mitigation: a validation step that checks the output against ground truth (a DB lookup, a rules check, a second-model critique for high-stakes outputs). For my content pipeline, every draft goes through a deterministic SEO/AEO audit before it can be published. If it fails, it goes back to a targeted revision agent with the specific failures listed.\n\n**Silent tool failures.** The tool returns a 200 with an empty body, or a partial success that looks fine. Mitigation: tools must return an explicit `{ ok: boolean, ... }`\n\nshape and the agent's tool-use loop must treat `ok: false`\n\nas a first-class case, not a string to interpret.\n\n**Runaway loops.** The agent keeps calling the same tool with slightly different inputs. Mitigation: track recent tool calls in the loop and inject a system message when the same tool+input hash repeats. Also: the wallclock cap from earlier.\n\n**Context rot.** Long conversations where the agent forgets or contradicts earlier decisions. Mitigation: don't run one long conversation. Break the workflow into steps with fresh context windows and pass forward only the artifact each step needs. This is the single biggest reliability win in multi-step agent design.\n\n**Model drift.** The vendor updates the model and your prompts subtly break. Mitigation: pin model versions in code, and run a small eval set on every deploy. Even 20 representative cases will catch most regressions.\n\nThe order matters. This is what I actually do:\n\nSteps 1-6 take about 60% of the total build time and prevent about 90% of the incidents. Skipping them is how you end up with a demo that crashes in week two.\n\nThe trending mistake I see repeatedly: teams pick a framework (LangGraph, CrewAI, whatever is fashionable this quarter) before they have written the pipeline as a boring function. The framework is not what makes it work. The decomposition is.\n\nIf you are building an agentic workflow that has to run against real production inputs, and you want a second set of eyes on the decomposition or the guardrails, I am open to a few consulting engagements this quarter. Reach out at [lazar-milicevic.com/#contact](https://lazar-milicevic.com/#contact), or read more on the [blog](https://lazar-milicevic.com/blog) for related posts on RAG evaluation, agentic context, and shipping agents that survive contact with users.", "url": "https://wpnews.pro/news/agentic-workflows-that-survive-real-inputs", "canonical_source": "https://dev.to/lamingsrb/agentic-workflows-that-survive-real-inputs-4emd", "published_at": "2026-07-30 07:17:39+00:00", "updated_at": "2026-07-30 07:31:22.832956+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "mlops"], "entities": ["BizFlowAI", "AWS", "WordPress", "Claude", "OpenAI", "Zod", "Pydantic"], "alternates": {"html": "https://wpnews.pro/news/agentic-workflows-that-survive-real-inputs", "markdown": "https://wpnews.pro/news/agentic-workflows-that-survive-real-inputs.md", "text": "https://wpnews.pro/news/agentic-workflows-that-survive-real-inputs.txt", "jsonld": "https://wpnews.pro/news/agentic-workflows-that-survive-real-inputs.jsonld"}}