bits~/first-agent-looplesson 4/10 · 0% →
You: why does the loop check stop_reason?
◆ tutor
Every reply comes with a reason the model stopped talking. If it’s
"tool_use", it wants you to run a tool and hand back the result. Anything else means it’s finished.↳ highlighted agent.ts lines 12–32
You: run it
npx tsx agent.ts "Weather in Chicago?"
→ tool_use get_weather({ city: "Chicago" })
← tool_result { temp_f: 41, sky: "overcast" }
→ end_turn "41°F and overcast in Chicago."
✓ 2 turns · 1 tool call · 1.8s
◆ tutor
Two turns: one to ask for the weather, one to answer. Now break it on purpose. Delete line 31 and run it again.
Predict first — does it loop forever, or crash?
import Anthropic from "@anthropic-ai/sdk";
import { tools, runTool } from "./tools";
const client = new Anthropic();
type Msg = Anthropic.MessageParam;
export async function agent(task: string) {
const messages: Msg[] = [{ role: "user", content: task }];
// the loop: think → act → observe → repeat
while (true) {
const res = await client.messages.create({
model: "claude-sonnet-5-5",
max_tokens: 1024,
tools,
messages,
});
messages.push({ role: "assistant", content: res.content });
if (res.stop_reason !== "tool_use") {
return res; // the model is done talking
}
const results = await Promise.all(
res.content
.filter((b) => b.type === "tool_use")
.map(runTool),
);
messages.push({ role: "user", content: results });
}
}
import type Anthropic from "@anthropic-ai/sdk";
export const tools: Anthropic.Tool[] = [{
name: "get_weather",
description: "Current weather for a city",
input_schema: {
type: "object",
properties: { city: { type: "string" } },
required: ["city"],
},
}];
export async function runTool(block: Anthropic.ToolUseBlock) {
const { city } = block.input as { city: string };
const weather = { temp_f: 41, sky: "overcast", city };
return { type: "tool_result" as const, tool_use_id: block.id, content: JSON.stringify(weather) };
}
# Get a key at console.anthropic.com
ANTHROPIC_API_KEY=sk-ant-…
TypeScriptUTF-8● lines 12–32: the loop
OUTPUT
npx tsx agent.ts "Weather in Chicago?"
turn 1 stop_reason="tool_use" → get_weather
turn 2 stop_reason="end_turn"
41°F and overcast in Chicago.