RFRoleFit

Settings

What RoleFit is currently wired to. Everything here is read from environment variables, so change .env.local and restart the dev server to see it update.

Services

Database

Hosted Postgres via the neon-http driver

OpenRouter

Parsing, OCR, match explanations and embeddings are all live.

Vercel Bloboptional

Not set. CVs are still parsed, but the original file is not kept.

Language model tasks

Five distinct jobs, each with its own environment variable. Point them at five different models or the same one five times. Slugs on OpenRouter rotate often, so check openrouter.ai/models and filter by Free if you want zero cost.

  • CV parsing

    Once per CV.

    Text modelUsing default

    Reads raw CV text and returns structured JSON: name, contact details, skills, work history, education, and estimated years of experience.

    What to pick: Reliable JSON output and a long context window. This is the model that most affects data quality, so it is the one worth paying for if you only pay for one.

    OPENROUTER_MODEL_PARSE=google/gemini-2.5-flash-lite,openai/gpt-4o-mini

    Primary google/gemini-2.5-flash-lite, falling back to openai/gpt-4o-mini if it is unavailable or over quota.

    OPENROUTER_MODEL_PARSE_TEMPERATURE=0 OPENROUTER_MODEL_PARSE_MAX_TOKENS=4000
  • OCR / scanned documents

    Only for scanned or image CVs.

    Vision model requiredUsing default

    Transcribes scanned PDFs and photos of printed CVs that carry no text layer. Only runs when normal text extraction comes back nearly empty.

    What to pick: Must accept image input. A text-only model here will fail on every scan.

    OPENROUTER_MODEL_OCR=google/gemini-2.5-flash-lite,openai/gpt-4o-mini

    Primary google/gemini-2.5-flash-lite, falling back to openai/gpt-4o-mini if it is unavailable or over quota.

    OPENROUTER_MODEL_OCR_TEMPERATURE=0 OPENROUTER_MODEL_OCR_MAX_TOKENS=8000
  • Match explanation

    Once per candidate, per role scored.

    Text modelUsing default

    Writes the recruiter-facing narrative for one candidate against one role: strengths, gaps, and a hiring verdict. It never produces the numeric scores, which are computed in code.

    What to pick: Decent reasoning over a short prompt. Output is small, so a cheap model is fine here.

    OPENROUTER_MODEL_MATCH=google/gemini-2.5-flash-lite,openai/gpt-4o-mini

    Primary google/gemini-2.5-flash-lite, falling back to openai/gpt-4o-mini if it is unavailable or over quota.

    OPENROUTER_MODEL_MATCH_TEMPERATURE=0.3 OPENROUTER_MODEL_MATCH_MAX_TOKENS=900
  • Candidate summary

    Once per CV, only when SUMMARY_SEPARATE_PASS is enabled.

    Text modelDisabled

    Writes a short neutral profile of the candidate for the recruiter. Off by default, because the parsing pass already returns a usable summary. Turn it on with SUMMARY_SEPARATE_PASS=true to get a better one from a dedicated call.

    What to pick: Good prose in a few sentences. The cheapest model you have is fine.

    OPENROUTER_MODEL_SUMMARY=google/gemini-2.5-flash-lite,openai/gpt-4o-mini

    Primary google/gemini-2.5-flash-lite, falling back to openai/gpt-4o-mini if it is unavailable or over quota.

    OPENROUTER_MODEL_SUMMARY_TEMPERATURE=0.3 OPENROUTER_MODEL_SUMMARY_MAX_TOKENS=400
  • Embeddings

    Once per CV and once per job role.

    Embedding model requiredSet by you

    Converts CVs and job descriptions into vectors so semantic fit can be measured beyond exact keyword overlap.

    What to pick: Must be an embedding model, not a chat model. Free options are rare here. If this is unset or failing, the semantic dimension is dropped and its weight is redistributed across skills, experience and education.

    OPENROUTER_MODEL_EMBED=openai/text-embedding-3-smallEMBED_DIMENSIONS=1536

What is never sent to a model

The match scores. Skills, experience, education and semantic similarity are all computed in code from your role definitions, so the same CV against the same role always produces the same number. The models only read documents and write prose.