# Agent Basics

Course: [AI Agents](https://www.devtutorials.ai/learn/ai-agents) · Section: Agent Foundations
Source: https://www.devtutorials.ai/learn/ai-agents/foundations/agent-basics

> What an AI agent is, why it needs boundaries, how it differs from a workflow, the four things it can do, and where agents are used in real work.

Imagine you ask a friend to fix a door that makes a noise when it opens and closes.

One friend simply says, "Try using some oil," and then leaves. They never looked at the door to understand what was causing the problem.

Another friend comes over and checks the door. They open and close it, listen carefully, and discover that one of the hinges is making the noise.

They apply some oil to the hinge. Then they open and close the door again to see if the problem is fixed. The noise is gone, so they stop.

The second friend behaves like an **AI agent**. They observe the situation, make a decision, take an action, and then check the result. They keep repeating these steps until the problem is solved.

**The main idea:** An agent works in a loop. It observes, thinks, acts, and checks the outcome. This process continues until the goal is achieved or a limit causes it to stop.

## A Simple Real-World Example

Imagine a new team member starting their first day at work. Their manager gives them a goal: "The ticket page shows the wrong number. Please fix it."

The manager does not provide step-by-step instructions, so the team member figures out what to do on their own.

1. They run the tests to identify what is failing.
2. They read the file mentioned in the test results.
3. They make a small change to the code.
4. They run the tests again to check whether the issue is fixed.
5. All the tests pass, so they tell the manager that the task is complete.

Each action depends on what they learned from the previous step. This is the basic idea behind how an agent works.

**In simple words:** An agent is a program that continuously decides what to do next and takes action until the task is completed.

## What You Will Learn

In this lesson, you will learn:

1. What an AI agent is.
2. Why an agent needs limits and boundaries.
3. How an agent is different from a workflow.
4. What it means to be goal-driven.
5. The four main things an agent can do: observe, reason, use tools, and take action.
6. Where agents are used in real-world work.

Every page in this course includes an **Agent Lab** where you can see agents working on the **Brightgrid Support Portal** project. By default, a **scripted brain** with fixed rules is used, so the results are always the same. You can switch to a **live model** in Settings to see how a real AI model makes decisions. The code examples on this page use plain JavaScript and do not require a model.

## Core Agent Concepts

### What Is an Autonomous Agent?

An **AI agent** is a program that uses an AI model to achieve a goal on its own. It works through a series of steps.

In each step, the agent performs four actions:

1. **Look.** It reads the goal and reviews the result from the previous step.
2. **Think.** The AI model decides what the next step should be.
3. **Act.** The application performs that step, such as running tests.
4. **Check.** It saves the result of the action. This result becomes the information the agent reviews in the next step.

**Autonomous** means "able to make decisions by itself." No one tells the agent exactly what to do next. Instead, it chooses the next step based on what it has just observed.

The next example shows how an agent loop works using plain JavaScript. There is no AI involved.

The `think` function uses a few fixed rules to decide what to do next. Even though it does not use AI, the overall structure is similar to how a real agent works.

```js runnable title="Each step is chosen from what the agent sees"
const world = { fileRead: false, testsPass: false };

function look() {
  return { ...world };
}

function think(seen) {
  if (seen.testsPass) return "finish";
  if (!seen.fileRead) return "read the file";
  return "fix the file";
}

function act(action) {
  if (action === "read the file") world.fileRead = true;
  if (action === "fix the file") world.testsPass = true;
}

for (let step = 1; step <= 5; step++) {
  const action = think(look());
  console.log("Step " + step + ": " + action);
  if (action === "finish") break;
  act(action);
}
```

Expected output:

```text
Step 1: read the file
Step 2: fix the file
Step 3: finish
```

The loop allows up to 5 steps, but it stops after 3 steps.

No one instructed it to stop at step 3. The `think` function noticed that the tests had passed, so it decided to finish the task.

**In simple words:** the agent decides what to do next by itself, and it stops by itself when the goal is completed.

Now let's compare this with a real agent. First, try a single model call.

A single model call receives the goal and provides one response. It does not have access to tools, so it cannot inspect the code or verify results.

Next, run the agent on the same goal. Use **Open it, then step through** to view each step one at a time.

Look at the steps shown on the right side of the Agent Lab. The agent:

1. Runs the tests and reads the failure.
2. Opens and reads the file mentioned in the failure.
3. Changes one line of code.
4. Runs the tests again.
5. Stops because every test passes.

To view the result from a user's perspective, open the **Preview** tab. It displays the ticket page in a browser view showing "Exported 80,000 rows".

### Agent Boundaries

A **boundary** is a rule that limits what an agent is allowed to do.

For example: "You can only change files inside the `web/` folder."

Boundaries are important because agents can make decisions and take actions on their own. Without limits, a wrong action could cause problems in other parts of the system.

Think about a new team member on their first day. They may be allowed to update the frontend code, but they are not allowed to change the payment system.

If they discover that the issue is in the payment system, they need to ask someone with the correct access. That is a boundary.

The next example shows how an application checks whether a file is inside the allowed boundary.

```js runnable title="A boundary: only the web folder may change"
const allowed = ["web/"];

function canChange(path) {
  return allowed.some((folder) => path.startsWith(folder));
}

const paths = ["web/format.js", "api/limits.js", "web/styles.css", "package.json"];

for (const path of paths) {
  console.log(path + " -> " + (canChange(path) ? "allowed" : "blocked"));
}
```

Expected output:

```text
web/format.js -> allowed
api/limits.js -> blocked
web/styles.css -> allowed
package.json -> blocked
```

The boundary check is performed by the application, not by the AI model. The model might request a change to `api/limits.js`, but the application can deny the request.

Do not rely on the model to follow boundaries by itself. Instructions are only requests. Real protection comes from checks built into your code. Always enforce boundaries in the code that runs the tool.

Now watch a boundary stop an agent from making an unauthorized change. In this example, the bug is located in `api/`, but the agent is allowed to modify files only in `web/`.

The agent attempts to change `api/limits.js`, but the application blocks the action. The agent then stops and asks a person for help.

This is the correct and safe outcome. A blocked action is not a failure. It means the boundary is working as intended.

### Agent vs Workflow

A **workflow** is a set of steps that is planned before the program starts. The program follows the same steps in the same order every time it runs.

An **agent** decides what to do while it is running. Each step depends on the result of the previous step.

| | Workflow | Agent |
|---|---|---|
| Who decides the steps? | The person who created the workflow | The AI model while the agent is running |
| Does the same input always produce the same steps? | Yes, always | Usually, but not always |
| Best for | Tasks where the steps are already known | Tasks where the next step depends on what is discovered |
| Limitation | Struggles with unexpected situations | Can be slower, more expensive, and less predictable |
| Example | Sending a welcome email to every new user | Finding the cause of a failed test and fixing it |

The next example gives both a workflow and an agent the same two bugs. The workflow always applies one fixed solution: adding commas. The agent first compares the current result with the expected result. It then chooses the fix that best matches the problem it finds.

```js runnable title="Same two bugs: the workflow fixes one, the agent fixes both"
const bugs = {
  "Bug A": { got: "80000 rows", want: "80,000 rows" },
  "Bug B": { got: "80,000 row", want: "80,000 rows" },
};

function workflowFix(text) {
  return text.replace("80000", "80,000");
}

function agentFix(text, want) {
  if (!text.includes(",") && want.includes(",")) return text.replace("80000", "80,000");
  if (!text.endsWith("s") && want.endsWith("s")) return text + "s";
  return text;
}

for (const [name, bug] of Object.entries(bugs)) {
  const byWorkflow = workflowFix(bug.got) === bug.want ? "fixed" : "still broken";
  const byAgent = agentFix(bug.got, bug.want) === bug.want ? "fixed" : "still broken";
  console.log(name + " | workflow: " + byWorkflow + " | agent: " + byAgent);
}
```

Expected output:

```text
Bug A | workflow: fixed | agent: fixed
Bug B | workflow: still broken | agent: fixed
```

The workflow works perfectly for Bug A because it was designed specifically to solve that bug. However, it is not useful for Bug B because it always follows the same predefined steps.

The agent can handle both bugs because it examines the problem before deciding what to do.

Now try it in the Agent Lab. Run these three examples in order.

The workflow follows its four predefined steps and reports **"1 passed, 2 failed"**. Because it cannot change its plan, it cannot respond to the new problem.

The agent reads the new failure, understands what is wrong, and chooses a different fix.

**Easy Way to Remember:** A workflow is like a **recipe**. An agent is like a **cook**. A recipe always follows the same instructions. A cook checks the food and decides what to do next.

Agents are not always the best choice. If the steps are already known, a workflow is usually faster, less expensive, and easier to test.

Use an agent when the next step depends on what is discovered during the task.

### Goal-Driven Execution

**Goal-driven** means the agent focuses on achieving a goal rather than completing a fixed number of steps.

The agent stops when the goal is reached. A good goal is something that can be checked and measured.

For example, **"Make all tests pass"** is easy to check because the test results clearly show whether the goal is complete.

A goal such as **"Improve the code"** is harder to check because there is no clear way to know when the work is finished.

If an agent cannot verify that the goal has been achieved, it cannot reliably decide when to stop.

Every agent also needs a **step limit**. A step limit is the maximum number of steps the agent is allowed to take. This prevents the agent from continuing indefinitely when it cannot make progress toward the goal.

```js runnable title="Stop when the goal is done, or at the limit"
function run(testsFailing, stepLimit) {
  let failing = testsFailing;
  let step = 0;
  while (failing > 0 && step < stepLimit) {
    step = step + 1;
    failing = failing - 1;
  }
  if (failing === 0) return "Goal done in " + step + " steps";
  return "Stopped at the limit. " + failing + " tests still failing";
}

console.log(run(2, 8));
console.log(run(5, 8));
console.log(run(12, 8));
```

Expected output:

```text
Goal done in 2 steps
Goal done in 5 steps
Stopped at the limit. 4 tests still failing
```

The same agent loop might take 2 steps for one task and 5 steps for another. The number of steps depends on what is required to achieve the goal.

The third example shows why a step limit is important. The agent reaches the limit of 8 steps and stops automatically.

In the Agent Lab, open **Settings** and change the step limit to 3. Then run **"Agent, bug A"** again.

This time, the agent runs out of allowed steps before it has enough time to verify whether its fix worked.

## Agent Capabilities

An agent has four main capabilities. Each capability supports a different part of the agent loop.

### Environment Observation

The **environment** is everything the agent works with.

For a coding agent, the environment includes files, tests, logs, and other information related to the project.

**Observation** means collecting information from the environment.

The agent may read test results, file contents, or error messages to understand what is happening.

Without observation, an agent has no information to work with and can only guess.

The one-call example shown earlier did not have observation. It never examined the code, so its response was only a guess.

### Autonomous Reasoning

**Reasoning** is how the agent decides what to do next.

The AI model reads the goal and the information collected so far. It then chooses the next action.

In the Agent Lab, each step includes a short explanation written in plain language. This explains the agent's reasoning.

For example:

"The test expected 80,000 rows but received 80000 rows. I will update the code to match the expected format."

Reading these explanations is one of the easiest ways to understand why an agent chose a particular action.

### Tool Usage

A **tool** is a function that an agent can request the application to run.

Each tool has:

- A name
- A short description
- Required inputs

The model cannot directly run code or perform actions on its own.

Instead, it requests a tool.

The application checks the request, runs the tool if it is allowed, and returns the result to the agent.

```js runnable title="The brain asks. The app checks and runs."
const tools = {
  read_file: (path) => "text of " + path,
  run_tests: () => "1 passed, 1 failed",
};

function runTool(request) {
  if (!(request.tool in tools)) return "ERROR: unknown tool " + request.tool;
  return tools[request.tool](...request.args);
}

console.log(runTool({ tool: "run_tests", args: [] }));
console.log(runTool({ tool: "read_file", args: ["web/format.js"] }));
console.log(runTool({ tool: "delete_everything", args: [] }));
```

Expected output:

```text
1 passed, 1 failed
text of web/format.js
ERROR: unknown tool delete_everything
```

The application only runs tools that it recognizes. If the agent requests a tool that does not exist or is not allowed, the application returns an error and no action is performed.

Open the **Tools** tab in the Agent Lab. You will see the four tools available to the agent:

- `list_files`
- `read_file`
- `write_file`
- `run_tests`

Among these tools, only `write_file` can make changes to files.

### Action Execution

**Action execution** is the stage where the application performs the requested action.

For example, it may:

- Read a file
- Write to a file
- Run tests

This is the point where the agent can affect the real environment.

Because actions can make changes, boundaries are checked at this stage before the action is allowed to run.

After each action is completed, the result is returned to the agent so it can decide what to do next.

Open the **Files** tab after an agent run. Any file modified by the agent is marked as **changed**.

You can also click **Run tests** yourself to verify the results.

**In simple words:**

- Observe means **read**.
- Reasoning means **decide**.
- Tool usage means **ask**.
- Action execution means **do**.

## Agent Applications

Agents are useful for tasks that involve multiple steps where the next action depends on what is discovered along the way.

Here are some common uses for agents.

### Business Automation

A business agent can help handle tasks such as customer support tickets.

For example, it might:

1. Read a support ticket.
2. Check the customer's subscription plan.
3. Search the help documentation.
4. Create a suitable reply.

The exact steps can vary from one ticket to another, which is why an agent is useful.

### Software Engineering

A coding agent works with software projects.

It can read files, update code, and run tests.

Coding agents can assist with many software development tasks, including:

- Feature planning
- UI design
- Frontend development
- Backend development
- Code review
- Testing

In Chapter 8 of this course, you will build a separate agent for each of these development tasks.

### Research Tasks

A research agent helps answer questions by gathering information.

It searches for information, reviews what it finds, decides what information is still missing, and searches again if needed.

The agent continues this process until it has enough information to provide an answer.

### Operational Workflows

An operations agent helps monitor and manage running systems.

For example, when an alert is triggered, the agent can read logs, identify the error, and prepare a short report for the person responsible for responding to the issue.

The next example classifies tasks using a simple question: **Do we know the steps before we start?**

```js runnable title="Do we know the steps before we start?"
const tasks = [
  { name: "Send the same welcome email to every new user", stepsKnown: true },
  { name: "Find why the checkout page is slow", stepsKnown: false },
  { name: "Copy yesterday's sales into a report", stepsKnown: true },
  { name: "Answer a customer using their account and our docs", stepsKnown: false },
];

for (const task of tasks) {
  const pick = task.stepsKnown ? "Workflow" : "Agent";
  console.log(pick + ": " + task.name);
}
```

Expected output:

```text
Workflow: Send the same welcome email to every new user
Agent: Find why the checkout page is slow
Workflow: Copy yesterday's sales into a report
Agent: Answer a customer using their account and our docs
```

When the steps are already known, a workflow is usually the better choice. When the steps depend on what you discover during the task, an agent is usually the better choice.

## Common Mistakes

| Mistake | Incorrect Understanding | Correct Understanding | What Can Go Wrong |
|---|---|---|---|
| Thinking a single model call is an agent | "I asked the model one question, so it is an agent." | An agent works in a loop and can use tools to gather information and take actions. | The response is only a guess because nothing was observed or verified. |
| No boundary is defined | "The agent will only change what is necessary." | Clearly define what the agent can access or modify, and enforce those rules in code. | A single incorrect action could modify files or systems that should never be changed. |
| Using a goal that cannot be verified | "Improve the code." | Use a goal that can be checked, such as "Make all tests in `web/` pass." | The agent has no clear way to know when the task is complete. |
| No step limit | "The agent will stop when it finishes." | Always set a step limit for every run. | A confused agent may repeat actions and waste time, resources, and money. |
| Using an agent for every task | "Agents are smarter, so they should be used everywhere." | Use a workflow when the steps are already known. | The solution becomes slower, more expensive, and less predictable than a simple script or workflow. |
| Trusting the agent when it says "done" | "The agent said the problem is fixed." | Always verify the result yourself, such as by running tests. | An incorrect fix could be accepted because no one checked the outcome. |

## Exercises

Each exercise ends with a value on the last line. Press **Check** to compare it with the expected answer.

## What to Remember

- An agent works in a loop: **observe, reason, act, and check**.
- The agent decides each new step based on the result of the previous step.
- A boundary defines what the agent is allowed to access or modify. Always enforce boundaries in code.
- A workflow follows a predefined set of steps. Use a workflow when the steps are already known.
- Give the agent a goal that can be checked and verified.
- Always set a step limit to prevent the agent from running indefinitely.

Next: **Core Pillars**, the four parts every agent needs: reasoning, planning, memory and action.
