Home / Articles / Practical notes: AI Agents vs Traditional Backend Applications: What’s Actually

This article is published in English.

Practical notes: AI Agents vs Traditional Backend Applications: What’s Actually

Operable walkthrough of Practical notes: AI Agents vs Traditional Backend Applications: What’s Actually: contracts, checks, and drop-in code slots for teams shipping this pattern.

2450 words

Use this as an operator-facing rebuild of the ideas in “AI Agents vs Traditional Backend Applications: What’s Actually Different?”: clear stages, ordered code slots, and recovery notes that survive a handoff. The Overview stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Keep configuration outside application code. Environment files, secret stores, and feature flags belong in one place operators can audit without reading the whole graph.

1. Linear Pipelines vs. The Reasoning Loop

For the 1 Linear Pipelines vs stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state. Document the happy path and the recovery path together. Retries, human gates, and dead-letter handling are part of the product, not later polish. Prefer structured outputs with schema validation over free-form prose when the next step is code or a tool call.

Traditional Backends: The Static DAG

For the Traditional Backends The Static stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state. Prefer small, testable units over sprawling scripts. When a step fails, the failure should point at a single responsibility rather than a tangled pipeline. Put human approval on edges that spend money or change production data. Compile-time wiring does not equal business completeness.

[Request] ──> [Validate Input] ──> [Database Query] ──> [Transform Data] ──> [Response]
                     │
                     └── (Invalid) ──> [Return 400]

AI Agents: The ReAct Loop

For the AI Agents The ReAct stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state. Treat this stage as a contract between inputs and validated outputs. Name the artifacts, define success checks, and refuse silent partial completion. Put human approval on edges that spend money or change production data. Compile-time wiring does not equal business completeness. For the AI Agents The ReAct stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state. Keep configuration outside application code. Environment files, secret stores, and feature flags belong in one place operators can audit without reading the whole graph.

┌────────────────────────┐
                       ▼                        │
[Objective] ──> [LLM Evaluates State]           │
                       │                        │
             Does it need more info?            │
             ├── Yes ──> [Select Tool & Arguments]
             │                  │
             │           [Execute Tool] ────────┘
             │           (API, DB, Search)
             │
             └── No  ──> [Return Final Answer]

2. A Concrete Comparison: Support Ticket Automation

When working through the 2 A Concrete Comparison stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest. Document the happy path and the recovery path together. Retries, human gates, and dead-letter handling are part of the product, not later polish. Checkpoint after expensive steps. Resume should not re-bill the same LLM call when an operator retries a later node.

The Traditional Approach

When working through the The Traditional Approach stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest. Prefer small, testable units over sprawling scripts. When a step fails, the failure should point at a single responsibility rather than a tangled pipeline. Checkpoint after expensive steps. Resume should not re-bill the same LLM call when an operator retries a later node.

// Traditional Backend: Strict, deterministic logic
async function handleRefund(orderId: string, customerReason: string) {
  const order = await db.orders.findById(orderId);
  if (!order) {
    throw new NotFoundError("Order not found");
  }
  // Strict business rule written by an engineer
  const isEligible = order.status === "DELAYED" && order.daysDelayed > 5;

  if (!isEligible) {
    return { status: "rejected", reason: "Delay does not meet refund criteria." };
  }
  const refund = await paymentGateway.refund(order.paymentIntentId);
  await db.orders.update(orderId, { status: "REFUNDED" });
  await emailService.sendRefundNotice(order.customerEmail);
  return { status: "success", refundId: refund.id };
}

The Agentic Approach

When working through the The Agentic Approach stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest. Treat this stage as a contract between inputs and validated outputs. Name the artifacts, define success checks, and refuse silent partial completion. Checkpoint after expensive steps. Resume should not re-bill the same LLM call when an operator retries a later node. When working through the The Agentic Approach stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest. Keep configuration outside application code. Environment files, secret stores, and feature flags belong in one place operators can audit without reading the whole graph.

// Agent Loop: The model decides which tools to call
import { generateText, tool } from "ai";
import { z } from "zod";
const tools = {
  fetchOrder: tool({
    description: "Fetch order details and shipping history",
    parameters: z.object({ orderId: z.string() }),
    execute: async ({ orderId }) => db.orders.findById(orderId),
  }),
  issueRefund: tool({
    description: "Issue a monetary refund to the customer",
    parameters: z.object({
      paymentIntentId: z.string(),
      amount: z.number(),
      reason: z.string()
    }),
    execute: async (args) => paymentGateway.refund(args.paymentIntentId, args.amount),
  }),
  escalateToHuman: tool({
    description: "Escalate edge cases or physical damage to a support manager",
    parameters: z.object({ ticketSummary: z.string() }),
    execute: async ({ ticketSummary }) => supportDesk.createEscalation(ticketSummary),
  })
};
// The execution is governed by an evaluation loop
const response = await generateText({
  model: yourConfiguredLLM,
  tools,
  maxSteps: 5, // Prevents infinite execution loops
  prompt: `Customer Issue: "The package arrived on time, but the driver ran over my mailbox. Order #1234."
           Evaluate policy guidelines and take appropriate action.`,
});

3. Side-by-Side Architectural Differences

The 3 Side-by-Side Architectural Differences stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Document the happy path and the recovery path together. Retries, human gates, and dead-letter handling are part of the product, not later polish. Keep graph state flat and typed. Nested blobs hide which node wrote which field and break resume after interrupts.

4. What Happens Behind the Scenes: The Context Window as CPU Cache

The 4 What Happens Behind stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Prefer small, testable units over sprawling scripts. When a step fails, the failure should point at a single responsibility rather than a tangled pipeline. Keep graph state flat and typed. Nested blobs hide which node wrote which field and break resume after interrupts.

5. Failure Modes: Why Agents Are Harder to Maintain

The 5 Failure Modes Why stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Treat this stage as a contract between inputs and validated outputs. Name the artifacts, define success checks, and refuse silent partial completion. Keep graph state flat and typed. Nested blobs hide which node wrote which field and break resume after interrupts. The 5 Failure Modes Why stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Keep configuration outside application code. Environment files, secret stores, and feature flags belong in one place operators can audit without reading the whole graph.

The Infinite Loop

For the The Infinite Loop stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state. Document the happy path and the recovery path together. Retries, human gates, and dead-letter handling are part of the product, not later polish. Put human approval on edges that spend money or change production data. Compile-time wiring does not equal business completeness.

Hallucinated Tool Arguments

For the Hallucinated Tool Arguments stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state. Prefer small, testable units over sprawling scripts. When a step fails, the failure should point at a single responsibility rather than a tangled pipeline. Authenticate at the gateway and re-authorize at the data plane. A bearer token alone is not a tenancy boundary.

// Expected:
{ "customerId": "cust_123", "amount": 50 }
// What the model occasionally outputs under high temperature:
{ "user_id": "cust_123", "refund_value": "$50.00" }

Non-Deterministic Routing

For the Non-Deterministic Routing stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state. Treat this stage as a contract between inputs and validated outputs. Name the artifacts, define success checks, and refuse silent partial completion. Put human approval on edges that spend money or change production data. Compile-time wiring does not equal business completeness. For the Non-Deterministic Routing stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state. Keep configuration outside application code. Environment files, secret stores, and feature flags belong in one place operators can audit without reading the whole graph.

6. When to Use Which Architecture

When working through the 6 When to Use stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest. Document the happy path and the recovery path together. Retries, human gates, and dead-letter handling are part of the product, not later polish. Checkpoint after expensive steps. Resume should not re-bill the same LLM call when an operator retries a later node.

Use Traditional Backend Code When:

When working through the Use Traditional Backend Code stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest. Prefer small, testable units over sprawling scripts. When a step fails, the failure should point at a single responsibility rather than a tangled pipeline. Checkpoint after expensive steps. Resume should not re-bill the same LLM call when an operator retries a later node.

Use AI Agents When:

When working through the Use AI Agents When stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest. Treat this stage as a contract between inputs and validated outputs. Name the artifacts, define success checks, and refuse silent partial completion. Checkpoint after expensive steps. Resume should not re-bill the same LLM call when an operator retries a later node. When working through the Use AI Agents When stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest. Keep configuration outside application code. Environment files, secret stores, and feature flags belong in one place operators can audit without reading the whole graph.

The Production Sweet Spot: The Hybrid Architecture

The The Production Sweet Spot stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Document the happy path and the recovery path together. Retries, human gates, and dead-letter handling are part of the product, not later polish. Keep graph state flat and typed. Nested blobs hide which node wrote which field and break resume after interrupts.

[Incoming Request] ──> [Traditional API Gateway] ──> Authentication / Rate Limiting
                              │
                              ▼
                      [Standard Business Logic] ──> Fast DB Reads / Validation
                              │
                              ▼
                    [Targeted Agent Boundary]  ──> Handles unstructured task
                              │                    (Restricted to 3 safe tools)
                              ▼
                      [Standard Business Logic] ──> Validates agent output
                              │
                              ▼
[Final Response] <─── [Structured DB Write]

Conclusion

The Conclusion stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Prefer small, testable units over sprawling scripts. When a step fails, the failure should point at a single responsibility rather than a tangled pipeline. Keep graph state flat and typed. Nested blobs hide which node wrote which field and break resume after interrupts.

Operational checklist

When working through the Operational checklist stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest.

Record timings and token or query cost next to functional results. Cost visibility early prevents surprise bills when the path moves from demo to shared environments.

Checkpoint after expensive steps. Resume should not re-bill the same LLM call when an operator retries a later node.

Pin dependency versions and record the image digest that ran the demo. Reproducibility beats tribal knowledge.

Keep configuration outside application code. Environment files, secret stores, and feature flags belong in one place operators can audit without reading the whole graph.

Checkpoint after expensive steps. Resume should not re-bill the same LLM call when an operator retries a later node.

Before promoting the stack, freeze versions, capture a golden transcript for the critical path, and confirm rollback steps. Shared environments need rate limits, tenancy checks, and a clear owner for secret rotation. Prefer boring reliability over clever one-off demos.

Batch note for 0b07728dd3ea: keep provider keys out of the repo, set a per-session token ceiling, and store transcripts next to the eval fixtures so later model swaps stay comparable.