How to Build an AI Agent in 2026: A Practical Guide
by Dr. Phil Winder , CEO
How do you build an AI agent in 2026 that survives production? You wrap a capable model in a good harness, provide it with information and tools, a sandboxed environment, a store with write rules, an evaluation loop, and you put a human in the loop on anything irreversible.
This guide is the playbook we use at Winder.AI when scoping and delivering agentic engagements. It includes a framework comparison with an opinionated “best for” column, two worked examples (a constrained agent in code and an open-ended agent defined in markdown), the environment, store, harness, and evaluation patterns that actually survive contact with real users, and a collection of pitfalls that can kill agent projects.
Framework comparison at a glance
Below is a table summarising what we reach for when working on an agentic project:
| Framework | Style | Best for | Main weakness | Typical learning curve |
|---|---|---|---|---|
| Yolo mode | A powerful LLM in a loop with a minimal harness (“harness engineering”) | Vague, open-ended goals where a capable model can find its own way to a solution with little to no scaffolding or custom code | Least control and predictability; requires close monitoring | Minutes |
| Pydantic AI | Lightweight, typed, Python-native building blocks | Small projects, demos, and prototypes that want structure without heavy dependencies | Not a full orchestration layer; you add state, memory, and evaluation yourself | Hours |
| LangGraph | Explicit graph of nodes and edges; typed state | More involved demos and prototypes that need branching and explicit state | A heavy third-party dependency that can become more burden than benefit to maintain long term | 2 to 3 days for an experienced Python engineer |
| Build your own | Direct LLM API plus your own state machine | Our default for production: only the parts you need, so the system stays focused, deliverable, and stable | Upfront effort; you own tracing, retries, and the loop | 1 to 2 weeks |
| Helix | Full private AI platform, agents and deployment out of the box | When you want a complete platform experience out of the box, licensed and supported by the Helix team | You adopt a whole platform rather than a single library, so less low-level control | Minutes; the platform handles the plumbing |
Our honest default for production work is to build our own agent runtime. Depending on a third-party framework often costs more than it saves once a system has to be maintained, so building only the parts we need keeps the result focused, deliverable, and stable. For smaller projects and demos we usually start with a lightweight framework like Pydantic AI; for more involved demos we sometimes reach for LangGraph, though any third-party dependency can become more of a burden than a benefit over time. For hardened production products we tend to reach for Go rather than Python, but that is a topic for another day.
We have written separately on the broader agentic AI architecture and frameworks for the framework-selection conversation. This article focuses on the build.
The components of a production agent
Large language models have come a long way since their text-completion origins. Now we can encapsulate entire workflows and processes in agentic systems that behave in a resilient, strategic way. Building a production agent in 2026 comes down to a handful of components:
- LLM: Match your language model to the complexity and privacy of the problem. Use self-hosted models to optimise for privacy or cost. Use frontier hosted models to optimise for performance or opportunity cost.
- Harness: Pick a harness that efficiently wraps your LLM in a loop. The best harnesses are simple, customisable, and observable.
- Sandbox: Give your agent a sandbox where it can do work without the risk of taking down other systems.
- Context: Connect your agent to the information it needs to do its job.
- Tools: Give your agent the actionable tools it needs inside the sandbox to do its job, such as the
ghCLI to interact with GitHub. - Store: Give your agent somewhere to store its learning.
- Evaluation: Coding harnesses excel when they have a closed loop that determines how well they have achieved the task. Evaluate your agent to make it easier to develop and maintain.
For a deeper architectural treatment, see our AI agent development services page.
Two ways to build an agent
The two examples that follow sit at opposite ends of that table: an open-ended agent driven by markdown in a harness, and a constrained agent written in code. Start with the harness approach, because it is the one people underestimate. What’s interesting about it is that it’s deliberately less deterministic. By offloading the burden of “getting it done” to the agent, you’re explicitly accepting some uncertainty to deal with more diverse requests. This works well in practice when you’re trying to automate a typical workplace workflow or process. If they really were deterministic and repeatable, you probably would have automated that already.
However, agents written in code have their place. They sit slightly back from the previous approach. You’re still leaning on the LLM’s ability to deal with uncertainty, but the code makes it cleaner to separate out the problem into smaller chunks. Chatbots are probably the best known use case of this approach, because they benefit from a little constraint.
Neither approach is better in the abstract. Reach for code when you need constraint. Reach for markdown when you want range.
Example 1: a constrained agent in code
When the remit is fixed, a lightweight framework like Pydantic AI keeps the agent on rails. Here is a minimal refund agent with two tools:
from pydantic_ai import Agent
agent = Agent(
"openai:gpt-4.1",
system_prompt=(
"Decide whether a refund request is in policy, then act. "
"Any refund over £50 must be handed to a human for approval."
),
)
@agent.tool_plain
def search_orders(customer_id: str) -> str:
"""Return the last five orders for a customer."""
return f"Last 5 orders for {customer_id}: [order_991, order_992, ...]"
@agent.tool_plain
def issue_refund(order_id: str, amount_pence: int) -> str:
"""Issue a refund. Only call after human approval for amounts over £50."""
return f"Refund of {amount_pence}p queued for {order_id}"
result = agent.run_sync(
"Refund the most recent order for customer C-42 if it was under £50."
)
print(result.output)
A few things carry more weight than the line count:
- Tool design over tool schemas. Typed schemas used to be the largest preventable bug class. That problem is now largely solved: the Model Context Protocol (MCP) and typed frameworks like Pydantic AI make every call schema-checked by default, so the model can no longer invent parameters. Spend the effort on the design instead.
- One responsibility per tool.
search_ordersdoes one thing. Do not bundle filters, sorts, and side effects into a single call. Agents regularly make mistakes calling tools, and it’s usually due to parameter complexity. Each mistake is an extra hop which adds latency. - A confirmation step for irreversible actions.
issue_refundshould route through human approval above a threshold, with a dry-run path your evaluation suite can use.
This shape is ideal for a chatbot or any workflow with a narrow, auditable set of actions. It is deliberately boxed in, and for a constrained job that is exactly what you want.
Example 2: an open-ended agent as markdown in a harness
For open-ended work, flexibility helps. Giving an agent a generic, pluggable harness provides it with a customisable workspace. A harness is a small program that wraps a capable model in a loop: it feeds the model a system prompt, gives it tools (a shell, file read and write, web access, connected services) inside a sandboxed environment, runs whatever the model decides, feeds the result back, and repeats until the goal is met. The agent itself is then just markdown.
Here is the whole of a research-and-report agent, as an agent.md file the harness loads as its system prompt:
# Goal
Given a company name, produce a two-page briefing on its public AI strategy.
# How to work
- Work in the /workspace directory.
- Save findings as you go into memory/, one fact per markdown file.
- Cite every claim with a source URL.
- Prefer primary sources (filings, the company's own posts) over commentary.
# Tools
- Shell, file read and write, web fetch, web search.
# Guardrails
- Never run destructive shell commands.
- If you cannot verify a claim, mark it UNVERIFIED rather than guessing.
# Done when
- briefing.md exists, is under two pages, and every claim has a source.
There is no task-specific code here. Swap the markdown and the same harness runs a completely different agent. You define the job to be done and let a capable model work out the path. For open-ended tasks, this works really well.
To harden this loop, wire in other components to make it more secure, maintain state, and stay observable:
- Harness. Harnesses are an emerging solution, but Goose and QwenCode are two actively maintained open-source options. Keep it simple, customisable, and observable.
- Sandbox. Run the loop inside a sandbox so a confused agent cannot damage anything real. A capability-deprived Docker container is a good first step, but more specialised sandboxes like nono are emerging to provide better AI-native isolation.
- Store. Give the agent somewhere durable to read and write. The simplest and often best is a persistent directory where the agent can write markdown files. But specific use cases might benefit from domain-specific stores, like databases for operational work or something like beads for software engineering.
- Context. Connect the agent to the information it needs through retrieval and data sources, increasingly via the Model Context Protocol (MCP) so one integration serves many agents. This is about giving the agent the right information, which is a separate concern from letting it act.
- Deployment. Containerise the harness and run it as a service behind a queue, or on a schedule for batch work. Add tracing (in some form) from day one, because an agent you cannot observe is an agent you cannot debug.
- Tools. Tools are how the agent acts, which is a separate concern from context. MCP solves typing, so that is no longer the deciding factor. For actions, though, I’d suggest starting without MCP. I’ve found the agent works better with human-oriented tools like CLIs: they are far more present in the training data and they are usually much more flexible. Prefer a CLI to begin with, at least. Reach for MCP-based actions when you need to audit, gate, or add security controls around what the agent can do.
We reach for this markdown-in-a-harness pattern far more often than a bespoke framework build for anything open-ended. Code still wins when the job is narrow and the actions are dangerous, but that is a smaller slice of the work than it used to be.
Evaluation: the hardest part
Evaluation is honestly one of the most difficult aspects of developing an agent. This is because of the way that we are using agents. We’re asking them to use their own insight and their own tools to solve a problem, but it’s really hard to come up with a variety of scenarios which have the breadth of real life yet the simplicity of something you can assert.
One of the simplest patterns is to chat directly with the agent and ask it to persist its learnings in the store. Whenever you do see a problem, you can internalise that learning and even ask the agent to contrast future results with that learning.
But real-life unit tests and benchmarks are remarkably hard to create. Despite that, it is worth building a benchmark for your specific domain if you rely on that agent in the long term. I’ll write a longer post about developing benchmarks in the future.
Even if you don’t have a benchmark, some regression tests working on a subset of the problem domain can help catch simple bugs.
The 2026 takeaway
Building an AI agent is remarkably easy in 2026, to the point where you no longer need any Python code. But building an agent that survives production still takes significant engineering work. It now lives in the harness, the environment, the store, and the evaluation and monitoring around the model, far more than in the framework or the bespoke code inside it. Surprisingly, I’m getting to the point where I don’t write any code for the actual instantiation of the agent any more. But, for narrow, high-stakes jobs, a little framework code keeps the agent honest.
If you would like an opinionated, scope-specific recommendation on which approach and architecture fits your use case, see our AI agent development services, LLM consulting and development, and AI workflow automation pages, or book a no-obligation scoping call.
Frequently asked questions
An AI agent is a program that uses a large language model (LLM) as its reasoning engine, calls external tools to act on the world, holds state across turns, and decides its own next step instead of following a fixed script. In 2026 there are two dominant shapes: a constrained agent defined in code with a framework such as Pydantic AI or LangGraph, and an open-ended agent that is a capable model wrapped in a harness and steered largely by markdown rather than bespoke code.
For a narrow, well-defined job, use a lightweight framework such as Pydantic AI, or LangGraph when you need explicit control over state and branching. For open-ended goals, a capable model in an open-source harness such as OpenHands or Goose, steered by markdown, often beats any framework. For most production work our default is to build a lean custom runtime so we ship only the parts we need, and for a full platform out of the box we use Helix. The framework matters less than the harness, environment, store, and evaluation you build around it.
A production agent in 2026 has a handful of components: an LLM matched to the problem (self-hosted for privacy or cost, a frontier hosted model for performance), a harness that wraps the model in a simple and observable loop, a sandbox so the agent cannot damage real systems, the context that connects it to the information it needs, the actionable tools it uses to do work (such as a CLI), a store (a directory of markdown files, a vector store, or both) with write rules, and an evaluation harness with a labelled gold set. Without them you have a demo, not a production system.
Tool use is how an agent acts on the world. The LLM proposes a tool call, your code executes the tool, and the result goes back to the LLM. In 2026 most tools are exposed through the Model Context Protocol (MCP), which makes every call typed by default, so hand-writing JSON schemas and worrying about hallucinated parameters is largely a solved problem. What matters now is tool design: one responsibility per tool, idempotent where possible, and a confirmation step or dry-run mode before any destructive action.
Short-term memory is the conversation buffer and the agent’s scratchpad inside the current run. Long-term memory is durable knowledge across runs, held in a store of what the agent has learned, from a directory of markdown files to a vector store such as Qdrant, pgvector, or Weaviate. In 2026 the practical pattern is summarised short-term context to manage token cost, plus a store with explicit write rules so the agent does not pollute it with garbage.
Evaluate agents at three levels. Trace-level: replay recorded runs to confirm the same inputs produce the same tool calls and outputs. Task-level: a labelled gold set of tasks with expected outcomes, scored by a judge LLM and human review. System-level: production metrics (success rate, cost per task, latency, escalation rate to humans). Tools we use in 2026 include LangSmith, Braintrust, Ragas, and DeepEval. Skipping evals is the single most common cause of agent regressions in production.
Building a working demo takes a senior engineer one to two weeks. Taking that demo to a reliable production system that handles edge cases, has evaluation coverage, monitoring, and a human-in-the-loop escalation path typically takes three to six months and £80,000 to £250,000 in mid-market budgets. The gap between demo and production is where most agent projects fail.
The most common failure modes are: (1) no evaluation harness, so regressions ship unnoticed; (2) no sandboxed environment, so a confused agent can damage real systems; (3) weak context, so the agent reasons from stale or missing information; (4) unbounded loops with no iteration or budget cap; (5) store pollution from writing everything verbatim; and (6) no human-in-the-loop checkpoint for irreversible actions. Each is preventable with a few hours of design work upfront.