Agents & tools

Agent

Also called: coding agent, AI agent

An agent is a language model wrapped in a loop that lets it call tools, read the results, and decide what to do next. The model supplies the judgement; the loop and the tools give it hands.

James Phoenix
Understanding Data Updated July 2, 2026

A plain language model can only produce text. It cannot open a file, run a test, or search your repo. An agent is what you get when you give that model a set of tools and run it in a loop: the model asks to use a tool, your code runs the tool, the result goes back into the conversation, and the model takes another step. It keeps going until the job is done or you stop it.

That loop is the whole idea. There is no separate "agent model." The intelligence is the same model you would chat with; the agent-ness lives in the harness around it.

The loop in code

Here is the core loop with the Anthropic SDK, stripped to its essentials. Notice the shape: call the model, check whether it wants a tool, run the tool, feed the result back, repeat.

TypeScript
import Anthropic from '@anthropic-ai/sdk'

const client = new Anthropic()

const tools = [
  {
    name: 'read_file',
    description: 'Read a file from the working directory',
    input_schema: {
      type: 'object',
      properties: { path: { type: 'string' } },
      required: ['path'],
    },
  },
]

const messages: Anthropic.MessageParam[] = [
  { role: 'user', content: 'Summarise what src/index.ts does.' },
]

while (true) {
  const response = await client.messages.create({
    model: 'claude-sonnet-5',
    max_tokens: 1024,
    tools,
    messages,
  })

  // Record what the model said (including any tool requests).
  messages.push({ role: 'assistant', content: response.content })

  // No tool requested means the model is finished.
  if (response.stop_reason !== 'tool_use') break

  // Run every tool the model asked for and hand the results back.
  const toolResults = []
  for (const block of response.content) {
    if (block.type !== 'tool_use') continue
    const output = await runTool(block.name, block.input)
    toolResults.push({
      type: 'tool_result' as const,
      tool_use_id: block.id,
      content: output,
    })
  }
  messages.push({ role: 'user', content: toolResults })
}

Every coding agent you have used, whether a CLI, an IDE panel, or a background worker, is a more elaborate version of this loop. The differences are in the tools offered, the safety checks before a tool runs, and how the growing message history is managed.

What makes an agent good

  • Sharp tools. An agent is only as capable as the actions it can take. Read, write, run, search, and a way to plug in more via MCP.
  • A managed context. The message history grows every turn and competes for room in the context window. Good agents summarise, prune, and re-focus so the model keeps seeing what matters.
  • Guardrails. Because the loop acts on your machine, the interesting design questions are about permission and blast radius, not just cleverness.
Tip
When an agent goes off the rails, the cause is usually the loop, not the model. Too many tools, a bloated history, or a vague instruction will derail a capable model. Fix the harness before you blame the intelligence.

Related terms

Building with AI agents?

This dictionary is part of how I think about agentic engineering. If you want the same thinking applied to your codebase, that is what I do.

See how I can help