Complete "Lesson 2: Controlling Model Output with Structured Prompts" first to unlock this lesson.Go to previous lesson

From Single Prompts to Agent Workflows

A single prompt asks the model one thing and gets one answer. An agent workflow breaks a complex goal into multiple steps: the agent plans, calls a tool, reads the result, decides what to do next, and loops until the job is done. In web app development, this means an AI feature can fetch data, transform it, validate it, and respond to the user — all without a human writing every step by hand.

The shift is from "ask and answer" to "decide and act." Instead of one carefully crafted prompt, you design a loop: think, act, observe, repeat.

Core Building Blocks of an Agent Workflow

Every agent workflow, no matter how complex, is built from the same four pieces.

First, a system prompt that defines the agent's role, its available tools, and the rules for when to stop. Second, a list of tools the agent can call — functions like `fetch_user_data`, `send_email`, or `query_database`. Third, a memory or state object that carries information between steps so the agent does not forget what it already learned. Fourth, a control loop that feeds the agent's output back in as input until it signals completion.

Here is a minimal pattern in TypeScript showing the loop:

typescript
async function runAgent(goal: string) {
let state = { goal, steps: [], done: false };
while (!state.done) {
const decision = await llm.decide(state);
if (decision.action === "finish") {
state.done = true;
} else {
const result = await callTool(decision.action, decision.input);
state.steps.push({ decision, result });
}
}
return state.steps;
}

The agent sees `state`, decides what to do, the workflow executes the tool, and the result goes back into `state` for the next round.

flowchart showing the agent loop: agent decides, tool executes, result feeds back into agent state, loop until finish

State Management and Stop Conditions

State is what prevents the agent from being a goldfish. Each turn the agent should see: the original goal, a history of past actions and their results, and any constraints (like "do not spend more than 5 steps" or "stop if the API returns an error").

Stop conditions matter just as much as start conditions. Without them, an agent can loop forever or burn through your API budget. Common patterns include: the agent emits a special `finish` action, a step limit is reached, an error occurs and the workflow bails out, or a validation check confirms the goal is met. Pick at least one hard limit (like max steps) as a safety net even if the agent has a "natural" stop signal.

Chaining Calls vs Parallel Calls

Not every multi-step task needs a loop. Sometimes chaining is enough: the output of call A becomes the input of call B, with no decision-making in between. This is faster, cheaper, and more predictable.

Use a loop only when the next step depends on what the previous step returned. If you are summarizing a user review, then translating it, then emailing it — that is a chain. If you are searching three databases and merging results — that is parallel. If you are searching a database, checking if the result is empty, and then deciding whether to search a different source — that is a loop.

side-by-side comparison diagram of a linear chain (A to B to C) versus a loop with a decision branch

Practical Example: A Support Ticket Agent

Imagine a workflow that handles incoming support tickets. The agent reads the ticket, classifies it, checks the user's account, and either drafts a reply or escalates to a human.

typescript
async function handleTicket(ticketId: string) {
const ticket = await fetchTicket(ticketId);
const classification = await llm.classify(ticket.body);
if (classification.category === "billing") {
const account = await fetchAccount(ticket.userId);
const draft = await llm.draftReply(ticket, account);
await sendReply(ticket.userId, draft);
return { status: "replied", draft };
}
await escalateToHuman(ticketId, classification);
return { status: "escalated" };
}

This mixes chaining (classify then draft) with a branch decision. The agent is not "thinking" freely — it is following a script that uses the LLM at specific decision points. That is usually the right balance for production: deterministic flow, smart calls.

Common Mistakes and How to Avoid Them

Giving the agent too much freedom too early. Start with a fixed flow that calls the LLM at known decision points. Only add a free-form loop when you genuinely need dynamic behavior.

Forgetting to log state. Every step, every tool call, every result — log it. When something breaks at 2am, the log is the only way to see what the agent was thinking.

No retry or fallback logic. Tools fail. APIs time out. Build retries with backoff, and always have a fallback path — even if it is just "send the ticket to a human."

Letting state grow unbounded. Each turn the agent sees the full history. After 20 steps, that history is huge and expensive. Summarize or trim old steps once the conversation gets long.

Tổng kết

An agent workflow is a loop: the model decides, a tool executes, the result updates state, and the cycle repeats until a stop condition fires. State carries context between steps, and you always need both a natural stop signal and a hard limit. Start with chaining for predictable pipelines, and reach for a full agent loop only when the next step truly depends on the previous result. Log everything, retry failures, and trim state as it grows.

Lesson practice

Lesson Checkpoint

Review what you learned and get feedback on your work.

0/1
Answered · 0/1