Tools and the Agent LoopThe ReAct loop, and createAgent
No narration yet
Module 2, Lesson 225 min

The ReAct loop, and createAgent

The ReAct loop, from first principles: call the model; if it requested tools, execute them and append the results as tool messages; call the model again; repeat until it stops requesting tools and returns a final answer. Reason, act, observe, repeat. That loop is all "agent" means.

createAgent with structured output
import { createAgent, tool, toolStrategy } from "langchain";

const agent = createAgent({
  model,
  tools: [snapshotInbox, applyPlan],
  systemPrompt: "You triage the Todoist inbox. Emit file actions only.",
  responseFormat: toolStrategy([TriagePlanSchema]),
});
const out = await agent.invoke({ messages });
out.structuredResponse; // typed TriagePlan when responseFormat is set

responseFormat: toolStrategy([ZodSchema]) is how you get typed structured output out of the agent loop, surfaced as result.structuredResponse. That is the modern replacement for the bare withStructuredOutput call from module 1, when you are inside an agent rather than calling a model directly.

Middleware wraps the loop with cross-cutting behavior, composed in a middleware: [...] array: summarizationMiddleware compresses long histories automatically, humanInTheLoopMiddleware pauses on chosen tools for human sign-off (module 5's territory), piiRedactionMiddleware strips PII. For this module you want the loop plus structured output; the destructive-action gate comes in module 5.

Practice

Try it yourself

Quiz

Why the rename matters

createReactAgent being superseded by createAgent is more than a name change. What actually changed?

Recall

toolStrategy vs withStructuredOutput

Inside the loop, tool-calling is already doing one job. The structured response would be a second use of the same mechanism.

Why does createAgent need responseFormat: toolStrategy([...]) rather than just wrapping the model in withStructuredOutput?

Do

Build the todoist triage agent

Build a real triage agent that reads the inbox and emits a plan, file actions only, guarded against destructive ops.

Tick every step to confirm you did it.

Check

Plan validates against the apply contract

Confirm the emitted plan matches the existing consumer contract.

You should see

Plan JSON validates against {actions:[{id,do,project,labels,priority,due}]}, and a guard test proves the agent never emits close or graduate actions.