AI Automation
Place a bounded AI step in a reliable workflow with explicit state, human review, safe retries and recovery.
Before you start: AI agents and tool use · Basic JavaScript. Reading time is an estimate; allow extra time for practice.
What you’ll learn
- Choose a bounded AI step inside a deterministic workflow.
- Separate generated proposals, approval and execution.
- Handle retries without repeating side effects.
- Plan audit records, recovery and evaluation for an automation.
On this page
Automate a task with a clear boundary
Consider a help desk that receives an email and prepares a draft response. The workflow can validate the message, ask a model to suggest a category and draft, then send the result to a reviewer. Receiving an email, creating a draft and sending it are distinct actions. Only the middle step needs language generation.
Use conventional code for predictable rules such as required fields, destination restrictions and account permissions. An agent can choose among tools dynamically; a workflow follows explicit steps. Choose the simpler workflow when the sequence is known. Allowing a model to invent its next action creates extra failure modes without necessarily improving the task.
Make the workflow state explicit
Give each request a stable identifier and track states such as received, drafting, review-required, approved, sent and failed. A timeout while drafting is different from a timeout while sending. In the second case, the message may already have reached the provider even though the response was lost.
Store enough information to resume safely: the input version, approved draft version, recipient, action identifier and last confirmed outcome. If someone edits the draft or recipient after approval, require a new approval. Approval of one payload is not permission to execute an arbitrary later payload.
Give retries the same identity
Idempotency means that repeating the same logical request does not repeat its side effect. A stable request key helps a server recognize a retry. If every retry creates a new key, the receiver cannot know it belongs to the earlier operation. Scope keys to the caller and action, and reject reuse with a different payload.
This local example demonstrates the contract with a Map. It is deliberately synchronous and has no email provider. A real service needs durable storage, concurrency control and an atomic relationship between its idempotency record and the operation. When an external provider performs the side effect, use its idempotency support or reconcile delivery before retrying.
const completed = new Map();
let deliveries = 0;
function sendApproved(key, recipient, text) {
const payload = JSON.stringify({ recipient, text });
if (completed.has(key)) {
const previous = completed.get(key);
if (previous.payload !== payload) throw new Error('Key reused with different payload');
return previous.receipt;
}
const receipt = 'receipt-' + (++deliveries); // Simulated side effect only.
completed.set(key, { payload, receipt });
return receipt;
}
const a = sendApproved('job-1:send-v1', 'john@example.test', 'Draft approved');
const b = sendApproved('job-1:send-v1', 'john@example.test', 'Draft approved');
if (a !== b || deliveries !== 1) throw new Error('Repeated delivery');
let rejected = false;
try { sendApproved('job-1:send-v1', 'james@example.test', 'Changed'); }
catch { rejected = true; }
if (!rejected) throw new Error('Payload mismatch accepted');
console.log('One simulated delivery; mismatched retry rejected');The repeated request returns the same receipt. Restarting this program loses the Map, so it is a teaching fixture, not production-safe delivery storage.
Bound retries and recover visibly
A validation failure will not be repaired by sending the same invalid input again. Retry only eligible transient failures, with a limited count, delay and total deadline. After the limit, move the job into a visible failure queue with a reason a person can act on. An endless retry loop can consume money and hide a broken integration.
Do not label an uncertain provider response as definitely failed or definitely sent. Record the uncertainty, look up the action by its stable identifier where supported, and reconcile. Test failures before the provider call, after it accepts the request and before your application records the response.
Evaluate the automation as a system
Measure draft usefulness, incorrect classifications, reviewer corrections, duplicate actions and time to recovery. A model-only score misses a workflow that drafts well but sends twice. Include adversarial message text and requests outside the approved scope in your test set.
Audit logs should record which input and approved action versions were used, without storing unnecessary sensitive content. Restrict access and retention. Start with review-required operation and expand automation only when there is evidence for that specific task; passing a few examples is not proof of safe autonomous behavior.
Try it yourself
Draw the state transitions for the help-desk draft workflow. Add what happens if sending succeeds but its response is lost, and if the draft is edited after approval.
Show hint
Keep the send operation identity stable across retries. Treat a changed approved payload as a new decision. Explain who can release an uncertain or failed job and what evidence they need.
Check your understanding
4 questions to revisit the ideas. No score is saved, and you can retry. This is separate from Skill Quiz; it does not award XP or unlock guides.
Sources & further reading
Primary references for the concepts in this guide. Examples and exercises are illustrative; verify provider-specific behaviour against the version you use.