Inspiration
As a B.Tech Computer Science student actively hunting for my first internship, I was spending hours every week doing the same repetitive task: reading job descriptions, figuring out if I was actually a fit, and writing a cover letter from scratch each time. It felt like exactly the kind of tedious, multi-step process that an AI agent — not just a chatbot — should be able to take off my plate. When I saw the "Agents for Humans" theme, this was the first real problem I thought of, because it's one I live with every week.
What it does
The Job-Hunt Agent takes a candidate's resume/skills and a set of job postings, then autonomously:
- Scores each job posting against the candidate's actual experience — not just keyword matching, but reasoning about genuine skill overlap
- Ranks the postings by fit, flagging what's missing when the match is weak
- Drafts a personalized, honest cover letter for the strongest matches
- Presents everything in a clean, ranked dashboard
It's built as a genuine multi-step agent — score → filter → draft — rather than a single prompt-response wrapper.
How I built it
- Frontend + Backend: Next.js (App Router) — one codebase for the UI and API routes
- AI: OpenRouter, using free-tier models, so the entire agent runs at zero cost
- Database: Supabase (Postgres) for storing job data and results
- Design: A custom UI system built around a warm, editorial "case file" aesthetic instead of the default AI-hackathon look, with Framer Motion used sparingly — one staggered reveal when the agent finishes ranking, rather than animation everywhere
The core of the project lives in lib/prompts.ts — two focused system prompts, one for scoring and one for cover-letter generation, chained together in an orchestration route that calls the scoring prompt across all postings, filters for the best matches, and only then spends tokens generating cover letters for those.
Challenges I ran into
This was my first time building an actual agent rather than a simple AI wrapper, so most of my challenges were about tooling, not the core logic:
- I initially tried wiring free OpenRouter models directly into Claude Code through a local router, which turned into a multi-hour debugging chain — broken native dependencies, protocol mismatches between Anthropic's API format and OpenAI-compatible providers, and a corrupted Windows binary. Eventually I made the call to switch to Cursor with OpenRouter's OpenAI-compatible endpoint instead, which was far more direct.
- Learning to write prompts that behave like decision-making steps (score, then conditionally draft) rather than a single Q&A completion took some iteration — my first version generated cover letters for every job, wasting time and tokens instead of only for the top matches.
- Working entirely with free-tier models meant occasionally dealing with rate limits and inconsistent output formatting, which pushed me to add stricter JSON-only response instructions to the prompts.
What I learned
That an "agent" is defined by its decision-making chain, not by which model powers it — and that a huge amount of the real work in building one is prompt discipline (forcing structured output, scoping each step tightly) rather than the AI call itself. I also learned, the hard way, when to cut losses on a tooling rabbit hole and switch to the simpler path.
Built With
- ai-agent
- artificial-intelligence
- career
- css
- deepseek
- framer-motion
- html
- javascript
- llm
- nextjs
- node.js
- openai-api
- openrouter
- postgresql
- react
- supabase
- tailwindcss
- typescript
- vercel

Log in or sign up for Devpost to join the conversation.