teachyou.ai academy
← All posts
Hermes Agent

What Makes a Good Agent Capstone Project?

Pramod Dutta · Jul 2, 2026 · 15 min read

Why most agent capstones fail before they start

Every cohort has the same moment. Someone finishes the lessons on tool calling, memory, and orchestration, opens a blank repo, and freezes. Not because they lack skill — because they don't know what "done" looks like for an agent project. So they default to one of two failure modes: the toy demo that impresses nobody, or the sprawling "AI assistant that does everything" that never ships.

A capstone project is the single artifact that stands between "I took a course on agents" and "I can build agents." Recruiters skim resumes. Hiring managers skim GitHub repos. What survives that skim is not your list of frameworks — it's whether your capstone demonstrates that you understand what an agent actually is: a system that observes state, decides an action, calls a tool, checks the result, and decides again. A good capstone doesn't need to be big. It needs to be honest about that loop, and it needs to fail in front of you at least once so you had to debug it.

This article is a working definition of "good" for an agent capstone — the scoping decisions, the technical bar, the traps, and the artifacts that separate a project that gets you hired from one that gets skimmed past. If you're currently enrolled in or considering 30 Days of Hermes Agent, this is also effectively the rubric we use internally when reviewing capstones from that course.

The core test: does it survive an unhappy path?

Before scope, before tech stack, before anything else, ask one question about your idea: what happens when the tool call fails, the API returns malformed data, or the user gives an ambiguous instruction?

If your honest answer is "I haven't thought about that yet," you don't have a capstone idea yet — you have a demo idea. The gap between a demo and a real agent project is entirely in how it handles the unhappy path. A weather chatbot that calls one API and formats the response is a demo. The same weather chatbot that has to decide what to do when the location is misspelled, when the API times out, when the user asks for "next weekend" and has to resolve that to actual dates — that's an agent project, because now there's a decision being made under uncertainty.

Concrete test you can run on any idea in five minutes: write down three things that could go wrong at runtime, and write down what the agent should do in each case. If you can't articulate at least one non-trivial failure mode, the idea is too shallow to be a capstone. If you can name five and none of them feel forced, you probably have too much scope — trim it down to the two or three failure modes that matter most.

Good scope vs. weak scope: concrete examples

Scoping is where most capstones are won or lost, so it's worth being blunt with side-by-side examples.

Weak scope: "A personal assistant agent that manages my email, calendar, and to-do list." This fails for a boring reason — it's three separate integration surfaces, each with its own auth flow, each with its own edge cases, and the "agent" part (the reasoning and tool-selection logic) ends up being a thin layer glued on top of API plumbing. You'll spend 80% of your time on OAuth flows and 20% on the actual agent behavior, which is backwards for a capstone meant to demonstrate agent design.

Strong scope: "An agent that triages a single Gmail inbox into three categories (needs-reply, FYI, spam-candidate) and drafts a reply for anything tagged needs-reply, using a scoring loop that re-reads its own draft against a tone-match rubric before finalizing." This is one integration surface, but it has real depth: classification under ambiguity, a draft-then-critique loop (the actual "agentic" part), and a clear success metric (did the human accept the draft with minimal edits). It's small enough to finish in the timeframe of a course project and deep enough to talk about for twenty minutes in an interview.

Weak scope: "A coding agent that can build any web app from a prompt." Too broad, and it's also already been built better than you'll build it by teams with a hundred times the resources. Building a worse clone of Devin or Cursor's agent mode teaches you less than you think, because you'll spend all your time fighting scope instead of understanding the loop.

Strong scope: "An agent that takes a failing pytest suite and a codebase, and iterates — read failure, hypothesize fix, apply patch, re-run tests, repeat — capped at five iterations, with a full transcript log of every hypothesis it tried, including the ones that made things worse." Narrow and concrete. The interesting design decisions are all still there: how do you decide when to stop retrying, how do you roll back a patch that made things worse, how do you avoid the agent thrashing on the same wrong fix five times in a row. That last requirement — logging the failed attempts, not just the final success — is what makes this a real capstone instead of a happy-path demo. It proves you understand that agent reliability is about bounding and recovering from bad decisions, not just making good ones.

Weak scope: "A customer support bot for an e-commerce site." Generic to the point of meaninglessness. Which support flows? Refunds? Order status? Product recommendations? Without a specific flow, this becomes a chatbot wrapper around an FAQ, not an agent.

Strong scope: "An agent that handles refund requests end-to-end: verifies order eligibility against a policy document (RAG), checks order status via a mock order API, and either auto-approves, auto-denies with a policy citation, or escalates to a human — with every decision logged with the exact policy clause it relied on." This has retrieval, tool use, a real decision boundary (approve/deny/escalate), and — critically — an auditability requirement. That auditability piece is what production teams actually care about, and almost no capstone projects include it. Adding "show your work" to any agent decision instantly makes a project look more mature.

The pattern across all of these: narrow the domain to one flow, keep two or three tools at most, and make the interesting part of the project the *decision logic*, not the integration surface area.

The technical bar: what "agentic" actually requires

A lot of projects get called agents because they call an LLM inside a for-loop. That's not the bar. Here's what should actually be present for a project to earn the word "agent" on your resume:

  • State that persists across steps. The agent needs to remember what it already tried, not just react to the current input in isolation. This can be as simple as an array of prior actions passed back into the prompt, or a proper memory store — but it has to exist.
  • A tool-calling boundary. The agent must be able to take an action in the world (call an API, run code, query a database, write a file) and observe the real result of that action, not just generate text about what it would do.
  • A decision point where the agent chooses between at least two paths. If the control flow is entirely fixed by your code (step 1 always leads to step 2 always leads to step 3), you've built a pipeline, not an agent. Somewhere, the model's output should determine which branch executes next.
  • A termination condition that isn't just "run once." Real agentic behavior loops until a goal is met or a limit is hit. Even a simple max-iteration cap with a success check counts — the point is that the loop's exit is a decision, not a given.
  • Observability into its own reasoning. You should be able to open a log and see why the agent did what it did, not just what it did.

Here's a minimal skeleton that satisfies all five, stripped down to make the shape visible:

class AgentRun:
    def __init__(self, goal, tools, max_steps=6):
        self.goal = goal
        self.tools = tools
        self.max_steps = max_steps
        self.history = []  # persisted state across steps

    def step(self, model):
        prompt = self.build_prompt(self.goal, self.history)
        decision = model.decide(prompt)  # decision point: which tool, or stop

        if decision.action == "stop":
            return "done", decision.rationale

        tool = self.tools[decision.action]
        try:
            result = tool.run(decision.args)
            outcome = {"action": decision.action, "args": decision.args,
                       "result": result, "ok": True}
        except Exception as err:
            outcome = {"action": decision.action, "args": decision.args,
                       "error": str(err), "ok": False}

        self.history.append(outcome)  # observability: full trace kept
        return "continue", outcome

    def run(self, model):
        for i in range(self.max_steps):
            status, payload = self.step(model)
            if status == "done":
                return {"success": True, "steps": self.history, "final": payload}
        return {"success": False, "steps": self.history, "reason": "max_steps_reached"}

Notice what's doing the actual work here: self.history is the persisted state, self.tools[decision.action] is the real tool boundary, the try/except is the unhappy-path handling that most demos skip, and the loop has an explicit, inspectable termination condition instead of running exactly once. None of this requires a fancy framework — it requires understanding what an agent loop is actually made of. Graders and interviewers can spot the difference between a project built on top of this understanding and one that's a single prompt wrapped in a chat UI within the first two minutes of looking at the code.

Pick a domain you can evaluate, not just demo

A subtle trap: choosing a domain where you can show the agent working, but can't actually tell if it's working *well*. Anything creative and subjective — "an agent that writes marketing copy," "an agent that suggests recipes" — is hard to evaluate because there's no ground truth. You'll end up cherry-picking your best three runs for the demo video and quietly ignoring the other twelve.

Pick domains with a checkable outcome instead:

  • Code and tests — you either pass the suite or you don't.
  • Structured data extraction — you either matched the schema and the values are correct, or they're not.
  • Rule-based decisions (refund policy, eligibility checks, compliance flags) — there's a right answer defined by the policy document, so you can build a test set.
  • Numeric or logical tasks (scheduling, routing, budget allocation) — outcomes are scoreable.

If your domain is inherently subjective, build in a proxy metric anyway. For a writing agent, that might be "does the output include all five required sections" or "does a second LLM call, used purely as a grader, rate it above a threshold on a rubric you defined." The point of a capstone is to demonstrate you can measure agent quality, not just produce agent output. A project with even a rough eval harness will outrank a flashier one that ships with zero numbers.

Build order: what to get working first

The order in which you build an agent project says a lot about whether you understand it. The common mistake is building the prompt first, the UI second, and the failure handling last — which means the failure handling never actually gets built, because by the time you get there the deadline is close and everything demos fine on the happy path.

Better order:

  1. Build the tools first, without any LLM involved. If your agent calls an order-lookup API, write and test that function standalone. Confirm it handles a missing order ID, a malformed ID, and a timeout, before any model ever touches it.
  2. Write the unhappy-path tests before the happy-path prompt. Decide now what "the agent handled this gracefully" means for each failure mode you listed earlier.
  3. Wire up the loop with a fixed, scripted "fake model" that returns hardcoded decisions, just to prove your state management and tool-calling plumbing work independently of prompt quality.
  4. Swap in the real model and tune the prompt. This is where most of your iteration time should go, but only after the scaffolding is solid.
  5. Add the eval harness and observability last, only in the sense that you validate it last — but design it in step 2, not step 5. Logging bolted on at the end is always worse than logging designed in from the start.

Building in this order also produces a much better capstone narrative for interviews: "I built the tool integration and tested its failure modes first, then wired in the model" is a sentence that signals engineering maturity. "I got a demo working then tried to make it robust" signals the opposite, even if the final code looks similar.

The write-up matters as much as the code

A capstone that ships without a README explaining the design decisions is a capstone nobody will fully credit you for, because the reviewer has to reverse-engineer your reasoning from the code alone. Include, at minimum:

  • The one-paragraph problem statement — what decision is the agent making, for whom, and why it's non-trivial.
  • The failure modes you designed for, listed explicitly, with what the agent does in each case.
  • Your eval results, even if the sample size is small — "tested against 40 refund scenarios drawn from three policy edge cases, correctly escalated all 6 ambiguous cases" is a sentence that does more for your credibility than any UI screenshot.
  • What you'd do differently at 10x scale. This single section signals more seniority than anything else in the write-up, because it shows you know the difference between "works for a demo" and "works in production," even if you didn't build the production version.
  • A short transcript of the agent failing and recovering (or failing and not recovering). Reviewers trust a project more, not less, when you show it breaking. It proves the demo isn't cherry-picked.

Common traps that quietly sink otherwise-good projects

A handful of mistakes show up again and again across capstones, independent of domain:

  • No cost or latency awareness. An agent that makes 40 model calls to answer one question will get flagged immediately by anyone who's shipped a production agent, because that's an unusable cost profile. Track and report your calls-per-task number.
  • Unbounded loops. If there's no max-iteration cap, you will eventually hit an infinite retry loop during a live demo, in front of the person you most wanted to impress. Always cap it, and make the cap a visible, tunable parameter.
  • Secrets committed to the repo. API keys in a .env file that's actually committed is an instant credibility hit for anyone hiring for a role that touches production systems.
  • No separation between the agent's "brain" and its tools. If the tool logic and the prompt logic are tangled in one giant function, it signals you haven't internalized why agents are architected the way they are — the whole point of the tool abstraction is that it's swappable and independently testable.
  • A demo video with no failure shown. Ironically, showing only successes reads as less trustworthy than showing one clean failure and how the system handled it.
  • Overreliance on a single framework's magic. If you can't explain what your orchestration framework is doing under the hood in your own words, you can't defend the project in an interview. Build at least one version of the loop by hand, even if you later migrate to a framework for convenience.

Scoping checklist before you commit to an idea

Run any capstone idea through this list before writing a line of code:

  • Can I name three concrete failure modes and what the agent should do for each?
  • Is there a single, clear tool-calling boundary, or have I accidentally scoped three separate integrations?
  • Can I measure success with something more rigorous than "it looked right when I tried it"?
  • Does the project have a real decision point, or is the control flow fully fixed by my own code?
  • Could I explain the whole architecture on a whiteboard in three minutes?
  • Would I be comfortable showing a reviewer a run where it failed?

If you can answer yes to all six, you have a capstone worth building. If two or three answers are shaky, that's exactly where to spend your planning time before you start coding — not after.

Closing: the capstone is the proof, not the practice

The lessons teach you the vocabulary — tool calling, memory, planning loops, evaluation. The capstone is where you prove you can assemble that vocabulary into something that survives contact with a real, messy input and a real failure. Keep the domain narrow, make the unhappy path a first-class citizen instead of an afterthought, and choose something you can actually measure rather than something that merely looks good in a screen recording. A tightly scoped agent that handles three failure modes gracefully and reports honest numbers on forty test cases will outperform a sprawling "does everything" assistant in every interview, every portfolio review, and every real engineering conversation you have about it afterward.

If you want a structured path through all of this — the tool-calling patterns, the memory architectures, the eval design, and a guided capstone build with review checkpoints — that's exactly what 30 Days of Hermes Agent walks you through, day by day, from Pramod Dutta and Ira Menon. The course is built around the same principle this article argues for: an agent capstone earns its name by how it handles the moment things go wrong, not by how polished the happy path looks.