Inspiration
I started this project from a problem I was personally facing.
I have technical skills and working projects that show what I can build, but I do not have years of traditional industry experience. When I started searching for jobs, I realized that finding the right opportunity was becoming a job by itself.
A relevant role could be on LinkedIn, Indeed, Google Jobs, Handshake, an ATS such as Greenhouse or Lever, or buried directly inside a company’s careers page. Even after hours of searching, I still could not be sure whether I had found the right roles or whether the listings were even still active.
There was another problem too.
Most job matching is heavily based on titles, keywords, and years of experience. An early-career candidate may never have held the title “AI Engineer,” but may already have built and deployed AI applications, connected APIs, automated workflows, worked with databases, or solved real problems through projects.
I wanted to build something that could understand that difference.
That became CareerScout.
How the idea evolved
CareerScout did not start as an ADK agent.
My first attempt was an automation workflow built with n8n.
The idea was simple:
- maintain a list of companies
- detect which ATS each company used
- search those job sources
- filter roles by title, experience level, and work authorization
- append relevant jobs into a structured output
I built separate branches for sources such as:
- Greenhouse
- Lever
- Wellfound
- CATSone
- Workday
- generic company careers pages
This taught me very quickly that job search automation is much harder than it looks.
Every ATS behaves differently.
Some expose structured data.
Some require HTML parsing.
Some redirect.
Some return 403 errors.
Some dynamically load content.
Some company career pages do not expose a clean individual job URL at all.
The biggest limitation of my n8n version was that I already needed to know which companies to search.
The automation could process companies I supplied, but it was not truly autonomous.
That led to the next question:
What if the system could decide where to search instead of requiring me to provide the companies?
That question became the foundation of CareerScout.
What CareerScout does
CareerScout is an autonomous job discovery and verification agent.
A user can provide:
- a target role
- location
- experience level
- explicit work-authorization constraints
- a specific job URL
- or even a resume and ask CareerScout to infer reasonable early-career roles
CareerScout then performs a full workflow:
Interpret → Discover → Inspect → Verify → Resolve → Classify → Explain
Instead of only returning search results, CareerScout independently checks whether the exact posting can still be verified.
Results are separated into:
- Verified Active
- Verified Closed
- Verification Failed
This last category is important.
CareerScout is designed to prefer uncertainty over false confidence.
If it cannot prove that a posting is current, it does not simply present it as active.
How I built it
CareerScout uses a hybrid architecture combining AI reasoning with deterministic Python verification.
The system is built using:
- Google ADK for agent orchestration
- Gemini 3.6 Flash through Vertex AI
- Google Search grounding for current-web discovery and verification
- Python for deterministic URL and page verification
- Pydantic for structured data validation
- Google Cloud Run for deployment
- Google Cloud Build and Artifact Registry for container build and deployment
The final architecture intentionally uses one public job tool:
search_and_verify_jobs
The ADK agent interprets the request and invokes this tool.
Internally, the tool performs the mandatory workflow.
First, Gemini with Google Search grounding discovers potentially relevant jobs.
Then Python independently inspects each discovered URL.
CareerScout checks things such as:
- whether the URL is reachable
- whether it points to a specific job instead of a generic company board
- redirects
- HTTP status
- title and company identity
- active or closed signals
If deterministic verification is not enough, CareerScout performs a grounded verification step using Gemini and Google Search.
Before any result is allowed to become verified_active, Python checks the canonical job URL again.
This prevents the model from being the only authority on whether a job is real and active.
One of the most important engineering discoveries
During development I learned that:
Structured output is not the same as truth.
An LLM can return perfectly valid JSON while the underlying information is still wrong.
I also learned that:
HTTP 200 does not mean a job is active.
A removed job may redirect to a generic careers page that still returns HTTP 200.
Similarly, finding a job title through search does not prove that the exact posting still accepts applications.
This changed the architecture.
CareerScout now treats:
Discovery and Verification
as separate problems.
Challenges
The hardest part of the project was not getting Gemini to find jobs.
The hardest part was deciding when CareerScout had enough evidence to trust a result.
Some of the issues I encountered included:
- generic ATS boards being mistaken for exact postings
- stale search results
- direct job URLs returning 404 or 410
- company pages returning HTTP 200 even when a job no longer existed
- Workday URLs changing or behaving inconsistently
- access-limited pages returning 403
- models finding the right job title but producing an unreliable direct URL
- grounded verification taking significantly longer than simple HTTP checks
- nested or more complex ADK workflow experiments causing execution and serialization problems
At one point I experimented with more complex agent/workflow structures.
Instead of making the project more reliable, they introduced additional failure modes.
That led me to simplify the design.
The final version uses:
One ADK agent + one public Python tool + deterministic internal verification
That architecture became much easier to reason about, debug, and trust.
Accomplishments that I am proud of
The project evolved from:
manual job searching
to:
n8n automation that required predefined companies
to:
an autonomous ADK agent that discovers where to search and independently verifies its findings
CareerScout can now:
- infer reasonable role families from resume evidence
- discover current job candidates from the public web
- inspect source URLs
- reject generic job boards as proof of an active role
- identify removed or closed postings
- perform grounded fallback verification
- enforce canonical direct job URLs
- preserve explicit sponsorship evidence without guessing
- return uncertainty instead of pretending to know
- run as a deployed application on Google Cloud Run
What I learned
This project taught me much more than how to call an LLM.
I learned that reliable agent systems need clear boundaries between:
- reasoning
- tools
- deterministic rules
- external evidence
I learned that an instruction such as:
“Always verify the job”
is not enough.
If verification is mandatory, the system should enforce it in code.
I also learned that simpler architectures can sometimes be more reliable than sophisticated multi-agent designs.
Most importantly, I learned to treat AI output as something that still needs evidence and verification.
What's next for CareerScout
The current hackathon MVP focuses on:
Scout → Verify → Explain
The next version could add:
- candidate-to-job evidence mapping
- deterministic qualification scoring
- Recommended / Worth Applying / Stretch classifications
- company-first employer discovery
- persistent job history
- application tracking
- asynchronous background monitoring
- personalized alerts
- long-term user preferences
- job-market intelligence
The long-term goal is to turn CareerScout from a job search tool into a trusted career-search agent that can continuously discover, verify, and explain opportunities for a candidate.
Built With
- gemini-3.6
- google-cli
- google-cloud
Log in or sign up for Devpost to join the conversation.