← All posts

What Is an AI Agent? LLM Plus Tools Plus a Loop

Quick answer: An AI agent is a language model wrapped in a loop and given tools. On each pass through the loop the model decides what to do next, calls a tool, reads the result, and decides again, repeating until the task is done. That is the whole idea: an LLM for reasoning, tools for acting, and a loop that lets it take more than one step. Strip away the buzzwords and an agent is those three parts.

The word "agent" gets stretched to mean almost anything lately, so let me give you a definition that actually holds up. If you understand the loop, you understand agents.

The Three Ingredients

Every agent, from a toy script to a production research system, is built from the same three things.

An LLM. The reasoning core. It reads the situation and decides what to do next. It does not act on its own; it produces decisions.

Tools. The ways the agent affects the world: fetch a URL, search the web, query a database, run code, send a message. Each tool is a function the model can request. (For how the request-response mechanics work, tool calling is the primitive underneath.)

A loop. The part that makes it an agent rather than a single answer. After each tool result comes back, control returns to the model, which decides the next step. Without the loop you have a chatbot that answers once. With it you have something that can chain steps toward a goal.

Take away any one of these and it is not an agent. An LLM alone is a text generator. An LLM with tools but no loop is a single function call. The loop is what earns the name.

The Plan-Act-Observe Cycle

The loop has a rhythm, and naming it makes agents much easier to reason about.

Phase What the model does
Plan Decides the next action given the goal and everything seen so far
Act Requests a tool call with concrete arguments
Observe Reads the tool result and updates its understanding

Then it loops back to plan. The cycle repeats until the model judges the task complete and produces a final answer instead of another tool call.

This is why agents can handle open-ended tasks that a single prompt cannot. "Research this company and summarize its funding history" is not one lookup. It is search, read, follow a link, read again, cross-check, then write. The plan-act-observe cycle lets the model discover that sequence as it goes rather than you scripting every step in advance.

Why Web Access Is the Highest-Value Tool

If you add exactly one tool to an agent, make it web access. Here is why it dominates.

The model's built-in knowledge is frozen at its training cutoff and it cannot look anything up on its own. That single limitation blocks a huge class of tasks: anything current, anything specific to a site, anything the model was never trained on. Web access removes that ceiling in one move. Search finds relevant pages, fetch pulls their contents, and suddenly the agent can reason over live, specific information instead of stale generalities.

Other tools are valuable for their domains, but web access is the one that widens what the agent can attempt at all. It is the difference between an agent that can only reformat what you give it and one that can go find what it needs. I made the fuller case in give your AI agent internet access.

A Minimal Agent in Code

Here is an agent in about thirty lines. It has one tool, web search backed by link.sc, and a loop. That is genuinely all an agent is.

import anthropic
import requests

HEADERS = {"x-api-key": "lsc_..."}

def web_search(query: str) -> str:
    resp = requests.post(
        "https://api.link.sc/v1/search",
        headers=HEADERS,
        json={"q": query, "engine": "google"},
    )
    results = resp.json()["serpData"]["results"][:3]
    pages = []
    for r in results:
        page = requests.post(
            "https://api.link.sc/v1/fetch",
            headers=HEADERS,
            json={"url": r["targetUrl"], "format": "markdown"},
        )
        pages.append(page.json()["content"])
    return "\n\n---\n\n".join(pages)

SEARCH_TOOL = {
    "name": "web_search",
    "description": "Search the live web and return full page content. Call this whenever you need current or specific information you do not already know.",
    "input_schema": {
        "type": "object",
        "properties": {"query": {"type": "string"}},
        "required": ["query"],
    },
}

client = anthropic.Anthropic()
messages = [{"role": "user", "content": "What did the company announce most recently?"}]

for _ in range(6):  # cap the loop
    response = client.messages.create(
        model="claude-opus-4-8",
        max_tokens=1024,
        tools=[SEARCH_TOOL],
        messages=messages,
    )
    if response.stop_reason != "tool_use":
        break
    messages.append({"role": "assistant", "content": response.content})
    results = []
    for block in response.content:
        if block.type == "tool_use":
            results.append({
                "type": "tool_result",
                "tool_use_id": block.id,
                "content": web_search(block.input["query"]),
            })
    messages.append({"role": "user", "content": results})

print(response.content[0].text)

Read the structure: a tool (web_search), a loop (for _ in range(6)), and an LLM deciding each pass whether to search again or answer. The model plans (decides to search), acts (requests the tool), observes (reads the results), and repeats. That is the whole pattern, and everything fancier is a variation on it. To see it scaled up into a real research pipeline, read build a deep research agent.

Notice the loop cap. That range(6) is not decoration, which brings me to the honest part.

Where Agents Actually Fail

Agents are powerful and also genuinely brittle. If you are going to build one, know the failure modes going in.

Loops that do not stop. Without a cap, an agent can keep calling tools, chasing a goal it never quite reaches, burning tokens and money. Always bound the loop.

Compounding errors. Each step builds on the last. A wrong turn early gets reinforced, and the agent confidently marches down a bad path. More steps means more chances to drift.

Garbage-in reasoning. An agent reasoning over bad tool output produces bad conclusions, stated with the same confidence as good ones. If your fetch returns a cluttered page or your search returns weak results, the agent's answer degrades and it will not tell you.

Context bloat. Every tool result piles into the context window. Long runs fill the window with old observations, crowding out the actual task and raising cost on every subsequent call.

The practical takeaways: cap the loop, keep tool output clean so reasoning has good inputs, and do not reach for an agent when a single prompt would do. Agents earn their complexity on open-ended, multi-step tasks, not on one-shot lookups.

The Short Version

An AI agent is an LLM plus tools plus a loop, running a plan-act-observe cycle until the task is done. Web access is the tool that most expands what it can attempt, and link.sc provides search and fetch built for exactly that. Build agents for genuinely multi-step work, cap the loop, feed it clean inputs, and respect that more autonomy means more ways to go wrong.


Building an agent that needs to search and read the live web? link.sc gives it clean, full-text search and fetch through one API. Start free.