Skip to content

PATTERN Cited by 1 source

Tool-call loop minimal agent

Pattern

A tool-using LLM agent is, in its simplest form, a single function that appends to a context array and calls one LLM endpoint in a loop:

  1. Append the user message to context.
  2. Call the LLM with context + a list of tools (each tool is a JSON schema describing name, description, parameters).
  3. If the response contains one or more function_call items: for each, run the tool, append the tool's output as a function_call_output to context, and loop back to step 2.
  4. Otherwise, append the assistant text to context and return it.

Fly.io demonstrates this in ~30 lines of Python against the OpenAI Responses API — call(tools) wraps client.responses.create, tool_call(item) runs one tool and returns its input+output pair, handle_tools(...) iterates the response's function-call items, and process(line) drives the loop. The "agent" is that code. (Source: sources/2025-11-06-flyio-you-should-write-an-agent.)

"Did you notice where I wrote the loop in this agent to go find and ping multiple Google properties? Yeah, neither did I. All we did is give the LLM permission to ping stuff, and it figured out the rest."

Why it matters

Three things the minimal loop makes visible:

  • Multi-step planning is emergent. Fly.io's demo asks "describe our connectivity to google" and the LLM independently issues three separate ping tool calls (google.com, www.google.com, 8.8.8.8). The agent author never wrote a "ping multiple endpoints" loop; the LLM decomposed the task against the available tools and the loop re-entered call() until the LLM was ready to produce a final answer. Tool inventory + a loop is the whole planner.
  • No MCP required. Fly.io explicitly notes the minimal agent needs no MCP: "MCP isn't a fundamental enabling technology. […] MCP is just a plugin interface for Claude Code and Cursor, a way of getting your own tools into code you don't control. Write your own agent. Be a programmer. Deal in APIs, not plugins." MCP becomes valuable precisely when you want your tools consumable by an agent someone else built; for your own agent, native tool-schema JSON is enough.
  • ~10 minutes of bash makes a coding agent. "Spoiler: you'd be surprisingly close to having a working coding agent. Imagine what it'll do if you give it bash. You could find out in less than 10 minutes." This is the structural reason agent ecosystems exploded in 2024–2025: the barrier to a working prototype is small.

Building-block variations (cheap to iterate)

Once the minimal loop is working, Fly.io points at the space of useful variations — each "your wackiest idea will probably (1) work and (2) take 30 minutes to code."

  • Sub-agents. Spawn a second context array + LLM call with its own tools (concepts/sub-agent + patterns/context-segregated-sub-agents).
  • Summarise old context. Feed a slice of the array back through the LLM and splice the summary back in as compression (concepts/context-engineering).
  • Tree-of-agents. Build parent/child chains, each sub-agent specialised by tool allowlist.
  • Multiple personalities. Two context arrays sharing the same user line, routed by coin-flip — the Fly.io Alph / Ralph demo.
  • Persist context. Dump the array to SQLite between process runs; reload on next start (systems/sqlite).
  • Swap tool allowlists per phase. Planning phase has the wide tool surface; execution phase has narrow tools so schemas don't crowd out output tokens (patterns/tool-surface-minimization).

When to reach for MCP vs. this pattern

Use this minimal-loop pattern when:

  • You own both the agent and the tools.
  • You want tight control over context allocation, tool schemas, retries, and cost accounting.
  • You're prototyping a new agent shape.

Reach for MCP (patterns/wrap-cli-as-mcp-server) when:

  • The consumer is an agent someone else built (Claude Code, Cursor, Goose, Claude Desktop).
  • You want the same tool server to serve multiple agent clients with one integration.

Fly.io's posture: "When you read a security horror story about MCP your first question should be why MCP showed up at all." The claim is not "MCP is bad" — it's "if you control the agent, you probably didn't need it; write the agent."

Caveats

  • The minimal loop has no turn-budget cap; a misbehaving LLM can loop on tool calls indefinitely. Production loops bound iteration count.
  • Tool outputs go into context verbatim by default. Large outputs consume token budget for the rest of the session — production agents truncate, summarise, or store-and-reference.
  • Security segregation is the operator's responsibility. Fly.io notes "You can trivially build an agent with segregated contexts, each with specific tools. That makes LLM security interesting." The minimal loop as written has one context and one tool set; production security posture requires splitting.

Seen in

Last updated · 200 distilled / 1,178 read