# When Zorlya uses a language model, and when it does not

> Zorlya calls a language model to write for you and to judge fit, and uses plain code for arithmetic, matching and lookups. A project to replace more model calls with rules is built but still running in shadow mode, which means nothing has been switched over yet.

Source: https://zorlya.com/blog/when-zorlya-uses-a-language-model

By Zorlya. Published 2026-10-06, updated 2026-10-25. Research and data. 4 min read.

A language model is the right tool for some jobs and a poor one for others. It writes a paragraph about you well. It is a slow, costly and unreliable way to subtract one list from another. Zorlya's rule is that a system it owns answers first, and a model answers only what that system cannot. This post lists where that already holds, where it is still a plan, and what the plan has and has not shown.

## What runs without a model

Several things that look like AI features are ordinary code:

- **The skills comparison.** Skills on the posting minus skills on your profile, after both are normalised, is set arithmetic. A full match scores 100 and no model is asked. When you refresh, a score that is not a full match also weighs the rerank's reading of your skills at 30%.
- **The ATS check.** It compares the posting's skills with yours and never calls a model.
- **Salary fit, location fit and seniority fit.** Each is a formula over stored fields.
- **The first matching pass.** After new jobs arrive, Zorlya scores them from stored embeddings, with skills as set arithmetic and salary and location from stored columns. No chat model is involved. The deeper pass, with a model rerank and written explanations, runs only when you press refresh.
- **Deduplication, date reading, location parsing.** All code.

Embeddings are produced by an embedding model, which is not a chat model, and they are cached so the same text is never embedded twice.

## What does use a model

Fifteen named tasks are sent to a model, each with a fixed size of answer and, for a few, a cache. The ones that matter to you:

- **Judging fit.** Rerank reads a shortlist against your profile, and the explanation under a score is written by a model. Rerank answers are cached for an hour and explanations for a day.
- **Reading a resume.** Parsing an uploaded file into fields.
- **Reading postings.** Extracting skills, a summary, level and similar fields from the ad text, with the result cached for 30 days.
- **Writing.** Cover letters, outreach drafts, interview preparation, the resume builder and resume tailoring. These write for one person about one job, so there is nothing a template could replace.

By default the models run on Cloudflare Workers AI, a small one for the structured tasks and the rerank, and a larger one for writing and for the explanation under a score. If a model is unavailable, a task falls to the next provider only when the previous one failed, never because it gave a poor answer.

## The less-AI project

The owner decided to reduce model use wherever a system Zorlya owns can do the work as well or well enough. Three reasons are written down: a model outage then matters for fewer reads, an owned answer cannot invent a fact, and calls that are not made have no delay and no rate limit.

The plan says openly that money is not the main reason. At the prices recorded on 6 October 2026, all model use costs about $0.030/month per active seeker, and the daily score refresh is 70% of that. The saving at current size is small. The project exists for reliability and for answers that can be checked.

## Shadow mode

Each replacement ships in one of three modes: `rules`, `shadow` or `model`. In shadow mode both paths run. The model's answer is the one used, and the owned answer is recorded next to it without being used, so the two can be compared on real traffic before anything changes.

Three slices are built:

| Slice | What the rules do | Mode today |
|---|---|---|
| Reading postings | Rules fill summary, salary, employment type, level and remote flag first, and the model is asked only for what is left | shadow |
| Skill gap | The list of gaps is computed and free, and the model writes only a learning plan for the top 3 gaps | shadow |
| Company brief and salary band | Built from Zorlya's own stored postings and companies, with a labelled "Research with AI" button when the data is thin | shadow |

"Shadow" is the default for all three, and nothing in the repository switches them. So the model still answers in each case. The rules are running alongside, being measured.

## How the rules are held to a standard

The plan sets a pass bar for each field before it can leave shadow. For salary, no wrong figure may be stored on a labelled sample, and the rule must find at least 60% of postings that state one. For employment type, accuracy of at least 95% where the posting states it. A field that fails stays on a model for that field only. When a rule is unsure it stores nothing, because a missing value is safer than a wrong one.

One trade is stated plainly. The summary on a card becomes the posting's own opening sentences, up to 300 characters, in place of a model summary. That reads less smoothly. It also cannot add anything the ad did not say.

## What has not been measured

The bars are not met, because the labelled sample is not collected. The plan calls for 200 postings drawn from production and adjudicated by the owner, and the development database cannot stand in, since 200 of its 210 postings are seeded fixtures. The share of calls that rules would take (the plan guesses 70% to 85% for posting extraction) is a hypothesis. The usage ledger does not yet record answers that rules gave in place of a model, so no figure for avoided calls exists.

The honest summary is short. Arithmetic and lookups run without a model today. Writing and judging use one. The replacements for the middle ground are built, switched off, and waiting for evidence.
