# What Data Is Used to Train the AI for Skill Gap Analysis in ai-job-search

> Discover how the ai-job-search AI trains for skill gap analysis using live candidate profiles, job postings, and web searches for real-time upskilling recommendations.

- Repository: [Mads Lorentzen/ai-job-search](https://github.com/MadsLorentzen/ai-job-search)
- Tags: deep-dive
- Published: 2026-07-09

---

**The skill gap analysis in the ai-job-search repository uses no pre-trained dataset; instead, it dynamically sources data from three live inputs—a candidate profile markdown file, job posting data from a CSV or fetched URL, and real-time web search results—to generate personalized upskilling recommendations at runtime.**

The ai-job-search project by MadsLorentzen implements an intelligent `/upskill` agent that identifies professional development opportunities by comparing user capabilities against market demands. Unlike traditional AI systems that rely on static training corpora, this tool assembles its knowledge base dynamically using live data sources defined in the [`.claude/skills/upskill/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/upskill/SKILL.md) specification. Understanding what data trains the AI for skill gap analysis reveals how the system delivers accurate, current recommendations without embedded training datasets.

## Three Live Data Sources Powering the Skill Gap Analysis

### Candidate Profile Baseline

The foundation of every analysis starts with [`01-candidate-profile.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/01-candidate-profile.md) located at [`.claude/skills/job-application-assistant/01-candidate-profile.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-application-assistant/01-candidate-profile.md). This markdown file contains the user's complete skill inventory, including technical competencies, certifications, education history, and professional experience. The agent reads this file during Step 3 of the upskill workflow to establish the baseline skill set against which all gaps are measured.

### Job Market Requirements

The second critical input comes from job posting data, sourced either aggregately or specifically. In aggregate mode, the system parses `job_search_tracker.csv` from the repository root, extracting required and preferred skills alongside fit ratings. In targeted mode, the agent utilizes **WebFetch** to retrieve a specific job posting URL provided as a command argument. According to the specification in [`.claude/skills/upskill/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/upskill/SKILL.md), these inputs supply the target skill requirements and contextual domain information necessary for gap identification.

### Real-Time Learning Resources

Rather than relying on static course catalogs, the AI performs live **WebSearch** queries (including the current year) to discover current learning materials. As defined in Steps 6-8 of the upskill specification, this search retrieves fresh resources from platforms like Coursera, official documentation, and relevant technical books. This ensures the generated learning plans cite accurate, year-specific resources without fabricating outdated information.

## How the Runtime Data Flow Works

The skill gap analysis operates through a five-step runtime pipeline that processes these live data sources:

1. **Load candidate profile** – The agent parses the markdown profile to construct the current skill inventory.

2. **Collect job data** – Depending on execution mode, the system either reads the tracking CSV for aggregate analysis or fetches a specific URL using WebFetch.

3. **Compute hard-skill diff** – The agent extracts skills from job postings and calculates gaps by identifying requirements not present in the candidate profile, weighted by numeric fit ratings from Step 3.

4. **LLM synthesis** – The language model expands the initial gap list by synthesizing domain context, soft-skill requirements, tooling needs, and credential gaps based on posting context from Step 4.

5. **Generate learning plan** – For each identified gap, the system executes web searches for current-year courses and materials, assembling prioritized recommendations into the final output from Step 6.

## Repository Structure and Key Files

Several specific files define this data architecture:

- [`.claude/skills/upskill/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/upskill/SKILL.md) – Contains the complete workflow specification including steps for skill extraction and learning resource generation.
- [`.claude/skills/job-application-assistant/01-candidate-profile.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-application-assistant/01-candidate-profile.md) – Stores the candidate's baseline skills and background information.
- `job_search_tracker.csv` – CSV file tracking scraped job postings used during aggregate analysis mode.
- [`tools/lint_skills.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/lint_skills.py) – Validation utility ensuring skill markdown files maintain correct metadata structure.

## Practical Usage Examples

You can invoke the upskill agent using the following command patterns:

```python

# Aggregate mode - analyzes all jobs in the tracking CSV

!python -m agents.upskill

```

```python

# Targeted mode - analyzes a specific job posting URL

!python -m agents.upskill https://example.com/job-posting-123

```

The internal processing follows this conceptual flow:

```python

# Load baseline profile

profile = read_markdown(".claude/skills/job-application-assistant/01-candidate-profile.md")

# Acquire job requirements

jobs = read_csv("job_search_tracker.csv")          # aggregate mode

# OR

job_page = webfetch(url)                           # targeted mode

# Calculate hard skill gaps

skills_from_jobs = extract_skills(job_page or jobs)
hard_gaps = skills_from_jobs - profile.skills

# Synthesize with LLM context

synthesized_gaps = llm_synthesize(hard_gaps, job_context)

# Build plan from live web data

for gap in synthesized_gaps:
    results = websearch(f'"best {gap} course 2026"')
    pick_top_resources(results)

```

## Summary

- The ai-job-search `/upskill` agent uses **no pre-trained dataset**; all analysis happens at runtime using live data.
- Three primary sources feed the AI: the candidate profile markdown, job posting data (CSV or URL), and real-time web search results.
- The system calculates hard-skill gaps by differencing job requirements against the candidate profile, then uses LLM synthesis to identify soft-skill and tooling gaps.
- Learning recommendations always pull current-year resources via live web searches to ensure accuracy.

## Frequently Asked Questions

### Does the ai-job-search repository include a pre-trained AI model for skill analysis?

No. According to the source code in [`.claude/skills/upskill/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/upskill/SKILL.md), the system performs "training" at runtime by feeding the LLM live candidate profiles and job posting data. No static training corpus is bundled with the repository.

### Where is my personal skill data stored in the repository?

Your skill inventory resides in [`.claude/skills/job-application-assistant/01-candidate-profile.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-application-assistant/01-candidate-profile.md) as a markdown file. This file serves as the baseline "skill inventory" that the agent compares against job requirements during Step 3 of the upskill workflow.

### How does the system ensure learning recommendations are current and not outdated?

The agent explicitly avoids static course catalogs by executing fresh **WebSearch** queries that include the current year (e.g., "best Python course 2026"). This occurs during Steps 6-8 of the workflow defined in [`SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/SKILL.md), ensuring resources are extant and verifiable rather than hallucinated.

### Can I analyze a single specific job posting rather than my entire tracked history?

Yes. While aggregate mode parses `job_search_tracker.csv`, you can run targeted analysis by passing a URL argument: `python -m agents.upskill https://example.com/job-posting`. The agent then uses **WebFetch** to retrieve that specific posting for analysis.