Summary
pSpark is Psiog’s annual technology festival & conference. This year, it took shape of a hackathon where teams build solutions to real business use cases leveraging AI. Our team of five (Team Apex) participated in pSpark and took back a lot of learnings & memories. Niyojana is what we built – an AI engine for Talent acquisition. It reads resumes, scores each candidate against a job with the evidence behind every point, and lets recruiters search the entire resume bank in plain language. The working rule is that the LLM reads and explains, code computes every score, and a person decides. Connectors bring in resumes from Gmail, Naukri and LinkedIn, and the architecture uses Azure SQL database, VS Code with MCP, a layer of views and live Power BI dashboards.
1. Problem statement
Recruitment teams across industries face increasing challenges in managing high volume of job applications, making resume screening a time consuming, manual, and often inconsistent process. Recruiters frequently review hundreds of resumes for a single role within limited timeframes, resulting in varying evaluation standards, overlooked qualified candidates, and underutilization of previously submitted resumes that may be suitable for future opportunities. The growing administrative burden reduces the time available for meaningful candidate engagement and other hiring activities, while the lack of a structured approach to candidate assessment can impact hiring quality and fairness. As a result, organizations experience longer hiring cycles, higher recruitment costs, reduced recruiter productivity, missed talent opportunities, and difficulties in meeting workforce demands, ultimately affecting business growth and operational performance.
1.1 Requirement Elicitation
We captured requirements from three personas, the recruiter, the HR leader and the HR administrator. The table pairs each challenge they face today with the requirement it led to, and every feature we built answers one of these rows.
Persona | Challenge today | Requirement |
Recruiter | Hours of reading, a few seconds per resume | I want details extracted, duplicates flagged and every recommendation explained, so I can trust it. |
Recruiter | Rejected resumes are rarely seen again | I want to search the whole bank in plain language, so good talent is not lost. |
HR Leader | Personal attributes can sway a skim, and it is hard to see where hiring slows | I want fair evaluations and funnels, recruiter and source dashboards. |
HR Administrator | Scoring changes wait on engineers | I want to change weights, taxonomy and thresholds myself, with an audit trail. |
2 The End to End Solution Data, AI & Application
Niyojana is an AI-powered recruitment intelligence platform designed to streamline and standardize the candidate screening process. The solution automatically analyzes resumes against job requirements, extracts relevant skills, qualifications, and experience, and provides transparent candidate assessments with clear justification for each recommendation.
It also maintains a centralized, searchable talent repository, enabling recruiters to rediscover previously reviewed candidates who may be suitable for future opportunities. By reducing the time spent on manual resume screening and ensuring a consistent evaluation approach across all applications, Niyojana empowers recruiters to focus on higher-value activities such as candidate engagement, interviews, and hiring decisions, while keeping the final selection and judgment entirely under human control.
Niyojana is one connected system – as a resume travels through it, from the inbox to the HR dashboard. An LLM reads a resume well but is unreliable as a calculator, since a candidate ranked 82 on one run may be ranked 71 on the next, so the LLM only judges each criterion and cites evidence, while deterministic code does the arithmetic with the recruiter’s weights. Every score is then reproducible and traceable.
Principle – the LLM reads and explains, the code computes, and a person decides.
2.1 Where AI is used, and the flow at a glance
AI is used in exactly four places, all of them where the input is unstructured language, and it stays out of anything a number or a decision depends on.
Where AI is used | What it does - the code still computes every number |
Resume parsing (LLM) | Reads a free-text PDF or DOCX into a structured profile. |
Scoring evidence (LLM) | Judges each requirement against the resume and cites the evidence, and the code computes the score. |
Semantic search (LLM + embeddings) | Turns a plain-language query into intent, then embeddings match on meaning and the results are fused with keyword search. |
Skill equivalence (LLM) | Recognizes differently worded skills as the same, for cases the alias map misses. |
Two guardrails hold throughout – personal details never reach the LLM, and the provider is swappable (Claude, Groq or Ollama) with one setting. Figure 1 shows the whole workflow. Gold boxes are LLM calls, teal boxes are the embedding model, and white boxes are plain code, SQL, BI or a person.
2.2 Sourcing resumes through connectors
Resumes already live in a recruiter’s Gmail, Naukri and LinkedIn, so the ingestion service has one adapter per source, plus bulk upload, all feeding one pipeline (Figure 2). Every candidate keeps a source tag, which lets us ask which channel produces candidates who get interviewed and hired. A new portal is one more adapter.
2.3 Understanding a resume
The stored file now has to be data. PyPDF2 extracts the text with no model involved, and the LLM turns it into a structured JSON profile covering skills, experience, roles, education, certifications, location and a summary. Parse status and confidence are recorded, and a keyword parser covers any LLM outage. A skill normalizer then maps variants to one canonical skill through an alias map and the taxonomy, with the LLM resolving the subtler equivalences, and duplicates are flagged for a recruiter to confirm. Lastly, the embedding model turns the profile into a 768-dimension vector for the in-memory index.
2.4 Scoring a candidate
With a profile stored, a candidate is scored against a requisition (Figure 3), whose criteria are weighted and some marked ‘must have’. The LLM receives the stripped profile and the criteria (prompt cached, since the instructions repeat) and returns a sub-score, evidence and gaps for each one. Code then computes the weighted 0-100 score, caps it if a must-have is missing, and applies thresholds to give a Shortlist, Consider or Reject recommendation with a confidence level. The recruiter sees the evidence and decides, and personal attributes are revealed only after shortlisting.
2.5 Ranking and searching the bank
The same stored profiles serve two more tasks. To score a whole requisition without sending the entire bank to the LLM, a model-free skill-match pre-rank retrieves a capped top K shortlist and only those candidates are scored (Figure 4), so LLM calls stay bounded as the bank grows.
Free-text search works from the other side (Figure 5). The LLM reads a query such as “senior backend engineers in Chennai who know Kafka” into filters and a clean query, then two searches run in parallel – a SQL keyword search over skills, role, summary and location, and a semantic search that embeds the query and ranks profiles by cosine similarity, so resumes describing the same work in different words still rank. Reciprocal rank fusion merges the two lists, so anyone strong on either signal rises to the top, including a resume filed under last quarter’s rejected role.
2.6 From database to dashboard
Everything the application produces, profiles, scores and the stage each candidate reaches, is written to one Azure SQL database, so reporting never needed a second system.
Getting from that database to dashboards took a short chain of integrations (Figure 6).
- Azure SQL as the single source. The application data lives in one database, so there is nothing to copy or keep in sync.
- VS Code + MCP. MCP provides a standardized way for AI assistants to interact with external tools and data sources, such as databases. We connected our database to VS Code through MCP-based SQL tools, with an LLM-powered coding assistant acting as the client. As a result, reports could be designed and validated against the actual data, with queries tested before deployment, all through natural-language prompts, which sped up development of the workflow.
- Views as the reporting foundation. From the same session, we wrote the reporting logic as views in a separate schema, with no personal data included. They are plain SQL scripts that can be re-run safely.
- Power BI over Direct Query. Direct Query means Power BI reads the live database instead of a copy. It connects to the same database and reads only the views, so a new stage or score shows up on the next refresh, with nothing imported or scheduled.
2.7 Architecture and security
Seen from above, the same flow is a small set of parts (Figure 7). A React client talks to a Fast API backend over JWT-authenticated APIs. The backend has four components, API routers and auth, resume parsing, the scoring engine and semantic search, which calls the pluggable AI engine (the LLM and an embedding model) with personal data stripped from every prompt, and read and write Azure SQL and Blob Storage. Power BI reads the reporting views beside them. Passwords are hashed, personal data is encrypted at rest, and containers run as non-root.
3. Build Journey
We built in four phases and tested each one before starting the next. That order paid off early, because the scoring problem we found in Phase 2 would have been much harder to fix once search and dashboards sat on top of it.
Phase 1 – agree on the problem. Our business analyst turned the use case into BRD, FRD, user stories and wireframes so all five of us built against the same picture.
Phase 2 – prove the core idea. Our full-stack and AI integration engineer first built the thinnest path, uploading a resume, parsing it and scoring it. The first surprise came quickly, when the same candidate scored 84 on one run and 71 on the next. Moving the arithmetic into code, with the LLM supplying only sub-scores and evidence, fixed it, and a test now asserts that the same candidate scores the same every time.
Phase 3 – make the bank searchable and fed. Next came embeddings, hybrid search and the connectors. Skills were the quiet problem, since React.js, ReactJS and React are one skill and K8s is Kubernetes, so we built the normalizer on an alias map and a taxonomy, with the LLM covering the subtler cases.
Phase 4 – connect the data to the dashboards. The data engineers on the team took this on. Connecting Azure SQL to VS Code through MCP let an LLM coding assistant explore the live data and help us write and test the views, and Power BI then read them live. The chain stayed short, with one database, one MCP session, one layer of views and one Direct Query connection.
Much of the code was first drafted with AI tools while the scoring rules, matching strategy and fairness boundaries were completely human driven.
4. Impact and Outcome
Area | Before | With Niyojana |
Hiring lead time | 5-6 weeks | 3-4 weeks |
Initial screening | Hours per 100 resumes | A ranked shortlist with evidence in minutes |
Consistency | Varies by person to person | The same candidate gets the same score every time |
Rediscovery | A rejected resume is rarely seen again | The whole bank is searchable in plain language |
Fairness | Personal details visible during a skim | Removed before scoring, revealed only after shortlisting |
For a recruiter that means a shortlist with evidence and one search box over the whole bank, and for a hiring manager a clear view of why one candidate outranks another. The larger value is not the minutes saved on one requisition but removing the same repetitive reading across every requisition a team opens.
5. Authors Note
Building Niyojana at pSpark gave the five of us a chance to go beyond using AI as a clever assistant and design it into a real workflow. We argued about where the LLM should stop, learned why a score has to be reproducible before it can be trusted, and found that a short, well-chosen data chain mattered as much as the prompts. The interesting part of applied AI is rarely the model. The real work was building something you would trust next to a hiring decision, with a firm line between what the engine may recommend and what only a person may decide. It helps people hire, and a person always makes the call.