← All insights

TalentCraft Engineering

Building TalentCraft’s Internal Recruiting Copilot

TL;DR

We built a recruiting copilot on Snowflake Cortex AI to help our team find candidates within TalentCraft’s existing network.

It combines search over resumes and recruiter notes with structured queries, returning supporting evidence that recruiters can review and refine through follow-up questions.

Intro

For a recruiting company like TalentCraft, one important metric is redeployment rate: placing candidates who have previously worked with us in any capacity. Redeployment reduces the time recruiters spend sourcing new candidates and also builds on existing relationships. We already know these candidates and, in many cases, have direct feedback from employers about the quality of their work. TalentCraft has accumulated tens of thousands of candidate records, recruiter notes, resumes, and client feedback spanning 8+ years. These records contain knowledge that can help our recruiters place candidates for new requirements.

Finding the relevant evidence across that history, however, takes time. This led to our central question: How can we help recruiters find candidates for redeployment using the business context and evidence we have already collected?

Our solution was to build a recruiting copilot that lets our team search TalentCraft’s internal candidate data in natural language, examine the evidence behind results, and refine a search through follow-up questions.

System Requirements

When scoping the project, we identified five functional requirements.

The system needed to:

  1. Provide a chat-based interface.
  2. Accept a candidate search or job requisition written in natural language.
  3. Accurately search resume content, recruiter notes, and structured candidate data.
  4. Return relevant candidates with supporting evidence.
  5. Preserve conversations and support follow-up questions.

The non-functional requirements shaped how we delivered those capabilities. The system needed to protect candidate data, restrict access to authorized users, accommodate growing usage, respond quickly enough for interactive searches, maintain reliable history, and operate within a predictable budget.

We chose Snowflake Cortex AI for managed search and Cortex Agents for orchestration. Cloudflare provides the web application, API compute, access control, and application state. This division places retrieval and agent orchestration alongside the recruiting data in Snowflake, while the application backend manages recruiter access and the search experience.

Running our own vector index and agent loop would have given us finer control over ranking and latency, but it would also mean operating embedding pipelines, an index, and an orchestration service for a small team.

Architecture and Design

We have an upstream ELT pipeline that brings our CRM and ATS data into Apache Iceberg tables stored on Amazon S3. That data is then made available in Snowflake, where it supports structured queries and search over parsed resumes and recruiter notes.

Within Snowflake, we configured a recruiting semantic view to give Cortex Analyst business context. A semantic view describes how business concepts map to the underlying data, including field meanings and relationships between records. This gives the system a foundation for translating recruiting questions into SQL. Snowflake’s semantic-view documentation describes this role in query generation.

Cortex Agent Setup

The Cortex Agent has two complementary capabilities:

  1. Cortex Search retrieves evidence from text. Our agent exposes separate tools for parsed resumes and recruiter notes. Cortex Search combines vector similarity, keyword matching, and semantic reranking. This supports searches where relevant experience may be described using different terminology, while retaining the value of exact skill and technology names.

  2. Cortex Analyst generates SQL for structured questions. It uses the recruiting semantic view to interpret a request and produce SQL, which is then executed in Snowflake. This supports questions involving recorded fields, relationships, filters, and aggregations.

A single request may need both capabilities.

Consider an illustrative search:

Find candidates in Chicago with 6+ years of k8s experience who are available next month.

A recruiter requests candidates in Chicago with 6+ years of k8s experience who are available next month. Cloudflare interprets k8s as Kubernetes. A Snowflake Cortex Agent can use Cortex Search to retrieve Kubernetes experience and evidence for six years from resumes and notes, and Cortex Analyst to check Chicago against city and state fields and next-month availability against the recorded availability date. Candidates and supporting evidence return to the recruiter for review.
Figure 1. Illustrative tool use for this request: resume evidence for Kubernetes experience and its duration; structured fields for location and availability. The agent can make repeated tool calls as needed.

The application first interprets k8s as Kubernetes. Cortex Search retrieves resume evidence of that experience, with recruiter notes available for supporting context. The six-year requirement must be assessed from dated experience; a mention of Kubernetes alone does not establish the duration. Cortex Analyst generates structured queries to check Chicago against candidate city and state fields and “available next month” against the recorded availability date. The agent can use those results together when preparing its response. Cortex Agents supports this process of planning, calling tools, evaluating results, and making further calls when needed.

Interpreting Recruiter Shorthand

Before a request reaches the agent, custom TypeScript code in our Cloudflare backend checks it against a curated vocabulary of recruiting terms, technology aliases, and common misspellings. Additional parsing rules identify criteria such as location, candidate status, availability, and required versus preferred qualifications. For example, a recruiter might type: Find k8s developers in Chicago. The application recognizes k8s as Kubernetes and identifies Chicago as a location. It preserves the original request and appends labeled guidance indicating that Kubernetes is the intended skill and location should be evaluated using structured city and state fields.

This gives us an inexpensive, testable way to handle recurring shorthand. The trade-off is that the vocabulary requires maintenance, and parsing rules cannot resolve every ambiguous request. These hints guide the agent’s interpretation; the agent still has to retrieve and evaluate the underlying evidence.

Request Path

Every API request passes through Cloudflare Access for identity verification, then through a function that enforces usage limits before calling Snowflake with credentials held only on the server. Responses stream back to the browser as they are generated. The application adapts Snowflake’s events into the AI SDK’s UI-message streaming protocol, so the interface can display progress and answer text incrementally.

Thread Persistence

An individual recruiter’s conversation continuity has two parts: Snowflake threads maintain the agent’s context, while Cloudflare D1 stores application history and thread ownership. The browser receives an opaque thread token, which the application resolves only for its owner. The application commits a successful exchange to D1 before sending the final completion signal to the browser. If persistence fails, it reports the problem and subsequent requests start a fresh conversation. This prevents the interface from presenting an exchange as successfully saved when its history is uncertain.

To control usage, the application checks per-user and global request limits, along with concurrency limits, before admitting an agent request. These controls bound application demand; overall operating cost also depends on Snowflake compute, search indexing, and model usage.

Protecting Candidate Information and Supporting Responsible Use

Candidate records contain personally identifiable information (PII), so protecting that information is part of the application design. Access is restricted to authorized users, and saved conversations are scoped to their owners.

During ELT, we strip or tokenize sensitive fields. Operational logs record request metadata, tool-call information, latency, and errors while excluding candidate content and conversation text. Separately, access logs support investigations into user searches and record access. Historical recruiting data can contain subjective judgments, outdated information, and uneven documentation. Those limitations can affect which candidates a search surfaces and how their experience is represented. The copilot retrieves and orders candidates for recruiter review; it does not make hiring or rejection decisions.

Recruiters remain responsible for verifying supporting evidence against job-related requirements. We also constrain what can be asked. The preprocessing function that expands recruiter shorthand rejects queries that filter on protected characteristics or well-understood proxies for them.

What We’re Working On

The copilot is still early in development, but we’re already seeing an improvement in our redeployment rate and finding relevant candidates from past recruiting efforts.

We’re now working to reduce search latency by building a capability that moves more of the language-model work into our data pipeline. The approach is inspired by LinkedIn’s Hierarchical Long-Term Semantic Memory paper, which describes extracting and organizing information before a request arrives, then retrieving that prepared information during a conversation.

For us, this means building a candidate evidence table in Snowflake. As resumes and notes enter the system, we’ll extract skills and experience, keeping each item linked to its supporting text and dates. When a candidate’s record changes, we’ll reprocess that candidate’s information. We’re also extending the shorthand parser to turn common search criteria into predefined SQL queries. For a request like “Find Kubernetes developers in Chicago,” the application could query the prepared evidence and location fields directly.

The agent would then review the evidence and explain the results, with Cortex Search and Cortex Analyst available for questions that need further investigation. This should reduce repeated interpretation and SQL generation while recruiters wait. We’ll compare the new version against the current workflow using the same recruiter searches, measuring response time, cost, and whether qualified candidates are being missed.