Skip to content

span 01 · case study · ask-my-agent · ai

Ask my agent

The tool-use agent behind this site's ⌘K palette, with a live trace of every call.

Role
Design & build
Year
2026
Stack
Next.js · TypeScript · Anthropic SDK · SSE · Zod

span 02 · architecture

⌘K palette/api/agentrate limiterClaudecontent toolsSSE stream

span 03 · write-up

The problem

A portfolio claims skills; recruiters skim. I wanted the site itself to prove the claim — an agent you can talk to, built the way I'd build one for production, with its reasoning visible.

How it works

The ⌘K palette posts the conversation to /api/agent. The route validates the body with Zod, rate-limits per IP, then runs a manual tool-use loop against Claude. The model can call four tools — search_projects, get_experience, get_stack and get_contact — which are plain functions over the same typed content that renders these pages. Events stream back over SSE and the palette renders each tool call as a span, live.

Decisions

  • The tools are the only source of facts. The system prompt forbids stating anything the tools didn't return, so the agent says "I don't know" instead of inventing an employer or a number.
  • Cost is capped before the model is touched. Input length, conversation length, tool iterations and requests per IP are all bounded.
  • It degrades, it doesn't break. No key, a rate limit or an upstream error switches the palette to clearly labelled scripted answers.
  • Drafts never leak. In production the tools see exactly what the pages show.

What I'd add next

An eval set of recruiter questions with expected tool calls, run in CI on every prompt change, and latency/cost numbers published in the footer.

span 04 · metrics

Content tools
4
Max tool iterations
4
p95 latency
not yet measured