Evaluation
Natural Language Search in Your Talent Pool
Someone applied to another posting three months ago and nobody remembers the name. You write what you are after as a plain sentence; the sentence is split into requirements and preferences, and matching candidates are ranked with an excerpt taken from their CV. Who gets invited to an interview is still your decision.
Natural language search in a talent pool means an HR specialist writes a plain sentence such as "knows React, at least two years of experience" and gets the matching applications in the pool ranked. GoTeam turns that sentence into requirement and preference chips you can see on screen; you can drop a chip or move it from requirement to preference. Every result row carries the CV passage the match rests on. Searching never spends an evaluation credit.
- This feature depends on the "AI CV Analysis" setting in the panel; while that setting is off, the related screens stay out of the menu.
What your sentence is turned into
The sentence you type into the search bar becomes a structured intent with a single model call. Five parts are extracted from it: hard filters (candidate type, city, years of experience), must have skills, preferred skills, seniority and the free text left over.
Hard constraints become database filters and never enter semantic search. The reason is mechanical: an "intern" condition cannot be enforced through a similarity calculation, and filler words such as "I am looking for" drag the vector toward generic HR language. Whatever free text remains is used as a semantic signal.
Unknown information is never used against a candidate. Under an "at most 5 years" filter a candidate with unknown experience stays in the list, and under an "outside Istanbul" filter a candidate with unknown city stays as well. Only an explicit lower bound drops a candidate whose experience is unknown.
- A candidate with no evidence at all for a required skill is removed; partial evidence that appears only in the skill list keeps the candidate in the list and ranks them lower
- The parsing of the same query stays cached for five minutes; simultaneous requests share one call
- Search runs on submit, not on keystroke: Enter or the Search button is needed
| Part | Example | How it is applied |
|---|---|---|
| Hard filter | internship candidate, 2+ years | Goes down to a database filter |
| Required skill | knows React | Anyone without evidence is removed |
| Preferred skill | TypeScript would be a plus | Ranked higher |
| Seniority | senior developer | Enters the fit calculation |
| Free text | has built a payment system | Matched against a CV passage |
The understood intent stays on screen and can be corrected
Chips appear under the search bar under the heading "This is how we read it". Every chip is labeled requirement, preference or excluded; you can drop a chip or turn a requirement into a preference. To narrow the results there is an "Only those meeting the requirements" switch.
Editing a chip never sends the query back to the model. The edited intent goes straight to the server with no second model call, so your correction stays your decision.
Parsing never throws under any condition. If the model call or the response breaks, a fallback path takes over and the result is marked as such. On the fallback path the "this is how we read it" line is identical to the text you typed: without model confidence, no interpretation is invented.
- The fallback path extracts no skills: it catches only the internship or job type and the year range, and the rest of the text becomes a semantic signal
- On an account whose evaluation balance is spent, parsing never reaches the model and drops straight to the fallback path
- How many candidates each requirement eliminated is counted and feeds the "Loosen the requirements" hint
The excerpt next to every row
A result row brings the CV passage matching your query alongside it: the semantic evidence with the highest similarity. When there is no free text query this excerpt is not shown at all, because in that case there is nothing to match.
The excerpt is found over a copy of the CV text that has been split into chunks and made searchable. For the many candidates of one posting, the query is computed once; requests arriving at the same time share that single computation.
Ranking produces a complete order. A candidate without a score is not treated as a zero, they fall to the end of the fit order and stay in the list; ties fall back to semantic relevance first and date second. Otherwise short queries would return the rows in a different order on every refresh.
- The overall CV score decides no ranking; it is not a posting level signal
- The fit calculation that follows a query runs deterministically
- On a set that has never been scored, the calculation moves six candidates at a time; hundreds of simultaneous model calls never happen
- The filter panel carries skill, role, language, experience level, city, university, department, class year and internship type options
Two scopes: with a posting and without one
The module opens with the posting list. Next to every posting you see the application count, the analysis count, the best candidate and the average. You can also come in without picking a posting: the Whole Pool, All Job Candidates and All Internship Candidates cards open the pool directly.
When you search without picking a posting, the meaning of the score changes. That score is calculated against a temporary position derived from your query; it is not a persistent posting fit and the id of the temporary position is never written to the result. Once you pick a posting, the default is that posting applicants, and the whole pool can be ranked against it on request.
By default the pool holds candidates still moving through a process. Applications that were hired, rejected, ended or terminated are not listed unless you ask for them explicitly.
The cost distinction gets muddled in a single sentence, so here it is as a table: parsing a natural language query counts among the free paths, but picking a posting without a query and scoring the whole pool against it is a different path.
| What you did | What the score is based on | Does it spend a credit |
|---|---|---|
| Searching without picking a posting | A temporary position | No |
| Applicants of a posting | The posting criteria | No |
| Scoring the pool against a posting | The posting criteria | One credit for every unscored candidate and posting pair |
| Rescoring the same pair | The same criteria | No |
Candidates who miss a hard criterion stay in their own group
A gate takes four values: passed, closed, unknown and manually overridden. "Unknown" never lands in the same bucket as "closed"; missing evidence is not counted as a shortcoming of the candidate. An older record whose gate was never calculated is not quietly counted as "passed" either, it enters no gate filter at all.
A candidate with a closed gate is never removed from the list. They sit in a separate group headed "Does not meet the hard criteria", with the badge and the score still visible. The note on the group says: "These candidates were not rejected; they are set apart because a gate is closed. The decision is yours."
Opening a gate by hand requires a written justification of at least 10 characters. The justification is stored with the name of the person overriding it, on the fit record and in the audit log. The human review queue gathers under a single filter: an undecided item, a gate left unknown and an injection flag share the same queue, because the work to be done is identical in all three.
Permissions, masking and bulk actions
Viewing and searching require the ai_advisor:view permission; bulk status changes and gate overrides require ai_advisor:manage. Sending a candidate notification email inside a bulk action requires email:send on top, so a user can change statuses without being able to send email.
For a user without the pii:view permission, results come back masked: the name drops to an initial, email and phone to asterisks, the CV passage matching the query disappears completely and injection excerpts are removed. The flag showing that a candidate is in human review stays, because the work to be done is the same for that user too.
AI never changes a status on its own. A bulk status change goes through the regular application status transition service, and the note on the bar says exactly that: "AI only makes suggestions; status changes are applied with human approval."
Every search leaves a trail: the user, the pool, the target position, whether a query was used, the filter keys and the result count are recorded. The query itself never reaches the audit log, only the filter keys do.
- A single request processes at most 200 candidates, and a selection carries at most 200 records
- Email delivery never rolls back a status change: even when the email fails, the status stays changed
- The calibration report returns numbers only; band distribution per posting, closed and unknown gate counts, human review and override counts. It carries no candidate name and no row level score
Frequently asked questions
A plain sentence describing the person you are after is enough, for example "knows React, at least two years of experience, has worked on payment systems". Hard filters, must have skills, preferred skills, seniority and free text are extracted from it separately. You then have to press Enter or click Search; the search is never triggered by keystrokes.
Yes. The understood intent is listed as chips under the search bar, and every chip is labeled requirement, preference or excluded. You can drop a chip or move it from requirement to preference; the edited intent is applied directly, and the model is never asked a second time.
No. Parsing a query counts among the free paths. One separate path does spend a credit: picking a posting and scoring pool candidates who have never been scored against it. A candidate fit against the posting they applied to, and rescoring the same pair, are both free.
From the chunked and embedded copy of the CV text: the passage with the highest similarity to your query is lifted onto the row. If you wrote no free text query, no excerpt appears, because there is nothing to match. For a user who sees candidate data masked, that passage disappears entirely as well.
On a temporary position derived from your query. That is not a persistent posting fit, and the id of the temporary position is not written to the result. If you want a persistent fit score, pick the posting first; the score is then calculated against the criteria of that posting.
Yes, if you have the ai_advisor:manage permission. The change goes through the regular application status transition service and a single request processes at most 200 candidates. Sending a candidate notification email requires email:send on top; even if the email fails, the status change stands.
Related features
Related guides
See this feature on your own data
Leave a demo request, we set it up together and walk through the process on one of your own positions.
Contact Us






