Module 5: Agents and Reliability · 40 min

Agents vs. Scripts: Choose the Simplest Reliable System

Learning goal

Turn this lesson into one checked practice output

By the end, you should be able to explain the core idea behind “Agents vs. Scripts: Choose the Simplest Reliable System” in your own words, apply it to one small real or sample task, and identify what still needs human review.

  1. 1

    Learn

    Read the 40-minute lesson without copying an output blindly.

  2. 2

    Try

    Use a small, non-sensitive example that you can inspect line by line.

  3. 3

    Review

    Check facts, fit, and risk; save one improvement note for next time.

Direct answer

Use a script when the steps and rules are known. Add a model call when one step requires interpreting unstructured language, images, or documents. Use an agent only when the system must choose among tools or adapt the sequence of multiple steps based on what it discovers. Start at the simplest level that can meet the requirement, because every extra degree of autonomy creates more paths to test, observe, secure, and pay for.

An agent is not automatically more advanced than a script. A reliable scheduled script that saves a team two hours each day is professional automation. An agent that loops through tools without clear stop conditions is an expensive demo.

The three levels

Level 1: deterministic script

Inputs follow a known schema, rules are explicit, and the same input should take the same path. Examples include renaming files, validating CSV columns, calculating invoice totals, sending a reminder at a fixed time, or calling an API after a form submission. Ordinary code gives you exact conditions, straightforward tests, and predictable cost.

Level 2: model-assisted workflow

The sequence remains controlled by code, but a model performs one bounded judgement: classify a support message, extract fields from a receipt, summarize a document, or draft a response. The model returns a structured result; code validates it and chooses the next step. This covers a large share of useful business AI without an open-ended agent loop.

Level 3: bounded agent

The application gives the model a defined goal and a small tool set. The model may decide which tool to call next, inspect the result, and continue until a stop condition or approval point. This is justified when the next correct step cannot be fully known in advance—for example, investigating a support incident across a knowledge base, order system, and status service. Even here, permissions, budgets, maximum steps, and side effects remain controlled by application code.

OpenAI's current Agents guide makes the ownership choice explicit: use the Responses API when your application should own the loop, and the Agents SDK when you want the SDK to manage recurring tool calls, handoffs, sessions, tracing, guardrails, or resumable approvals. That is an implementation choice after you establish that an agent is necessary.

A decision test before you build

Ask these questions in order:

  1. Can ordinary code express the rule accurately?
  2. Is the uncertain part only one classification, extraction, ranking, or draft?
  3. Does the system need to discover which step comes next?
  4. Are the available tools narrow, typed, and safe?
  5. Can you state a stop condition, step budget, time budget, and escalation rule?
  6. Can a reviewer reconstruct what happened from logs or traces?
  7. Is the expected improvement worth the extra latency, operational risk, and evaluation work?

If question one is yes, use a script. If question two is yes, use a model-assisted workflow. Move to an agent only when questions three through seven have credible answers.

Worked build: handling ecommerce return requests

A Daraz-style seller receives a return form with order ID, delivery date, reason, requested remedy, and optional message. The first prototype is often pitched as a “returns agent.” Break the job apart:

  • Validate required fields: deterministic code.
  • Check whether the order exists: deterministic API call.
  • Calculate days since delivery: deterministic code.
  • Look up the applicable policy: deterministic retrieval with version filters.
  • Classify an unstructured customer explanation: bounded model call.
  • Decide whether the case is automatically eligible: deterministic rules.
  • Draft a courteous reply: bounded model call using verified facts.
  • Approve a refund above a threshold: human decision.

There is no reason for an agent to invent this sequence. A controlled workflow is easier to test and safer around money.

Here is a minimal runnable JavaScript version of the deterministic spine:

function routeReturn({ deliveredAt, reason, amountPkr, orderFound }) {
  const allowedReasons = new Set(["damaged", "wrong_item", "missing_parts", "changed_mind", "other"]);

  if (typeof orderFound !== "boolean") {
    return { state: "ESCALATE", reason: "INVALID_ORDER_STATUS" };
  }
  if (!orderFound) return { state: "ESCALATE", reason: "ORDER_NOT_FOUND" };
  if (!allowedReasons.has(reason)) {
    return { state: "ESCALATE", reason: "INVALID_RETURN_REASON" };
  }
  if (!Number.isFinite(amountPkr) || amountPkr < 0) {
    return { state: "ESCALATE", reason: "INVALID_AMOUNT" };
  }

  const ageDays = Math.floor((Date.now() - Date.parse(deliveredAt)) / 86_400_000);
  if (!Number.isFinite(ageDays) || ageDays < 0) {
    return { state: "ESCALATE", reason: "INVALID_DELIVERY_DATE" };
  }
  if (ageDays > 14) return { state: "REVIEW", reason: "OUTSIDE_POLICY_WINDOW" };
  if (reason === "changed_mind") return { state: "REVIEW", reason: "POLICY_CHECK" };
  if (reason === "other") return { state: "REVIEW", reason: "UNCLASSIFIED_REASON" };
  if (amountPkr > 20_000) return { state: "APPROVAL", reason: "HIGH_VALUE" };
  return { state: "ELIGIBLE", reason: "RULES_PASSED" };
}

console.log(routeReturn({
  deliveredAt: new Date(Date.now() - 5 * 86_400_000).toISOString(),
  reason: "damaged",
  amountPkr: 7_500,
  orderFound: true,
}));

The thresholds here are fictional for the lab; a real seller must encode its approved current policy. A model can classify a free-text reason into a fixed enum, but the code should validate that enum and handle uncertainty. It should not be allowed to call issueRefund merely because the customer's message sounds convincing.

When might an agent become justified? Perhaps an exception investigator must look up shipment scans, ask a courier-status tool, retrieve a policy clause, identify contradictory records, and assemble an evidence packet. Even then, let the agent investigate, not transfer money. Give read-only tools by default and place a human approval gate before the side effect.

Tool design decides agent quality

Tools should do one understandable job, accept a strict schema, return structured results, and enforce permissions internally. Prefer get_order_status(order_id) over run_sql(query). Prefer draft_refund_case(...) over manage_customer(...). Tool names and descriptions help the model choose, but authentication and authorization must live in code.

Separate read tools from write tools. Log every call. Set timeouts. Return typed errors such as NOT_FOUND, TEMPORARY_FAILURE, and FORBIDDEN. Define whether a call is safe to retry. An agent cannot compensate for ambiguous tool contracts.

Failure cases to test

  • The agent repeats the same search because no maximum step count exists.
  • Two tools overlap, and the model chooses the risky write tool instead of the read tool.
  • A user message contains instructions to ignore policy and trigger a refund.
  • The model returns prose where the application expected structured arguments.
  • A tool times out after completing a side effect, and the agent retries it.
  • The agent reaches a plausible conclusion from incomplete evidence rather than escalating.
  • A multi-agent design adds handoffs but no measurable improvement over one controlled workflow.
  • A cheap-looking model choice increases retries and total cost per successful task.

🇵🇰 Pakistan Angle

The simplest reliable architecture is especially valuable where mobile connections, load-shedding, imported-service costs, and small teams shape daily operations. A deterministic job can queue locally and resume after connectivity returns. A long agent loop may lose state midway, consume unnecessary tokens, or leave a staff member unsure whether a WhatsApp message or order update actually happened.

Start with one painful workflow in a real Pakistani operating context: reconciling COD orders, formatting marketplace listings, triaging customer messages, or preparing a sales follow-up draft. Keep currency rules, local holidays, branch differences, and Urdu or Roman Urdu inputs in explicit tests. Do not automate consequential employment, credit, medical, or payment decisions just because an agent can call the relevant tool. Human accountability matters more than a clever demo.

Hands-on deliverable

Choose one workflow and create a system-choice pack:

  • a step-by-step task map;
  • a label for every step: code, model, retrieval, tool, or human;
  • three candidate designs: script, model-assisted workflow, and agent;
  • a scored decision table covering reliability, latency, cost, security, observability, and maintenance;
  • one runnable deterministic spine with mocked external calls;
  • a tool list with schemas, read/write classification, retry safety, and permission owner;
  • a one-paragraph justification for the least complex design that meets the requirement.

Completion rubric

  • I can distinguish a deterministic script, a bounded model step, and an agent loop.
  • Every nondeterministic step has a reason ordinary code is insufficient.
  • Tool contracts are narrow, typed, permission-aware, and classified by side effect.
  • The design has maximum steps, timeouts, budgets, and escalation conditions.
  • High-impact writes require a deterministic rule or human approval.
  • I compared cost and reliability per completed task, not by novelty.
  • The simplest qualifying design is the one I selected.

Key takeaway: Professional AI engineering is knowing where model judgement helps—and refusing to add autonomy where ordinary code is clearer, safer, and easier to operate.

Sources

Self-check

Before you mark Lesson 5.1 complete

  • Can I explain “Agents vs. Scripts: Choose the Simplest Reliable System” without reading the lesson back word for word?
  • Did I complete the lesson’s practice step on a real or clearly labelled sample task?
  • Did I check the result for invented facts, private data, unsafe actions, and mismatch with the brief?