How this site works

A plain-English look at how the assistant finds the right context, chooses an answer, checks its work, and handles failures.

Responds in real time

Answers appear as they are written, and the status reflects what the assistant is actually doing — not a fake typing animation.

Finds the right context

Searches for both exact words and related ideas, then combines the strongest matches before answering.

Human judgment first

I review test answers first, then compare the AI judges against those human decisions.

Built to fail safely

If context search is unavailable, the assistant uses the full resume instead, so visitors can still get an answer.

Architecture

One FastAPI service serves the static frontend and the API. Guardrails (rate limits, quotas, validation) run before any model call; retrieval and model routing run concurrently; the answer streams back over SSE.

Architecture diagram The browser connects to the application, which searches for exact words and related ideas while choosing the right Claude model, then streams the answer back. Browser vanilla JS · no framework FastAPI gateway guardrails · quotas · model router Haiku classifier picks the model Context search exact words + meaning combines best matches resume + project notes Claude Opus — complex Sonnet — simple fallback on failure Answer assembly grounded reply · sources · follow-ups SSE stream back tokens render live

Streaming & model routing

Every chat is a real server-sent-event stream: the browser shows retrieval status, then tokens as Claude produces them. What you see in the status steps is what actually happened — a cached answer says "answered from cache," it doesn't fake a search.

A small Haiku classifier (4 output tokens, 2-second timeout) routes each question: simple factual lookups go to Sonnet, synthesis and comparisons go to Opus, and any router failure fails safe to the most capable model. Routing runs concurrently with retrieval, so it adds no time to first token.

event: status   {"stage": "rag_search", "state": "done", "sources": [...]}
event: status   {"stage": "routing", "state": "done", "model": "sonnet"}
event: delta    {"text": "Dakota is PCAP-certified and uses Python in"}
event: done     {"reply": "...", "sources": [...], "followups": [...]}

How it finds the right context

When someone asks a question, the assistant searches my resume and project notes in two ways: one looks for the exact words they used, and the other looks for ideas with a similar meaning. It combines the best matches and gives Claude the most relevant context before it answers.

If search is temporarily unavailable, the site uses the full resume instead, so visitors can still get an answer.

Human-judged LLM

I reviewed a 100-question test set by hand, using pass/fail labels and written critiques to identify recurring problems. I then built three focused LLM graders and compare their verdicts with the human labels. The graders are still being tuned, so human judgment remains the standard. This workflow is inspired by Hamel Husain's human-first evaluation approach.

Connect your own AI

The MCP endpoint doesn't run my AI assistant for you. It exposes my resume as structured, AI-readable data so your own agent or preferred AI tool can reason over it. The flow is deliberately simple:

  1. Your MCP client connects to the remote server at /mcp (streamable HTTP, no authentication).
  2. It discovers a single read-only tool: get_resume.
  3. get_resume returns structured career data — experience, projects, skills, education, and certifications. Private contact details like my phone number are excluded.
  4. Your AI does the reasoning: fit comparisons, gap analysis, summaries, interview prep — with its own model, on your side of the connection.

That split is intentional. The server exposes data, not a hosted model — so any compatible MCP client that supports remote servers gets the same structured access, and what its AI concludes is up to it. The resume is also machine-readable without MCP: /llms.txt is rendered live from the same source of truth.

To connect a compatible client, add a remote MCP server with this URL (streamable-HTTP transport, no authentication):

https://www.dakotaradigan.io/mcp

Claude (claude.ai or desktop): Settings → Connectors → Add custom connector, then paste the URL above.

Claude Code (terminal):

claude mcp add --transport http resume https://www.dakotaradigan.io/mcp

Then ask your assistant something like "Using the resume tool, is Dakota a fit for this role?" Other MCP-compatible clients that support remote servers work the same way.

Ask the assistant about any of this