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.
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:
- Your MCP client connects to the remote server at
/mcp(streamable HTTP, no authentication). - It discovers a single read-only tool:
get_resume. get_resumereturns structured career data — experience, projects, skills, education, and certifications. Private contact details like my phone number are excluded.- 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.