Multi-LLM GenAI Job-Search Agent
A multi-LLM system I designed, built and use every day. It finds relevant roles across the UK and Europe, ranks each one against my CV with a three-model LLM-as-a-judge cascade, tracks every application on a Kanban board, and assists with application forms through a Chrome extension that learns from my edits.
Job hunting is a data problem
Relevant roles are spread across hundreds of employer sites and a dozen job boards. Many are duplicates or stale "ghost" adverts, and each suitable role ends in a form with 20 to 60 questions. I wanted a system that does the finding, filtering and form filling, and leaves the judgement calls to me.
Collect, clean, rank, track, apply
Sources
9 ATS APIs across 356 employers, plus Reed, Adzuna and LinkedIn, Indeed and Google Jobs through Bright Data.
Normalise
One schema, fuzzy de-duplication, agency filtering and UK, EU and rest-of-world tiers.
LLM scoring
A rubric-based fit score, reasoning, skill gaps and a ghost-job flag for every role.
Web app
A Next.js dashboard, a Kanban tracker and daily Telegram reports with the best matches.
Browser extension
Saves postings, flags duplicates, fills forms from the right CV and drafts written answers.
Runs daily on GitHub Actions, stores data in Supabase Postgres, serves the web app from Vercel, and uses OpenAI, Google Gemini and DeepSeek models.
The engineering behind it
1. A three-model LLM-as-a-judge cascade that keeps costs down
Each role is scored from 0 to 100 against my CV by a model acting as a strict recruiter. It follows a written rubric (seniority, required stack, domain, location and right to work) and returns structured JSON: the score, its reasoning, named skill gaps and a ghost-job flag. The design problem was accuracy at thousands of roles a day without paying frontier-model prices for all of them.
Strong matches also get CV recommendations: the keywords the role asks for that I can genuinely evidence, and where to put them. The right one of my nine role-specific CVs is picked by fixed rules based on role family, seniority and the cloud platform the advert emphasises.
2. Collecting jobs from 9 ATS platforms and the main job boards
- ATS detection: each employer's careers URL is classified and routed to the right public API: Greenhouse, Lever, Ashby, SmartRecruiters, Workable, Recruitee, Personio, Workday and Teamtailor.
- Job boards: Reed, Adzuna across a prioritised list of countries, and LinkedIn, Indeed and Google Jobs results through Bright Data and Apify.
- Fuzzy de-duplication: two adverts count as one job when employer and title match and either the description is near-identical or the location matches, so a role posted in five towns becomes one row.
- Quality filters: recruitment agencies are removed so only direct employers remain, and roles are grouped into data science, AI engineering and data analysis.
- One source of truth: the country table and CV-matching rules are written once in Python and generated into TypeScript for the web app and extension, with tests that fail if the copies drift apart.
3. A Chrome extension that fills application forms and learns
A Manifest V3 extension adds a floating assistant to job pages. It reads the advert, warns me if the job is already on my tracker, and on an application form fills in four passes:
Most of the effort went on the web itself: forms inside shadow roots and cross-origin iframes, React inputs that ignore plain value changes, Workday dropdowns that are buttons rather than select boxes, and attaching the right CV to the upload field.
4. A web app and Kanban tracker on the same data
- Next.js 14, TypeScript and Tailwind, exported as a static site on Vercel behind Supabase Auth with row-level security, and installable on iPhone and iPad.
- A jobs explorer split by region and role family, with spreadsheet-style column filters that persist, CSV export and one-click saving to a board.
- A Kanban tracker with custom boards, drag and drop, activity logs and age badges that count from the date I applied. My earlier application history was migrated in with an import script.
Built to be trusted
A tool that writes to employers on my behalf has to be reliable before it is clever.
A person in the loop
Nothing is submitted automatically. Every drafted answer is shown for review, and CAPTCHAs are handed back to me rather than bypassed.
No invented facts
Facts come from rules, not the model. Multiple-choice answers must match one of the form's options, and tools I've only used in projects are labelled as such.
Secrets kept out of the page
API keys live only in the extension's background worker. The browser uses the public key, and the database is locked with row-level security.
The code is in a private repository because it holds personal data. I'm happy to demo it or walk through the code.