The Agentic Loop

The single pattern that powers every AI agent, from Claude Code to Copilot to custom SDK agents.

The Core Idea

An agent is just an LLM in a loop:

User prompt
    |
    v
+-------------------+
| LLM decides:      |
| - use a tool?     |<--+
| - hand off?       |   |
| - respond?        |   |
+-------------------+   |
    |                   |
    v                   |
+-------------------+   |
| Execute action    |   |
| (tool call, etc.) |---+
+-------------------+
    |
    v
Final response to user

The LLM receives a prompt, decides what to do, executes an action, feeds the result back, and repeats until it has a final answer. That’s it.

Every agentic system - Claude Code, OpenAI Agents SDK, Copilot agent mode - implements this exact loop. The differences are in what tools are available, how permissions work, and how context is managed.

Why This Matters

Before agents, LLM interactions were single-turn: prompt in, response out. The agentic loop changes that fundamentally:

  • Autonomy - the model decides what actions to take, not the user
  • Multi-step reasoning - complex tasks get broken into tool calls
  • Self-correction - the model sees errors and retries
  • Grounding - the model works with real data, not just training knowledge

The Loop in Code

Here’s the minimal agentic loop in pseudocode:

messages = [{"role": "user", "content": user_prompt}]

while True:
    response = llm.generate(messages, tools=available_tools)

    if response.has_tool_calls:
        for tool_call in response.tool_calls:
            result = execute_tool(tool_call)
            messages.append(tool_call)
            messages.append(tool_result(result))
    else:
        # No tool calls = final response
        return response.text

Every SDK wraps this pattern. The Claude Agent SDK calls it the “agent loop.” OpenAI Agents SDK calls it the “runner.” Copilot SDK has its “execution loop.” Same thing, different names.

Tool Definitions

Tools are how agents interact with the world. They’re defined as JSON schemas that tell the LLM what’s available:

{
  "name": "read_file",
  "description": "Read contents of a file",
  "input_schema": {
    "type": "object",
    "properties": {
      "path": { "type": "string", "description": "File path to read" }
    },
    "required": ["path"]
  }
}

The LLM doesn’t execute tools - it outputs structured JSON saying “I want to call read_file with path=/src/main.py”. Your code executes the tool and feeds the result back.

Tool Categories

Most agentic systems provide tools in these categories:

CategoryExamplesPurpose
Readread_file, search, grepGather information
Writeedit_file, write_fileModify state
Executerun_command, bashRun arbitrary code
Communicateask_user, create_prInteract with humans
Delegatespawn_agent, handoffMulti-agent patterns

Permission Models

The key design question is: what can the agent do without asking?

ApproachUsed byTrade-off
Ask for everythingEarly chatbotsSafe but slow
AllowlistClaude CodeBalance of safety and speed
Full autonomy--dangerously-skip-permissionsFast but risky
TieredCopilot agent modeRead=auto, write=review, exec=approve

Claude Code’s model is worth studying: read tools are auto-approved, write tools need approval the first time, bash commands always need approval (unless allowlisted in settings).

Context Window Management

The biggest practical challenge in agentic loops is context. Each tool call adds to the conversation:

Turn 1: User prompt (500 tokens)
Turn 2: LLM decides to read a file (100 tokens)
Turn 3: File contents (2000 tokens)
Turn 4: LLM decides to search (100 tokens)
Turn 5: Search results (1500 tokens)
...
Turn 20: Context is 50K tokens deep

Strategies for managing this:

  • Summarization - compress earlier turns (Claude Code does this automatically)
  • Subagents - spawn new agents with fresh context for subtasks
  • Selective context - only include relevant file sections
  • Sliding window - drop oldest messages as context fills up

Key Insight

The agentic loop is deceptively simple. The hard problems are all in the details:

  • Which tools to expose (too many = confusion, too few = capability gaps)
  • When to ask for permission (too often = annoying, too rarely = dangerous)
  • How to manage context (too much = slow/expensive, too little = lost state)
  • When to stop (too early = incomplete, too late = wasted compute)

Understanding this loop is the foundation for everything else in this module.

Agent Teams

A newer pattern builds on the agentic loop: agent teams. Instead of a single agent looping, multiple agents coordinate in parallel:

Team Lead (orchestrator)
├── Agent A: works on subtask 1 (own loop)
├── Agent B: works on subtask 2 (own loop)
└── Agent C: works on subtask 3 (own loop)

Each teammate runs its own agentic loop, but the team lead coordinates their work. Teammates can reference each other’s outputs - unlike subagents, which are isolated.

This is different from simple subagent delegation:

  • Subagents - isolated, one-way communication, parent manages results
  • Agent teams - shared awareness, bidirectional, team lead orchestrates

See Agent Teams for patterns and tradeoffs.