Build Your Own AI Job Search Agent in 30 Minutes
Step-by-step tutorial: use HireQL API + OpenAI/Anthropic to build a personalized job-hunting agent that finds, filters, and summarizes remote dev jobs based on your preferences.
RVCJ Editorial
Editorial Team
The Remote Vibe Coding Jobs editorial team covers AI-assisted development, remote work trends, and career guides for modern developers.
Job boards are dumb. They show you everything. You filter by "remote" and get 10,000 results, half of which are "remote available" (read: you better live near an office).
AI agents are smart. They can read your preferences, query job APIs, filter noise, and surface only the stuff that actually fits.
Let's build one. 30 minutes. Python. No fluff.
What We're Building
A personal job agent that:
- Queries HireQL API for remote jobs
- Uses an LLM (GPT-4, Claude, whatever) to rank them based on your preferences
- Summarizes the top matches and sends you a daily digest
You'll be able to say things like:
- "I want senior backend roles, preferably Rust or Go, async culture, transparent salary"
- "No blockchain, no ad-tech, no 'move fast and break things' nonsense"
And the agent will handle it.
Prerequisites
- Python 3.9+
- A HireQL API key (get one at /developers)
- An OpenAI or Anthropic API key
Step 1: Set Up the Project
mkdir job-agent
cd job-agent
python -m venv venv
source venv/bin/activate # or venv\Scripts\activate on Windows
pip install requests openai python-dotenv
Create a .env file:
HIREQL_API_KEY=your_hireql_key_here
OPENAI_API_KEY=your_openai_key_here
Step 2: Query HireQL
Create hireql.py:
import os
import requests
from dotenv import load_dotenv
load_dotenv()
HIREQL_API_KEY = os.getenv("HIREQL_API_KEY")
BASE_URL = "https://remotevibecodingjobs.com/api/v1"
def search_jobs(tech=None, vibe_tags=None, posted_since=None, limit=20):
"""Search jobs via HireQL API"""
headers = {
"Authorization": f"Bearer {HIREQL_API_KEY}",
"Content-Type": "application/json"
}
payload = {
"limit": limit
}
if tech:
payload["tech"] = tech
if vibe_tags:
payload["vibe_tags"] = vibe_tags
if posted_since:
payload["posted_since"] = posted_since
response = requests.post(
f"{BASE_URL}/jobs",
headers=headers,
json=payload
)
response.raise_for_status()
return response.json()["jobs"]
# Test it
if __name__ == "__main__":
jobs = search_jobs(tech=["python", "typescript"], limit=5)
for job in jobs:
print(f"{job['title']} at {job['company']}")
print(f" {job['url']}\n")
Run it:
python hireql.py
You should see a list of jobs. If not, check your API key.
Step 3: Add AI Ranking
Now let's use GPT-4 to rank jobs based on personal preferences. Create agent.py:
import os
from openai import OpenAI
from hireql import search_jobs
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
# Your preferences (customize this!)
PREFERENCES = """
I'm looking for:
- Senior backend or full-stack roles
- Rust, Go, or TypeScript (bonus for Rust)
- Remote-first companies (not "remote available")
- Async culture, minimal meetings
- Transparent salary (dealbreaker if not listed)
- No blockchain, crypto, ad-tech, or surveillance tech
- Prefer smaller companies or early-stage startups
"""
def rank_jobs(jobs):
"""Use GPT-4 to rank jobs based on preferences"""
# Format jobs for the LLM
jobs_text = "\n\n".join([
f"Job {i+1}:\n"
f"Title: {job['title']}\n"
f"Company: {job['company']}\n"
f"Tech: {', '.join(job.get('tech_stack', []))}\n"
f"Vibe: {', '.join(job.get('vibe_tags', []))}\n"
f"Salary: {job.get('salary', 'Not listed')}\n"
f"URL: {job['url']}"
for i, job in enumerate(jobs)
])
prompt = f"""
You are a job search assistant. I'm going to give you my preferences and a list of jobs.
Rank the jobs from best to worst fit, and explain why.
My preferences:
{PREFERENCES}
Jobs:
{jobs_text}
Return a ranked list with brief explanations. Be honest — if a job is a bad fit, say so.
"""
response = client.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": "You are a helpful job search assistant."},
{"role": "user", "content": prompt}
],
temperature=0.3
)
return response.choices[0].message.content
# Main agent loop
if __name__ == "__main__":
print("Fetching jobs from HireQL...")
jobs = search_jobs(
tech=["rust", "go", "typescript"],
vibe_tags=["async", "transparent-salary"],
posted_since="7d", # last 7 days
limit=15
)
print(f"Found {len(jobs)} jobs. Ranking with AI...\n")
ranking = rank_jobs(jobs)
print(ranking)
Run it:
python agent.py
You'll get a personalized ranking like:
**Best Fits:**
1. Senior Rust Engineer at Oxide Computer
- Perfect match: Rust-first, transparent salary ($180k-$220k), async culture
- Small team, systems-level work
- https://remotevibecodingjobs.com/jobs/xyz789
2. Backend Engineer at Remote First Co
- Good fit: Go + TypeScript, remote-first, no meeting culture
- Salary listed: €130k-€160k
- https://remotevibecodingjobs.com/jobs/abc456
**Okay Fits:**
3. Full-Stack Engineer at StartupXYZ
- TypeScript focus, remote-available (not remote-first)
- Salary not listed (potential dealbreaker)
- https://remotevibecodingjobs.com/jobs/def123
**Not Recommended:**
4. Blockchain Developer at CryptoVentures
- Disqualified: crypto/blockchain (per your preferences)
- https://remotevibecodingjobs.com/jobs/nope999
Step 4: Automate Daily Digests
Let's send the results to your email or Slack. Here's a simple email version using SMTP:
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
def send_email(subject, body, to_email):
"""Send email via Gmail SMTP (or any SMTP server)"""
from_email = os.getenv("EMAIL_USER")
password = os.getenv("EMAIL_PASSWORD")
msg = MIMEMultipart()
msg['From'] = from_email
msg['To'] = to_email
msg['Subject'] = subject
msg.attach(MIMEText(body, 'plain'))
with smtplib.SMTP('smtp.gmail.com', 587) as server:
server.starttls()
server.login(from_email, password)
server.send_message(msg)
# Add to agent.py
if __name__ == "__main__":
jobs = search_jobs(
tech=["rust", "go", "typescript"],
vibe_tags=["async", "transparent-salary"],
posted_since="24h", # daily
limit=10
)
if len(jobs) > 0:
ranking = rank_jobs(jobs)
send_email(
subject=f"Daily Job Digest: {len(jobs)} new matches",
body=ranking,
to_email="your_email@example.com"
)
print("Digest sent!")
else:
print("No new jobs today.")
Add to .env:
EMAIL_USER=your_gmail@gmail.com
EMAIL_PASSWORD=your_app_password
Set up a cron job to run daily:
0 9 * * * /path/to/venv/bin/python /path/to/agent.py
Now you get a personalized job digest every morning at 9 AM.
Step 5: Add Smarts (Optional)
Track Applied Jobs
Store job IDs in a local file so you don't see duplicates:
import json
SEEN_FILE = "seen_jobs.json"
def load_seen_jobs():
try:
with open(SEEN_FILE, 'r') as f:
return set(json.load(f))
except FileNotFoundError:
return set()
def save_seen_jobs(job_ids):
with open(SEEN_FILE, 'w') as f:
json.dump(list(job_ids), f)
# Filter out seen jobs
seen = load_seen_jobs()
new_jobs = [job for job in jobs if job['id'] not in seen]
if new_jobs:
ranking = rank_jobs(new_jobs)
send_email(...)
# Mark as seen
seen.update(job['id'] for job in new_jobs)
save_seen_jobs(seen)
Auto-Apply (Experimental)
If a job is a perfect match (e.g., ranked #1 with high confidence), you could auto-fill applications using tools like Puppeteer or Playwright. But that's a whole other tutorial.
Using Claude Instead of GPT-4
Prefer Anthropic? Swap the OpenAI client:
from anthropic import Anthropic
client = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
def rank_jobs(jobs):
# ... same prompt ...
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=2000,
messages=[
{"role": "user", "content": prompt}
]
)
return response.content[0].text
What You've Built
In 30 minutes, you've created an AI agent that:
- Searches 630+ remote jobs via HireQL
- Filters by your tech stack and vibe preferences
- Uses GPT-4/Claude to rank matches
- Sends you a daily digest
- Avoids showing you jobs you've already seen
No more manual scrolling. No more "remote available" bait-and-switch. Just the jobs that fit.
Next Steps
- Add more filters — salary range, company size, funding stage
- Integrate with Notion/Airtable — auto-log jobs to your tracker
- Build a web UI — Flask + React for a personal job dashboard
- Deploy to the cloud — run it on a cron service like Render or Railway
Check out our API stats to see what else you can query.
Final Thoughts
AI agents aren't magic. They're just automation + intelligence. HireQL gives you the data. LLMs give you the smarts. You wire them together.
The best part? This works for any API. Job search today, apartment hunting tomorrow, freelance gigs next week. The pattern is the same.
Now go build something cool.
Browse Related Remote Jobs
Find remote developer jobs that match the topics in this article.
Related Articles
The Future of Job Hunting: AI Agents That Apply For You
Why job applications are ripe for automation, how AI agents can handle the grunt work, and why APIs like HireQL are the foundation for autonomous job search.
Why Every Developer Needs a Job Search API (And How HireQL Delivers)
Stop scraping job boards manually. Learn how job search APIs give developers programmatic access to remote job data, and why HireQL is built specifically for the vibe-coding workflow.
The Remote Developer Jobs API You Actually Want to Use
Why generic job APIs fail remote developers, and how HireQL provides structured, curated remote job data with real salaries, tech stacks, and company vibe signals.
Daily digest
The best vibe coding jobs, in your inbox
Curated remote dev roles at async-first, no-BS companies. No spam, unsubscribe anytime.