System designby Learnastra

System-design interview · Extended interviews

Design durable agent workflows

By Anup Rai

Run an AI-assisted business process across waits and crashes while keeping approved actions, saved progress and uncertain outcomes explicit.

You will learn to

  • Distinguish a model recommendation from an authorized external action.
  • Build a resumable workflow around durable states and activity results.
  • Recover a lost provider response without blindly repeating a purchase.

Practice in this chapter

8 interview questions with model answers and follow-ups.

Go to interview practice

Useful foundations: Distributed transactions and sagas · Idempotency, retries, and timeouts · Authentication, authorization, and tenant isolation

Workload and timing examples are interview assumptions.

01Design a business process that uses a model

An agent workflow is a process that uses a model to interpret information or propose a next step. The application still decides which tools exist, which actions are permitted and what counts as completion. A conversational transcript alone is not a reliable record of a purchase, approval or retry.

Ask which actions the model may propose, which need human approval, and what should happen if the vendor receives an order but its reply is lost. This design permits a fixed purchasing process, approval of exact terms and an explicit uncertain-submission outcome.

Our example buys ten laptops from one of three approved vendors. The model compares quotes and drafts a proposal. A human approves an exact proposal, and only then may the service submit the order. The workflow may wait thirty minutes for approval, survive worker restarts and report the final order identity. Payment settlement and arbitrary browsing are outside this scope.

The complete flow is save task → research quotes → save proposal → wait for approval → submit approved order → save result. This fixed sequence is intentionally enough for the interview. The model helps with research and explanation; it does not invent new privileges or freely change the workflow. A durable workflow means that progress survives a process crash and execution resumes from recorded state rather than starting the business action again.

02Functional requirements

Agree on what the service must do before choosing its components.

  1. Create and inspect tasks. Create a tenant/requester-owned purchase task, return its durable identity and show its phase, current proposal and any external order result.
  2. Research an allowed purchase. Compare quotes from the three approved vendors and draft a proposal for ten laptops. The model supplies bounded interpretation; trusted code checks commercial terms and policy.
  3. Review and approve exact terms. Let an authorized human review and approve the exact current proposal, with a documented expiry. Replacing the proposal or changing its terms invalidates earlier approval.
  4. Submit and audit an order. Submit only the authorized proposal, preserve the external action identity, record the provider’s result and expose reconciliation when the result is uncertain.
  5. Cancel at a defined boundary. Before submission admission, cancellation prevents the action from starting. After the provider may have accepted, any cancellation is a separate business operation. Payment settlement and arbitrary browsing are outside scope.

03Non-functional requirements

Use these hypothetical requirements for the worked interview. Confirm the assumptions with the interviewer; the numerical targets require testing and are not measured results. For latency, p95 and p99 mean that 95% and 99% of measured delays, respectively, are no greater than the reported value.

  1. Workload. Assume 100,000 starts/day, ten model calls and fifteen ordinary tool calls per task, with a thirty-minute average approval wait. Account separately for bursts, retries and vendor limits.
  2. Responsive control. Target task creation and status p95 below 300 ms. Measure research, approval wait and submission completion separately; an approval that may take hours cannot share a tiny end-to-end latency target.
  3. Durable progress. Saved task state and activity results must survive the selected database-node failure. Waiting tasks consume durable state and timers rather than blocked workers. Retain activity results, approvals and provider reconciliation records through the declared recovery window, and keep unresolved action evidence available until reconciled.
  4. Exact authorization. Submission must use the exact currently approved proposal, a stable action identity and current permission/budget checks. Tenant isolation, allowed vendors, bounded quantities/spend and approval/quote expiry apply even when the model recommends otherwise.
  5. Honest external outcomes. Provider idempotency and lookup determine recovery after a lost response. Report SubmissionUnknown when evidence is insufficient; do not claim canceled, completed or exactly-once remote execution merely because local workflow history is durable.
  6. Bounded execution and privacy. Limit steps, tokens, retries, elapsed time and provider concurrency per tenant/task. Separate model calls, vendor reads and submission capacity; keep credentials and unrestricted network access outside model control.

04Save each completed step before moving forward

Begin with an API, a relational database and one background worker. Creating task T81 commits its owner, inputs and initial state before returning its ID. The worker claims ready work, loads T81 and performs the next activity. An activity is one bounded operation, such as fetching a vendor quote or asking the model to compare saved quotes.

Save each successful activity result and advance the workflow state in a transaction. If the worker restarts after that commit, it reads the saved result instead of making the same model call again. If it crashes before recording a harmless quote read, that read may run again. Re-execution is acceptable only when the operation’s effects permit it.

After research, save proposal P8 and enter WaitingApproval. No worker remains blocked for thirty minutes; the database records the wait. An approval request validates the actor and proposal version, then makes the submission step eligible. A worker submits it using a stable external action key and records the provider’s order ID.

The API returns task status from durable state. A browser disconnect does not cancel or erase the purchase process. This baseline already explains asynchronous execution, restart recovery and the difference between a waiting task and a running worker.

Design diagramOne durable business process

Workers perform ready activities; the database holds waiting tasks and saved results.

One durable business processWorkers perform ready activities; the database holds waiting tasks and saved results. user to api: Create, inspect or approve; api to db: Save state and exact approval; db to worker: Claim ready step; worker to tools: Bounded activity or approved action; worker to db: Save result and next stateCreate, inspect or approveSave state and exact approvalClaim ready stepBounded activity or approvedactionSave result and next stateCLIENTRequester andapproverSERVICETask and approvalAPISTORETask history andproposalsWORKERActivity workerSERVICEModel and approvedvendorssyncasync
Read each connection in order
  1. syncCreate, inspect or approveRequester and approver → Task and approval API
  2. syncSave state and exact approvalTask and approval API → Task history and proposals
  3. asyncClaim ready stepTask history and proposals → Activity worker
  4. syncBounded activity or approved actionActivity worker → Model and approved vendors
  5. syncSave result and next stateActivity worker → Task history and proposals

05Separate running work from waiting tasks

Assume 100,000 task starts per day: approximately 1.16 starts/s on average. At ten model calls and fifteen ordinary tool calls per task, the averages are about 11.6 model calls/s and 17.4 tool calls/s. Peak bursts, retries and vendor rate limits require separate headroom.

With 3,000 input tokens and 500 output tokens per model call, average model demand is roughly 34,700 input tokens/s and 5,800 output tokens/s. Token volume and the number of active requests both matter when choosing provider quotas and worker concurrency. A fixed request count hides large prompts and long responses.

If approval takes thirty minutes on average, about 1.16 × 1,800 ≈ 2,083 tasks are waiting at any instant. They need durable rows and timers, not 2,083 blocked worker processes. The worker pool should scale with ready activities and external call latency.

At 200 saved events of 2 KB each, one task adds about 400 KB of history and 100,000 tasks add 40 GB/day before indexes and replication. Store large documents separately and reference immutable versions from history. Retention and redaction decisions should preserve the evidence needed for recovery without keeping every sensitive prompt forever.

06Give task, proposal and action separate identities

Create a task

POST /tasks
Request information Purpose
Scoped request key Identify the intended creation; save it with the result so a client retry returns T81.
Purchase requirements Describe the requested purchase, such as ten laptops in the worked example.

Task control operations

Operation Request or result
GET /tasks/T81 Return phase, current proposal, outstanding approval and any external result.
POST /tasks/T81/approve Name the exact proposal version being approved.
POST /tasks/T81/cancel Request the applicable cancellation behavior.

Durable workflow records

Record Information retained Purpose
Task Current state and version Coordinate the saved process.
ActivityResult Workflow step, inputs and saved result Recover completed work without unnecessarily executing it again.
Proposal Immutable purchase terms Identify the precise offer the human reviews.
Approval Authenticated approver and exact proposal representation Bind authority to those terms.
ExternalAction Stable action key, payload, status and provider order ID Recover one intended external purchase.

Proposal fields

Fields What approval covers
Vendor and item identifiers Who supplies which products.
Quantity How many items are being purchased.
Total amount and currency The commercial cost being approved.
Destination and quote expiry Where the order goes and how long the offer remains valid.

External action identity in the example

Task:        T81
Proposal:    P8
Action key:  T81-P8-submit

The key identifies one intended purchase attempt, not a worker process. A replacement worker must reuse it when recovering that action.

Use expected task versions or a database lock to prevent two workers from advancing the same state concurrently. This protects local records. It does not undo an external effect already performed by a worker whose lease expired, so external action identity remains necessary even with careful scheduling.

07Keep model output inside an explicit workflow

Research first gathers quotes through permitted read-only tools. The model receives those saved facts and returns a structured comparison. Validate required fields and business constraints before constructing P8. Model output is a proposal; trusted application code calculates totals, checks approved vendors and determines whether the next step is allowed.

Waiting for approval is a durable state with an expiry timer. The approval endpoint checks the caller’s authority and the exact current proposal. A sentence saying “approved” in a document or chat message is not an authenticated approval. If a vendor changes the price or quote validity expires, produce a new proposal and request new approval.

Before contacting the provider

  1. Recheck permission and terms. Validate applicable permission, budget and proposal validity.
  2. Save intent. Persist the exact outgoing action and its stable key.
  3. Submit. Only then contact the provider.

This creates a recoverable account of what the worker intended to send even if the response never arrives.

The model may explain why one quote is preferable, but it does not receive raw production credentials or construct unrestricted network requests. Application code checks permission and saves progress; the model compares the supplied facts and explains its proposal. Each responsibility can be tested separately.

08Add workers without losing the saved process

A durable work queue separates task admission from execution. Publish ready work through a transactional outbox or an equivalent database-backed queue so a committed task cannot disappear between saving it and enqueueing it. An outbox is a table of pending dispatch records written in the same transaction as the state change; a relay forwards them and may retry.

Workers claim activities with bounded leases and renew while running. On expiry, another worker can recover the activity from durable state. Local version checks reject stale state updates. A duplicate queue message first inspects the recorded step outcome instead of assuming another complete execution is required.

Use separate concurrency limits for model calls, vendor reads and order submission. One slow vendor should not consume the entire pool. Apply tenant quotas and bound retry counts, token budgets and elapsed time per task. Waiting approval tasks consume neither provider concurrency nor busy workers.

A workflow engine can supply timers, history and retry scheduling once those requirements justify it. It does not automatically solve provider idempotency or business approval semantics. Keep the same saved-state and external-action contracts when adopting an engine, and pin workflow versions so a code deployment does not reinterpret an old task unpredictably.

Design diagramDurable state coordinates workers, approvals and external actions

An API transaction saves task or approval state with ready work. The relay can repeat delivery IDs; workers recover recorded outcomes before continuing. Model calls propose bounded results, while separately authorized vendor actions use stable action identities. Waiting approvals remain in storage.

Durable state coordinates workers, approvals and external actionsAn API transaction saves task or approval state with ready work. The relay can repeat delivery IDs; workers recover recorded outcomes before continuing. Model calls propose bounded results, while separately authorized vendor actions use stable action identities. Waiting approvals remain in storage. user to api: Create, inspect or approve; api to db: Commit state and ready work; db to relay: Pending dispatch records; relay to queue: Publish activity IDs; queue to workers: Dispatch ready activities; workers to db: Claim, recover and save result; workers to model: Bounded interpretation; workers to vendors: Permitted read or approved actionCreate, inspect or approveCommit state and ready workPending dispatch recordsPublish activity IDsDispatch ready activitiesClaim, recover and save resultBounded interpretationPermitted read or approvedactionACTORRequester andapproverSERVICETask and approvalAPISTOREWorkflow state andoutboxWORKEROutbox relayQUEUEReady activitiesWORKERLeased activityworkersEXTERNALApproved languagemodelEXTERNALApproved vendorAPIssyncasync
Read each connection in order
  1. syncCreate, inspect or approveRequester and approver → Task and approval API
  2. syncCommit state and ready workTask and approval API → Workflow state and outbox
  3. asyncPending dispatch recordsWorkflow state and outbox → Outbox relay
  4. asyncPublish activity IDsOutbox relay → Ready activities
  5. asyncDispatch ready activitiesReady activities → Leased activity workers
  6. syncClaim, recover and save resultLeased activity workers → Workflow state and outbox
  7. syncBounded interpretationLeased activity workers → Approved language model
  8. syncPermitted read or approved actionLeased activity workers → Approved vendor APIs

09Recover the order whose response was lost

Lost-response trace for approved proposal P8

  1. Save the action. T81’s worker records T81-P8-submit.
  2. Send the purchase. The worker calls the vendor.
  3. The vendor accepts. It creates order O902.
  4. The response is lost. The connection breaks before the worker receives O902.

The saved action records what the worker was authorized to submit. It does not show whether the request reached the vendor or created an order.

If the provider supports durable idempotent submission, retry the same key and identical payload within its documented retention window. It should return the existing outcome instead of creating another order. If lookup by action key or client reference is available, query it and save the confirmed order identity. Provider guarantees must be verified; no generic HTTP retry supplies them.

If the provider cannot resolve the action safely, leave it SubmissionUnknown and reconcile through a controlled operator process. Do not invent a fresh key just to get a successful response. That would convert one uncertain purchase into a possible duplicate purchase.

This is the central recovery story. Saving workflow history prevents forgotten progress, but cannot make a remote side effect part of a local database transaction. The application needs provider cooperation or an honest uncertain state. “Exactly once” without that boundary obscures the business risk instead of solving it.

Request traceOrder accepted, response lost

The replacement worker recovers the same purchase identity.

Order accepted, response lostThe replacement worker recovers the same purchase identity. worker to db: Save T81-P8-submit; worker to vendor: Submit with stable key; vendor to worker: Creates O902; reply lost; worker to db: Recover unresolved action; worker to vendor: Lookup or retry same supported key; vendor to worker: Return existing O902, or unresolvedPARTICIPANTWorkerPARTICIPANTAction recordPARTICIPANTVendor1. Save T81-P8-submit2. Submit with stable key3. Creates O902; reply lost4. Recover unresolved action5. Lookup or retry same supported key6. Return existing O902, or unresolvedsyncreturn
Read each connection in order
  1. syncSave T81-P8-submitWorker → Action record
  2. syncSubmit with stable keyWorker → Vendor
  3. returnCreates O902; reply lostVendor → Worker
  4. syncRecover unresolved actionWorker → Action record
  5. syncLookup or retry same supported keyWorker → Vendor
  6. returnReturn existing O902, or unresolvedVendor → Worker

10Handle changes while a task is in progress

Before the service authorizes submission, canceling T81 saves a terminal state that blocks the purchase. Submission checks the current task version. If cancellation and submission race, the database accepts one state change first; that order determines whether submission was authorized, and the UI reports the result.

Once submission may have reached the provider, cancellation becomes a request to stop or reverse an order, subject to the vendor’s API and business rules. A successful local cancel button cannot prove an in-flight remote purchase vanished. Resolve the original action first, then perform any supported cancellation under its own tracked identity.

Changing quantity, vendor or destination creates a new proposal version. Approval for P8 does not authorize P9 even if both belong to T81. Similarly, an expired quote may require research and approval again rather than silently purchasing at a new price.

Retry read-only activities with bounded backoff, but classify failures. Invalid input is not repaired by ten retries, and an uncertain purchase is not equivalent to a failed quote read. Escalation, compensation and human review are explicit workflow outcomes. The simplest safe design makes those states visible rather than hiding them behind a generic retry loop.

11Test business boundaries and recovery evidence

Trace task, activity, proposal and action IDs across logs while redacting credentials and unnecessary personal data. Measure queue age, ready versus waiting tasks, activity latency, provider error rate, token/spend budgets, approval age and unresolved submissions. A high completion rate can conceal dangerous duplicates or stale approvals, so inspect those outcomes separately.

Test a worker crash before saving a quote, after saving a model result, while waiting for approval and immediately after a provider accepts an order. The expected recovery differs at each point. Also test duplicate queue messages, changed proposals, revoked approvers, expired quotes and exhausted provider idempotency retention.

Treat retrieved content and vendor descriptions as untrusted input. Instructions embedded in them cannot authorize a tool or change the allowlist. Tool gateways validate schemas and permissions; secrets remain in trusted service integrations. Sandboxed computations may help comparison, but a sandbox is not a substitute for authorizing the eventual purchase.

Deploy workflow changes with compatibility for existing histories or explicitly migrate them. Practice operational reconciliation using realistic provider evidence. The strongest final design is one the operator can explain after a timeout: what was approved, what may have been sent, what was confirmed, and which action is still safe to take.

12Check the design against its requirements

Before closing, check the final design against the agreed requirements. FR means functional requirement and NFR means non-functional requirement; the numbers refer to the lists above. These are proposed validation checks, not test results.

Requirement Mechanism in the final design Validation and remaining limit
FR 1, 2; NFR 1–3 Transactional saved state, activity results, durable dispatch and waiting timers let workers resume. Crash around an activity commit and leave 2,083 illustrative tasks awaiting approval. Verify no blocked worker per wait; load-test control p95 and recovery under node loss.
FR 3, 4; NFR 4 Immutable proposals, authenticated approvals and guarded submission recheck exact terms. Change quantity, expire a quote, revoke an approver and race workers. Require a valid current approval and one stable intended action.
FR 4; NFR 3, 5 External action records preserve the provider key and uncertain result for reconciliation. Lose O902’s reply; recover with the same supported key or lookup. If the provider cannot resolve it, require unknown status and operator review, not another purchase.
FR 5; NFR 4, 5 The task state transition orders cancellation against submission admission. Race cancellation before and after admission. Prevent a not-yet-admitted action; do not pretend a remote order already accepted has vanished.
NFR 6 Tool validation and separate tenant/provider budgets constrain model-driven work. Inject vendor-text instructions and exhaust one provider’s quota. Check credentials stay private and unrelated work can progress within measured capacity.

13Rapid revision

Rehearse the numbered functional requirements and non-functional targets first. Use this table to recall the mechanisms, then close with the requirements check above.

Remember: Lost purchase reply → recover the same action.

Prompt Recall the mechanism and limit
What makes a workflow durable? Saved state and activity results let replacement workers resume after a crash
Why save a waiting state? A thirty-minute approval wait needs a record and timer, not a blocked worker
What can the model approve? Nothing by itself; application policy and an authenticated person authorize actions
What does approval name? The exact unchanging proposal, including purchase terms and expiry
Why a stable external action key? Replacement workers must recover the same intended purchase
Does a lease prevent duplicate purchases? No; it coordinates workers but cannot undo an external purchase
What follows a lost vendor reply? Retry the provider-supported key or look up the result; otherwise report unknown
What does cancellation mean? Before submission is authorized it blocks the purchase; afterward reversal needs its own tracked action
What limits cost? Limit steps, tokens, retries, elapsed time and simultaneous provider calls

Close with: “I use a fixed durable workflow around the model. Saved proposals and authenticated approvals authorize exact actions. Workers can restart, but external effects recover through stable identities and provider evidence. When that evidence is insufficient, the workflow reports uncertainty instead of blindly buying again.”

Practise the interview questions

Say your answer aloud before opening the model answer. Then answer the follow-up and compare the reasoning.

Foundation · Question 1

What makes this more reliable than replaying a chat transcript?

Reveal a model answer

The service stores explicit workflow state, bounded activity results, exact proposals, authenticated approvals and external action identities. A restarted worker resumes from those facts instead of asking the model to reconstruct what happened.

What the answer must demonstrate: The service stores explicit workflow state, bounded activity results, exact proposals, authenticated approvals and external action identities.

Foundation · Question 2

Do 2,083 tasks waiting for approval require 2,083 workers?

Reveal a model answer

No. Waiting tasks are durable records with timers. Workers run ready activities and release capacity while approval is pending. Worker sizing follows active call demand and latency rather than the number of open tasks.

What the answer must demonstrate: No. Waiting tasks are durable records with timers.

Applied · Question 3

P8 was approved, but the vendor changes the price. May the agent submit?

Reveal a model answer

Not under the old approval. Validate the saved quote and exact proposal before admission; changed commercial terms require a new proposal and approval. Generated text saying the new price is acceptable does not authorize it.

What the answer must demonstrate: Not under the old approval. Validate the saved quote and exact proposal before admission; changed commercial terms require a new proposal and approval.

Applied · Question 4

The worker crashes after saving a model result. Should it call the model again?

Reveal a model answer

It should reuse the saved activity result and resume the next state. If the result was never committed, repeating a bounded read or generation may be acceptable; external purchases require a different recovery contract.

What the answer must demonstrate: It should reuse the saved activity result and resume the next state.

Applied · Question 5

The vendor accepted an order but its response was lost. What next?

Reveal a model answer

Recover the same action identity through the provider’s documented idempotent retry or lookup within its supported retention window. Save the confirmed order if found. If it cannot be resolved, report SubmissionUnknown and reconcile; a new key risks another order.

What the answer must demonstrate: Recover the same action identity through the provider’s documented idempotent retry or lookup within its supported retention window.

Follow-up · Question 6

Why is a worker lease insufficient to guarantee one purchase?

Reveal a model answer

An expired worker may already have sent the request, and a remote provider can act after local ownership changes. Leases and task versions coordinate local progress; a stable external action key handles duplicate submission where the provider supports it.

What the answer must demonstrate: An expired worker may already have sent the request, and a remote provider can act after local ownership changes.

Applied · Question 7

Can cancel always promise that no order was created?

Reveal a model answer

Only before submission has been admitted and sent. Afterward the action may already exist remotely. Resolve that action and use the vendor’s cancellation or compensation process under a tracked identity. The UI must distinguish these states.

What the answer must demonstrate: Only before submission has been admitted and sent.

Follow-up · Question 8

A retrieved vendor document tells the model to send credentials elsewhere. What stops it?

Reveal a model answer

Retrieved text is untrusted data. Tool gateways allow only validated operations, enforce current permissions and keep secrets in trusted integrations. The model cannot authorize a destination or grant itself a credential.

What the answer must demonstrate: Retrieved text is untrusted data. Tool gateways allow only validated operations, enforce current permissions and keep secrets in trusted integrations.

Blank-page exercise · 45 minutes

Build the answer yourself

Design an AI-assisted purchasing workflow that compares approved vendors, waits for human approval and safely handles a lost order response.

  • Agree the numbered functional requirements and non-functional targets, including the model’s role, exact approval, response time, durability and external uncertainty.
  • Draw the one-worker saved-state baseline.
  • Separate waiting tasks from active concurrency.
  • Model exact proposals and authenticated approvals.
  • Trace an accepted purchase with a lost reply.
  • Validate task control, approval, submission, cancellation, recovery, latency and budgets against the numbered requirements; state unresolved provider and retention limits.

Check that each component and design decision follows from your requirements and workload.

Recall the key ideas

Answer from memory before opening each card. Explain why the choice works and what it costs. Revisit missed cards tomorrow.

Design durable agent workflowsThe vendor creates O902 but its reply is lost. What may the replacement worker do?Recall first, then reveal

Recover the saved action using the same provider-supported key or a result lookup. If the provider cannot establish the outcome, keep it unknown for reconciliation rather than send a new purchase.

Lost purchase reply → recover the same action.

Return to lesson
Design durable agent workflowsWhy not use a fresh key after a purchase reply is lost?Recall first, then reveal

The first purchase may already exist. Recover its original action through the provider’s supported retry or lookup; a fresh key can create another order.

Unknown is a state

Return to lesson

Final revision

Summary and interview notes

Save progress so another worker can resume. Require approval for the exact purchase. If the vendor’s reply is lost, recover the original action through its supported retry or lookup; otherwise report the outcome as unknown.

Remember these points

  • Agree the numbered functional requirements and non-functional targets before designing components; validate the final design against them.
  • Saved activity results prevent unnecessary re-execution.
  • Approval binds an exact proposal.
  • Waiting tasks do not block workers.
  • Remote uncertainty needs a visible recovery state.

Interview tips

  • Use one lost-order-response story to defend the architecture.
  • Never use exactly-once as a replacement for the external provider contract.

Important qualifications

  • General autonomous planning and cross-system compensation protocols are optional extensions.

Continue after the core interview

Explore the advanced version

The advanced lesson keeps the full detailed design. Use these sections when you want to examine the stronger requirements and failure cases.

Technical references

Practice marks stay in this browser.