AI-Powered Auto-Fill for Job Search Filters Using a Data-Driven Database
Job seekers often struggle with filters on sites like HeadHunter, SuperJob, Zarplata.ru, and TrudVsem. Analytics reveal that users open the filter panel, enter data haphazardly, get irrelevant results—from thousands of janitor jobs to empty lists—and bounce. Fixes like disclaimers, required fields, and highlights flopped: conversion dropped as users got intimidated or typed nonsense like "job".
Key insight: it's the complexity. Each platform uses unique IDs for cities (HeadHunter has 1,600 with IDs, SuperJob its own), specializations, experience levels. Dumping full dictionaries into an LLM means 140,000 tokens per query (25–40 RUB), hallucinations, or bankruptcy.
Data-Driven AI Pipeline Architecture
The solution leverages an existing database with tables job_filters, job_filter_options, job_service_filters, city_master, and city_source_map. These map canonical values to platform-specific IDs (e.g., Moscow: HeadHunter=1, SuperJob=4).
The system auto-categorizes filters flagged is_ai_eligible = true:
- Small dictionaries (≤30 options): experience (
noExperience,between1And3), employment (FULL,PART). Sent to the prompt (~400 tokens). - Large dictionaries (>30): cities, roles. LLM outputs text ("Moscow"), code resolves IDs from DB.
- Free text: queries like "Python backend developer".
- Numbers: salary from resume or LLM.
Prompts are dynamically generated from the DB. Example:
== MULTIPLE-CHOICE FILTERS ==
experience: noExperience="No experience", between1And3="1-3 years"
employment_form: FULL="Full-time"
== DICTIONARY FIELDS ==
city_name: "Moscow"
== TEXT FIELDS ==
text: 2-8 words
Input: resume summary (skills, experience), desired role, target sites. Output—JSON without IDs:
{
"text": "Python backend developer",
"area_name": "Moscow",
"experience": "between1And3",
"salary": {"from": 250000}
}
Processing Phases and Resolution
Phase 1: Prompt Generation and LLM Call
BuildSearchFiltersPromptTask assembles the instruction. LLM (GigaChat) parses user intent, picks from small dictionaries, names large ones.
Phase 2: Code Post-Processing
- Resolution:
SearchCitiesActionlooks up "Moscow" incity_master, maps to IDs viacity_source_map. - Adaptation: converts
between1And3to platform API format. - Assembly:
unified_filters+filter_labelsfor frontend.
Result: pre-filled filters for all sites. Users review and save.
Scalability: new site/filter—just add DB data; prompt and pipeline adapt automatically.
Performance Metrics
| Approach | Tokens | Cost per Query | Accuracy |
|----------|--------|----------------|----------|
| Naive (full dictionaries) | 140,000 | 25–40 RUB | Low (hallucinations) |
| Data-driven | 850 + 150 | 0.1 RUB | High (DB resolution) |
Savings: 150x. Search bounce rate dropped, average revenue per user from paid features rose.
Key Takeaways
- Role separation: LLM handles semantics, DB does ID mapping—cuts tokens and errors.
- Auto-classification: 30-option threshold is dynamic; new filters integrate code-free.
- JSON output: Strict LLM format simplifies parsing.
- Scale: Handles thousands of users without cost spikes.
- UX: Auto-fill lowers entry barriers.
— Editorial Team
No comments yet.