Agentic AI Concepts
Vendor-neutral theory that applies to any agentic assistant — GitHub Copilot, Anthropic’s Claude Code, Cursor, OpenAI’s Codex — to the SDK you’ll use later, and to any agent framework you’ll ever touch. Be able to explain what makes a system “agentic.”
A chatbot answers one question and stops. An agent keeps going: it thinks, does something, looks at what happened, and tries again — like a kid solving a maze by testing paths until they reach the end.
What “agentic” actually means
☺ Like you’re 10: A regular chatbot is like a friend who answers one question and walks away. An agent is like a friend who helps you build a LEGO set — they try a piece, see if it fits, and keep going until it’s finished.
A plain language model is a function: text in, text out. It has no ability to act, no memory beyond the conversation, and no way to check whether it was right.
An agent wraps that model in a loop that lets it act on the world, observe what happened, and decide what to do next:
Foxy: A chatbot already answers my questions. Why does an agent need to keep going round and round?
Professor Owl: Because a chatbot answers once and stops. An agent runs a loop: it reasons, then it acts, then it observes what happened — and repeats until the goal is met.
Olly the Octopus: Watch me! I reach out an arm to run the test — that’s act. It fails, so I read the error — that’s observe — then I think again and try a new fix.
Timmy the Turtle: And before Olly declares “done,” I check the result myself. If the test truly passes, the loop stops; if not, we go around one more time.
The four building blocks of any agent
☺ Like you’re 10: Think of an agent like a robot chef: it needs a brain to think, hands to cook with, a notebook to remember the recipe, and a plan for what to do first, second, and last. Take away any one and dinner never happens.
Every agent — including the ones inside tools like Copilot, Claude Code, and Cursor — is built from four ingredients. When you build your own, you’re assembling these:
- A model (the reasoning engine). The LLM that decides what to do — the “brain.” You pick it from a model picker (Copilot’s dropdown, Claude’s model selector, OpenAI’s API, and so on).
- Tools (the hands). Functions the agent can call to affect or observe the world: run a command, query a database, call an API. These arrive via MCP servers, built-in capabilities, or custom tool definitions in an SDK — the same shape whether you’re in Copilot, Anthropic’s Claude SDK, or another framework. An agent with no tools is just a chatbot.
- Memory (continuity). State that persists. Short-term working memory is the current session’s context; long-term memory survives across sessions (Copilot Memory, Claude Code’s persistent project memory, persistent CLI sessions) and is what lets an agent get better at your repo over time.
- Planning & control (the workflow). The logic that decides the order of actions and when to stop — break a goal into steps, choose a tool, recover from failure, know when it’s done. Frameworks and assistant runtimes (Copilot, Claude Code, and the like) handle this for you.
Agent = Model + Tools + Memory + Planning. Every “how do I build an agent” question reduces to “how do I provide these four things.” It’s also the GH-300 exam’s favorite framing.
The ReAct pattern (Reason + Act)
☺ Like you’re 10: It’s like a treasure hunt where you read one clue, take a step, look around at what you found, and then read the next clue — think, do, look, repeat — instead of trying to guess the whole path at once.
The most common agent architecture is ReAct: the agent alternates between reasoning (thinking in words) and acting (calling a tool), feeding each observation into the next reasoning step. A run looks like:
Thought: I need the user's order history to answer this.
Action: query_db("SELECT * FROM orders WHERE user_id = 42")
Observation: [3 orders returned]
Thought: The most recent order is still 'pending'. Check shipping status.
Action: call_api("GET /shipments?order=1007")
Observation: { status: "in_transit", eta: "2026-06-27" }
Thought: I now have enough to answer.
Answer: Your order #1007 is in transit, arriving June 27.You don’t usually write this loop by hand — the assistant’s runtime does it, whether that’s Copilot, Claude Code, or an agent SDK. But it explains why agents behave the way they do, why they sometimes loop, and why good tool descriptions matter so much (the agent picks tools based on their descriptions).
How the agent knows when to stop
☺ Like you’re 10: The agent raises a little flag after each turn. One flag says “I still need to grab something” so it keeps playing; the other says “I’m finished” so the game ends. You watch the flag, not what the agent mumbles to itself.
Look back at the loop diagram: it repeats until the goal is met — but how does the runtime actually decide that? Modern agents key off one signal the model returns with every step, its stop reason:
| The model returns… | …and the loop |
|---|---|
tool_use — “I want to call a tool” | runs the tool, appends the result to the conversation, and loops again |
end_turn — “I’m done; here’s the answer” | stops and hands the result back to you |
That single rule — keep going while it’s tool_use, stop on end_turn — is the entire control flow. (tool_use/end_turn is Anthropic’s vocabulary; OpenAI’s API expresses the same signal as finish_reason: "tool_calls" vs "stop" — different names, identical rule.) It’s also a favourite exam trap (it’s explicit in Anthropic’s CCAR-F) because the tempting wrong answers are all anti-patterns:
- Don’t parse the model’s prose for words like “done” — phrasing is unreliable, and the model may say “done” mid-thought.
- Don’t make a fixed iteration cap the primary stop. A cap is a good safety net against runaway loops, but if it’s doing the deciding you’ll cut off real work or hide a stuck agent.
- Don’t stop just because a tool returned an error. A good agent observes the error and tries to recover — that’s the whole point of the loop.
Watch the loop run: a real example
☺ Like you’re 10: Watch the agent fix a broken toy step by step: it pokes the toy to see what’s wrong, finds the loose part, tightens it, tests it again, and only stops once the toy works. Each look tells it what to try next.
Theory clicks once you trace it. Here is what actually happens when you hand an agentic coding assistant — Copilot’s agent mode, Claude Code, or a similar tool — a one-line goal — “the checkout test is failing, fix it” — annotated with the loop stage each step belongs to:
GOAL: "the checkout test is failing, fix it"
① REASON See the failure first.
ACT run_terminal("npm test -- checkout") → tool_use
OBSERVE FAIL: expected 19.99, received 1999 (cents vs dollars?)
② REASON Looks like a units bug. Find where the total is built.
ACT search_code("function calculateTotal") → tool_use
OBSERVE cart.js:42 returns the sum of item.priceCents
③ REASON The test wants dollars; the code returns cents. Fix the conversion.
ACT edit_file("cart.js", divide the total by 100) → tool_use
OBSERVE file written
④ REASON Re-run to confirm the fix.
ACT run_terminal("npm test -- checkout") → tool_use
OBSERVE PASS (1 test)
⑤ REASON Goal met — summarise and stop. → end_turn
ANSWER Fixed a cents/dollars mismatch in calculateTotal (cart.js:42);
the checkout test passes.Notice three things. Each observation changed the next reasoning step — that feedback is exactly what a plain chatbot can’t do. The run ended because the model emitted end_turn, not because a counter ran out. And the agent freely ran read-only steps, but a sensible setup would gate step ③’s file edit (or a later git push) behind your approval — the autonomy question we turn to next.
Levels of autonomy (match them to risk)
☺ Like you’re 10: It’s like learning to ride a bike: first a grown-up holds the seat, then you get training wheels, then you ride alone on the driveway, and only later on the busy street. How much freedom you get depends on how badly a fall would hurt.
Not all agents should be equally free. A useful five-level scale:
| Level | Name | The agent… | Human role |
|---|---|---|---|
| 0 | Assistant | suggests; you do everything | You act |
| 1 | Co-pilot | drafts actions; you approve each | You approve every step |
| 2 | Supervised agent | executes a task; you review the result | You review output (cloud agent → PR) |
| 3 | Autonomous agent | executes and self-corrects within bounds | You set guardrails, spot-check |
| 4 | Orchestrator | coordinates other agents | You set policy, monitor the fleet |
The engineering discipline is matching autonomy to blast radius. Low-risk, easily-reversible work (writing a test, drafting a changelog) can run at level 3. High-blast-radius work (touching auth, deleting data, deploying to prod) should sit at level 1–2 with a human gate. You see this principle baked into today’s assistants: Copilot’s cloud agent opens a draft PR rather than merging, and Claude Code pauses to ask before it edits files or runs commands you haven’t pre-approved — agent proposes, human approves the sensitive actions.
Guardrails: the non-negotiables
☺ Like you’re 10: Guardrails are the safety rules at a swimming pool: a grown-up watches before you go in the deep end, you only get the floaties you need, you swim in a roped-off lane, and a lifeguard writes down what happened. They let you have fun without anyone getting hurt.
Autonomy without guardrails is how you get a 3 a.m. incident. The essentials:
- Human-in-the-loop gates on irreversible or sensitive actions (merging, deploying, deleting, spending, touching production data). Assistants enforce this in similar ways — Copilot asks before running terminal commands and produces reviewable PRs; Claude Code prompts for approval before it edits a file or runs a command.
- Least-privilege tools. Give an agent only the tools it needs. Don’t hand a changelog agent database-write access.
- Sandboxing. Run risky execution in isolation (Copilot’s cloud agent runs in a sandboxed Actions container, and Claude Code can run inside a container or restricted workspace, for exactly this reason).
- Observability. Log every action and tool call so you can audit and debug. A commit-by-commit trail, or a transcript of every tool call the agent made, is this.
- Prompt-injection awareness. An agent that reads external content can be tricked by malicious instructions hidden in that content. Treat anything an agent reads from the outside world as untrusted data, not commands — a real, active class of vulnerability with its own OWASP risk lists.
(1) What single capability turns a chatbot into an agent? (2) Recite the four building blocks. (3) Why should a “deploy to prod” agent run at a lower autonomy level than a “write a unit test” agent? (4) What is prompt injection and why does tool access make it dangerous?
Check your answers
- The agent loop: The ACT → OBSERVE → REASON cycle — the ability to try something, see what happened, and adjust, repeating until the goal is met. A chatbot answers once and stops; an agent runs this loop, which is what lets it (for example) fix its own failing tests. Concretely, an agent with no tools to act with is just a chatbot.
- Model + Tools + Memory + Planning: A model (the reasoning engine/brain that decides what to do), tools (the hands — functions it can call to affect or observe the world), memory (continuity — short-term session context plus long-term state across sessions), and planning & control (the workflow logic that orders actions, recovers from failure, and decides when to stop).
- Match autonomy to blast radius: Deploying to prod is high-blast-radius, hard-to-reverse work, so it should sit at a low autonomy level (1–2) behind a human gate; writing a unit test is low-risk and easily reversible, so it can safely run autonomously (level 3). The engineering discipline is matching how free the agent is to how badly a mistake would hurt.
- Prompt injection: It is when malicious instructions are hidden in external content an agent reads, tricking it into following those instructions instead of treating the content as mere data. Tool access makes it dangerous because a tricked agent can then act on those hidden commands — running commands, writing files, or calling APIs — so anything read from the outside world must be treated as untrusted data, not commands.