← Back to portfolio

// project

AI Product Engineer CopilotA multi-step agent that plans, cites its sources, and grades its own work

How the agent is built end to end, and why the eval/observability layer, not the agent loop itself, is where most of the engineering effort went.

Most agent demos stop at 'it can call a tool.' I wanted to answer a harder question: how do you actually know an agent is getting better, not just different — and how do you prove it didn't just make up that analytics number?
AI Product Engineer Copilot — Home screen — describe a product or feature, or try an example prompt

// the problem

PM-facing agent tools are easy to demo and hard to trust. A generated PRD can look polished and still cite a metric nobody measured, skip a step because a node degraded silently, or regress on exactly the case that mattered — with no way to catch any of it before a person reads the whole thing.

// the solution

Design the rigor layer in from day one, not bolted on after: a supervisor + sub-agent graph where every deliverable after the PRD depends on it explicitly instead of guessing in parallel, MCP tool calls that degrade to a visible note instead of a fabricated answer, and an eval harness with a golden set, a bias-checked LLM judge, and a four-tag failure taxonomy that can specifically catch a hallucinated claim.

A supervisor + sub-agent graph, not a flat fan-out

The PRD agent runs first, alone — every other deliverable (user stories, architecture review, experiment design) is a downstream consumer of what it decides, not an independent parallel branch. Those three fan out in parallel once the PRD exists in shared graph state, a roadmap agent joins all of it into a sequenced plan, and an assembler merges the five outputs into one response. A flat five-way fan-out was the first draft, and it broke immediately: an architecture reviewer can't review an architecture nobody proposed yet.

MCP tools grounded in real data, not fixtures

Two MCP servers back the graph: one does embedding-based search over this project's own docs via pgvector in Neon Postgres, the other pulls live GitHub repo stats through the GitHub API, cached with a 1-hour TTL. A failed tool call degrades to a visible '[data unavailable]' note in the affected deliverable instead of crashing the run or letting the model quietly invent a number — the same anti-hallucination discipline whether the failure is a flaky API or a rate limit.

An eval harness whose judge has to prove itself first

A golden-set regression harness runs the real graph against a fixed set of requests and grades each deliverable with an LLM judge on a five-point rubric plus the four-tag failure taxonomy. Before it grades anything real, the judge has to correctly score two known-answer control documents — a fluent PRD that says nothing, and specific user stories tied to real numbers — or the run aborts with 'the instrument is broken' instead of a list of false regressions. It isn't run on every visitor's request, since that would roughly double the model spend on a demo whose whole pitch is that it's cheap — it's a pre-deploy check, not a live gate.

// key takeaways

// tradeoffs

TypeScriptNext.jsLangGraph.jsVercel AI SDKMCP SDKNeon Postgres (pgvector)
View live ↗Get in touch