← AI Engineering / Case study 01

See If We Match.

An agentic RAG assistant that checks a job description against my portfolio, live. Every requirement is rated Strong, Partial or Missing, with an exact quote and a link to the evidence.

Role
Solo build: design, backend, frontend, evaluation, deployment
Audience
Recruiters & hiring managers
Year
2026
Status
Live on every page of this site

Project presentation · use ← → or swipe

The problem

Recruiters have to match a job's requirements to a portfolio by hand, searching every project for each skill, and that takes time. So I built a chat that does the mapping for them, and names the gaps honestly instead of hiding them.

What I built

  • Paste a job description, get a fit check. The agent searches my projects, CV and site, then rates every requirement Strong / Partial / Missing with a word-for-word quote and a source link.
  • A ReAct loop with 3 tools (search_portfolio, list_skills, get_project), max 6 rounds. No framework, for a fast serverless cold start and easy-to-follow code.
  • RAG without a vector database. Website HTML + CV + a facts file become 71 section-aware chunks, embedded with text-embedding-3-small and searched by cosine similarity in pure Python.
  • Live agent steps. FastAPI streams each step to the browser over Server-Sent Events, so recruiters see the agent work.
  • Built to be reusable. All personal details live in one config file with a setup guide, so anyone can swap in their own site, CV and facts.

Lightweight by design

Not every agent needs LangGraph, a vector database and a backend server. For a job this size, a small agent does the work just as well, and it's cheaper and easier to keep running.

Read more

No database. The whole knowledge base is two JSON files of about 1 MB: knowledge.json with 71 text chunks and embeddings.json with their vectors. They load into memory when a request comes in, and retrieval is a few lines of Python comparing vectors by cosine similarity. For 71 chunks that takes milliseconds, so a vector database would only add another service to host and pay for.

No agent framework. The ReAct loop runs directly on the OpenAI SDK. The only dependencies are FastAPI and OpenAI, which keeps the serverless cold start fast and the code easy to follow.

One serverless function on Vercel. The website is static and the agent is a single Python function that only runs when someone asks a question. Nothing runs between visits, and a job check costs under 1¢.

Easy to update. When the site text changes, one script rebuilds the JSON files, and they ship with the next deploy.

Knowing the limit. This works because the knowledge is small and changes rarely. With thousands of documents, frequent updates or per-user data, I'd use a vector database, the way I did in DropOperator with Pinecone and Supabase.

How I built it

I built See If We Match with Claude Code, Anthropic's AI coding assistant, as my pair programmer. I set the goals, made the architecture and model choices, decided what the eval tests check and ran them after every change. Claude Code helped me write, debug and refactor the code.

Difficulties solved

  • Hallucination: every rating must quote the portfolio word for word; no quote means Missing.
  • Overrating: today's date is injected, and years of experience are counted from dated evidence.
  • Inconsistent runs: evidence first, verdict last. The model writes the quote before choosing the rating.
  • Prompt injection: user text is treated as data, and chat history only accepts user/assistant roles.
  • Broken links: repaired in code, because deterministic fixes belong in code, not prompts.

Evaluation

An automatic eval suite runs 4 test cases with 13 pass/fail checks, including a check that every quote really exists in the portfolio. With a date-aware prompt and an evidence-first format, gpt-5.4-mini passes 13/13 on repeated runs with 0 invented quotes, at under 1¢ per job check, about 7× cheaper than gpt-5.5.

  • Python
  • FastAPI
  • OpenAI API (tool calling, embeddings)
  • RAG
  • ReAct agent
  • SSE streaming
  • Vanilla JS
  • Vercel
Next projectAI Sales Assistant →