Inspiration
I'm a Computer Engineering student looking for my first developer role, and remote job hunting is genuinely exhausting: open a job board, scroll past dozens of postings, most a poor fit, and for the few worth applying to, write a cover letter from scratch and hope your résumé's keywords happen to match what an ATS is scanning for. I was doing this myself, by hand, every day.
I'm also the target user — not a hypothetical one. Every design decision in BidWatch came from what I actually wanted while job hunting.
What it does
BidWatch is an AI agent, built with the Strands Agents SDK on Amazon Bedrock, that:
- Scans remote job postings on a schedule
- Scores each new posting against a detailed profile of my real skills, rates, and deal-breakers
- For strong matches, generates a tailored résumé — cherry-picking the projects, skills, and bullet points most relevant to that specific job from a structured career database, so a .NET job gets a .NET-led résumé and a Python job gets a Python-led one
- Drafts a tailored cover letter in my voice
- Sends everything to Telegram as one reviewable package: score, company info, salary if listed, the résumé PDF, the letter, and a field sheet with every value an application form typically asks for
The user's only remaining job is the one a machine shouldn't make: review, and apply.
How I built it
The core is a single Strands agent orchestrating focused tools — fetching postings, deduplicating against a local store, scoring with reasoning (not just keyword matching), generating the résumé, drafting the letter, and notifying. A Telegram bot handles the interactive side: buttons for Bid, Open, Skip, and an edit loop that lets me tell the agent "make it shorter" or "mention the restaurant project" and get a regenerated draft instantly.
The résumé generator was the most interesting piece to build. My profile.md holds a complete, tagged career database — every project's bullets are tagged by which stack and skill they demonstrate. When a job comes in, the model analyzes the posting and returns only identifiers — which summary variant, which skills, which project bullets — and the actual résumé text is copied verbatim from the source file. The model never generates résumé content directly; it only selects and orders. This means invented experience has no code path at all, not just a prompt asking the model to behave.
Challenges I ran into
Getting Bedrock access from a new account. I burned several days on AccessDeniedException and ThrottlingException errors before realizing my account had zero provisioned quota on newer Claude models, some of which weren't available for my account's region at all. I ended up building on GLM 5 instead — which turned out to be an unplanned but useful lesson in keeping the model provider swappable behind one config line.
Deciding not to auto-submit applications. I originally wanted BidWatch to fill out and submit application forms automatically. After building a browser-automation prototype, I hit the real wall: most employer application flows sit behind logins, CAPTCHA, or platform-specific gating that can't be reliably automated — and even where it's technically possible, I didn't want an agent submitting my name and words to a real employer without me reading it first. I deleted the auto-submit code entirely rather than leave a half-working feature, and rebuilt the flow around a simple principle: the agent prepares, the human submits. A test in the suite asserts no module in the project contains an outbound submission path at all — the guarantee is architectural, not just a setting I could forget to check.
Keeping the agent honest. Early cover letters occasionally drifted toward confident-sounding claims not actually in my profile. I rewrote the system prompt with an explicit hard rule against this, and it shows in the output — on a senior-level posting, the agent wrote plainly that it wasn't the seniority level the role wanted, rather than inflating my experience to look like a better match. I'd rather apply to fewer jobs honestly than more jobs dishonestly.
Keeping secrets out of a public repo. profile.md needed to be public for the hackathon submission, but it originally held my phone number and email. I moved contact details into a separate, gitignored applicant.md file and added a test that fails the build if contact information is ever committed to the public file.
What I learned
Real depth in an agent comes from tool and prompt design, not model choice — I built the entire thing on a mid-tier model and it works well, because the hard problems (safe field selection, honest scoring, graceful fallbacks) are architecture, not model horsepower. I also learned that the most valuable thing I could remove from this project was a feature — automated submission — and that saying so plainly is more convincing than pretending the limitation doesn't exist.
What's next for BidWatch
- A second job source (I have a Freelancer.com integration partially scoped, using the same source-adapter pattern already proven with the current feed)
- Deployment to Amazon Bedrock AgentCore for scheduled, always-on runs
- Assisted form-filling for known ATS providers, where a human still reviews and clicks submit
I'm continuing to use BidWatch for my own job search after the hackathon — it's already found and prepared applications I wouldn't have otherwise gotten to.
Built With
- claude
- python
- strands
Log in or sign up for Devpost to join the conversation.