JobPilot
Inspiration
Job hunting is often repetitive, fragmented, and emotionally exhausting. Candidates search across multiple sources, compare job descriptions manually, rewrite resumes, draft cover letters, and still struggle to understand which opportunities are genuinely worth pursuing.
We built JobPilot to make that process more focused and human-centered. Instead of automatically applying to every possible role, JobPilot helps candidates discover relevant jobs, understand their fit, prepare personalized application materials, and make the final decision themselves.
What It Does
JobPilot is an autonomous AI job-search and application-preparation agent. A user provides their target role, location, skills, experience, and resume information. The system then:
- Discovers relevant job opportunities.
- Analyzes each role against the candidate’s profile.
- Identifies matching and missing skills.
- Scores and ranks opportunities.
- Generates preparation packages with resume bullet suggestions and cover letter drafts.
- Pauses for human review before anything can be submitted.
The system never auto-submits an application. Every generated package is marked as requiring human review, keeping the candidate in control.
How We Built It
JobPilot uses a React, TypeScript, and Vite frontend with a Python and FastAPI backend.
The backend is organized around a workflow state machine:
queued -> discovering -> analyzing -> ranking -> preparing -> waiting_for_review -> completed
The AI analysis layer supports Google Gemini through the Google ADK. It evaluates job descriptions, candidate skills, experience, and optional resume text to produce structured results such as:
- Match score
- Matching skills
- Missing skills
- Recommendation
- Explanation
To make the project reliable during development and testing, we also built deterministic offline implementations. Job discovery can use a mock provider or an external provider, while the AI layer falls back to predictable analysis when no API key is configured.
For persistence and asynchronous execution, JobPilot uses repository and publisher abstractions:
- In-memory storage for local development and tests
- Firestore for production workflow state
- In-memory Pub/Sub simulation for demos
- Google Cloud Pub/Sub for production background processing
- Separate Cloud Run services for the API and worker
This architecture lets us test the complete workflow without requiring cloud credentials or incurring API charges.
What We Learned
We learned that building an AI agent is not only about generating good text. The surrounding system matters just as much:
- Structured outputs are essential when AI results drive application logic.
- Human review must be designed into the workflow, not added as an afterthought.
- Interfaces and abstractions make it possible to switch between local mocks and production services.
- Asynchronous processing gives users a faster experience while long-running analysis continues in the background.
- Deterministic fallbacks make AI-enabled systems easier to test, demo, and debug.
- Least-privilege cloud architecture and keeping secrets out of workflow records are important parts of responsible AI development.
Challenges
One challenge was coordinating several stages of work without blocking the user interface. We addressed this by creating the workflow record first, publishing only its workflow_id, and letting a worker process the job asynchronously.
Another challenge was making the application testable without depending on Gemini, Firestore, Pub/Sub, or production credentials. We solved this with provider and repository interfaces, in-memory implementations, fake cloud clients in tests, and deterministic mock analysis.
We also had to balance automation with safety. Generating a convincing cover letter is useful, but submitting an application without review could introduce incorrect claims or unwanted applications. JobPilot therefore treats AI output as preparation material, clearly labels it as AI-generated, and keeps application_status as not_submitted until a human explicitly decides what to do.
The Result
JobPilot turns a scattered job-search process into a transparent workflow. It combines discovery, personalized analysis, ranking, and application preparation while preserving candidate control at the most important point: the final decision to apply.
Built With
- ai-agents
- asynchronous-processing
- cloud-firestore
- cloud-pub/sub
- cloud-run
- docker
- fastapi
- google-adk
- google-cloud
- google-gemini
- human-in-the-loop-ai
- job
- llm
- natural-language-processing
- pydantic
- python
- react
- rest-api
- search
- typescript
- vite
Log in or sign up for Devpost to join the conversation.