--- title: TalentPulse AI Candidate Matching emoji: ⚡ colorFrom: purple colorTo: indigo sdk: docker pinned: false app_port: 7860 --- # TalentPulse: AI-Powered Candidate Matching System ## Overview TalentPulse is a production-grade, full-stack AI system for matching job descriptions against large candidate pools. It replaces manual resume screening with semantic retrieval, neural reranking, structured gap analysis, and LLM-generated explanations. The platform is built for recruiters and hiring teams who need fast, explainable, and configurable candidate matching. It supports session-based candidate batches, dynamic scoring weights, trajectory analysis, and reusable matching workflows for A/B testing and precision hiring. ## Key Features ### Session-based Candidate Management Group candidates into named sessions for isolated workflows and repeatable matching experiments. ### Two-stage AI Matching Pipeline - **Stage 1: Retrieval** — Fast vector search in Qdrant with structured scoring for skills, experience, and other signals. - **Stage 2: Reranking** — Cross-encoder reranking of the shortlist, fused with Reciprocal Rank Fusion. ### Live Weight Sliders Adjust matching priorities in real time and rerank results in memory without running new model inference. ### Structured Gap Analysis Detect missing skills, experience gaps, and mismatches to generate grounded candidate explanations. ### LLM-generated Explanations Use Groq-powered LLM responses based on the precomputed gap analysis. ### Trajectory Scoring Estimate career growth velocity from work history and reward strong advancement patterns. ### JD Quality Feedback Evaluate job descriptions for clarity, breadth, and missing signals. ## Tech Stack | Layer | Technology | |------|------------| | Frontend | Next.js 16, React, Tailwind CSS v4 | | Backend | FastAPI, Uvicorn | | Database | Neon Postgres, Asyncpg, SQLAlchemy, Alembic | | Vector Search | Qdrant Cloud | | Async Jobs | Celery | | Cache | Redis Cloud | | Embeddings | BAAI/bge-small-en-v1.5 via SentenceTransformers | | Reranking | BAAI/bge-reranker-v2-m3 via FlagEmbedding | | LLM Provider | Groq (llama-3.3-70b-versatile) | | Deployment | Docker, Nginx, Supervisord, HuggingFace Spaces | ## Architecture Overview ```mermaid graph TD UI[Next.js Frontend] -->|REST API| Proxy[Nginx Reverse Proxy] Proxy --> API[FastAPI Backend] API -->|Async Tasks| Queue[Redis / Celery Queue] Queue --> Worker[Celery Workers] API -->|Read / Write| DB[(Neon Postgres)] Worker -->|Persist Metadata| DB API -->|Vector Search| VectorDB[(Qdrant Cloud)] Worker -->|Store Embeddings| VectorDB API -->|In-Memory Rerank| LocalAI[Local Reranker Model] API -->|LLM Explanations| LLM[Groq API] Worker -->|LLM Jobs| LLM ```` ## Project Structure ```text / ├── backend/ │ ├── alembic/ │ ├── src/ │ │ ├── matching/ │ │ ├── ml/ │ │ ├── models/ │ │ ├── routers/ │ │ ├── schemas/ │ │ └── workers/ │ ├── main.py │ └── requirements.txt ├── frontend/ │ ├── public/ │ ├── src/ │ │ ├── app/ │ │ └── lib/ │ ├── next.config.ts │ └── globals.css ├── docker-compose.yml ├── Dockerfile ├── supervisord.conf └── nginx.conf ``` ## Core Modules & Responsibilities ### Backend * **backend/src/ml** Handles model loading, text embedding, and feature extraction. * **backend/src/matching** Implements retrieval, reranking, weighted scoring, and explanation logic. * **backend/src/workers** Runs background jobs such as candidate ingestion and explanation generation. * **backend/src/routers** Exposes API endpoints for sessions, JDs, candidates, matching, and health checks. ### Frontend * **frontend/src/app** Contains user-facing routes such as sessions, JD details, and pipeline orchestration. * **frontend/src/lib** Centralized API client wrappers. ## Application Flows ### Candidate Upload & Ingestion Flow ```mermaid sequenceDiagram actor User participant UI as Next.js UI participant API as FastAPI Router participant Queue as Redis / Celery Queue participant Worker as Celery Worker participant Store as Postgres + Qdrant User->>UI: Upload candidate CSV/JSON UI->>API: POST /api/candidates/upload API->>Queue: Dispatch ingest_candidates_batch API-->>UI: Return task ID UI->>API: Poll /api/candidates/status/{task_id} Worker->>Queue: Fetch task Worker->>Worker: Parse candidate data Worker->>Worker: Compute embeddings and growth velocity Worker->>Store: Save metadata and vector points Worker-->>Queue: Mark task complete API-->>UI: Return success status ``` ### Matching & Reranking Flow ```mermaid sequenceDiagram actor User participant UI as Next.js UI participant API as FastAPI Router participant Qdrant as Vector DB participant Reranker as Local Reranker participant Cache as Redis Cache User->>UI: Open JD and click Match UI->>API: POST /api/match/{jd_id} API->>Qdrant: Retrieve top candidates Qdrant-->>API: Return top-K vectors API->>Reranker: Cross-encoder reranking Reranker-->>API: Return adjusted scores API->>API: Apply rank fusion and weights API->>Cache: Store result API-->>UI: Return ranked candidates User->>UI: Adjust weight sliders UI->>API: POST /api/match/{jd_id}/rerank API->>API: Recompute ranking in memory API-->>UI: Return updated ordering ``` ### Explain & Refine Flow ```mermaid sequenceDiagram actor User participant UI as Next.js UI participant API as FastAPI Router participant DB as Postgres participant LLM as Groq API User->>UI: Open candidate match details UI->>API: POST /api/match/{jd_id}/candidates/{candidate_id}/explain API->>DB: Load match data and gap analysis API->>LLM: Generate grounded explanation LLM-->>API: Return explanation text API-->>UI: Show explanation to user ``` ## API Documentation | Method | Path | Purpose | | ------ | ---------------------------------------------------- | -------------------------- | | POST | /api/sessions | Create a candidate session | | GET | /api/sessions | List sessions | | POST | /api/jds | Create a job description | | GET | /api/jds | List job descriptions | | POST | /api/candidates/upload?session_id= | Upload candidate files | | GET | /api/candidates/status/{task_id} | Check task progress | | POST | /api/match/{jd_id}?session_id= | Run full matching pipeline | | POST | /api/match/{jd_id}/rerank | Rerank in memory | | POST | /api/match/{jd_id}/candidates/{candidate_id}/explain | Generate explanation | | GET | /health | Health check | ## Database Models * **Session** — Candidate batch container * **JobDescription** — Stores JD text and parsed requirements * **Candidate** — Stores profile, skills, work history, embeddings * **MatchResult** — Stores scores, gaps, explanations, weights ## Authentication & Security * No formal authentication yet * CORS allows all origins * Minimal admin utility route exists ## State Management * React Hooks (`useState`, `useEffect`, `useCallback`) * Local storage for persistence * Redis for backend caching ## Caching & Performance * Cached match results by `jd_id + session_id` * Models pre-downloaded into Docker image * SQLAlchemy cache tuned for Neon pooling ## Setup & Installation ### Run Locally ```bash docker-compose up --build ``` ### Database Migration ```bash cd backend alembic upgrade head ``` ## Environment Variables ```env DATABASE_URL= QDRANT_URL= QDRANT_API_KEY= REDIS_URL= GROQ_API_KEY= GROQ_MODEL= EMBEDDING_MODEL= RERANKER_MODEL= NEXT_PUBLIC_API_URL= ``` ## Deployment * Multi-stage Docker build * Runs FastAPI + Next.js + Celery + Nginx * Optimized for HuggingFace Spaces * Exposes port `7860` ## Improvement Recommendations * Add JWT auth + RBAC * Replace polling with WebSockets / SSE * Add object storage * Add automated tests * Add observability & metrics ## Quick Summary TalentPulse combines semantic search, reranking, and LLM reasoning to help recruiters identify the best candidates faster, with explainable AI-powered hiring workflows.