Skip to content

Repository files navigation

MIA - Course Recommendation Engine

AI-powered course recommendation engine built using Azure OpenAI for Data Science and AI careers.

MIA helps users discover the most relevant learning resources for Data Science and AI careers. It follows a multi-agent architecture where every agent has a single responsibility, with Azure OpenAI's inbuilt guardrails protecting every LLM interaction.


System Workflow

flowchart TD
    %% ── Entry point ───────────────────────────────────────────────
    START([User Query]) --> IG{Input Guard Agent}

    %% ── Input guard decision ──────────────────────────────────────
    IG -->|REJECTED| REJ[Return Error Response]
    IG -->|VALID| IE[Intent Extraction Agent]

    %% ── Core pipeline ─────────────────────────────────────────────
    IE --> REC[Recommendation Agent]
    CAT[(Course Catalog)] --> REC
    REC --> RG[Response Generation Agent]
    RG --> OG{Output Guard Agent}

    %% ── Output guard decision ─────────────────────────────────────
    OG -->|REJECTED| FALLBACK[Return Safe Fallback Response]
    OG -->|VALID| FINAL([Final Response])

    %% ── Grouping by responsibility ────────────────────────────────
    subgraph LLM["Azure OpenAI (LLM)"]
        IE
        RG
    end

    subgraph DETERMINISTIC["Deterministic (No LLM)"]
        REC
    end

    subgraph GUARDRAILS["Azure Inbuilt Guardrails"]
        IG
        OG
    end

    %% ── Legend ────────────────────────────────────────────────────
    subgraph LEGEND["Legend"]
        direction LR
        L1([Start / End])
        L2{Decision Point}
        L3[Agent / Process]
        L4[(Data Source)]
    end
Loading

How to read this diagram: rounded nodes are entry/exit points, diamonds are guardrail decision points, rectangles are agents/processes, and cylinders are data sources. The three subgraphs group components by responsibility: LLM-backed agents, the deterministic recommendation engine, and the guardrails.

Pipeline Steps

  1. Input Guard Agent — Validates the request using Azure's inbuilt content filters + domain relevance. Rejects off-topic or unsafe queries before they reach the LLM.
  2. Intent Extraction Agent — Uses Azure OpenAI to extract the user's profile (career goal, skills, missing skills, experience level).
  3. Recommendation Agent — Deterministically matches courses from app/data/courses.json. Never calls the LLM.
  4. Response Generation Agent — Uses Azure OpenAI to generate a friendly mentor explanation of the recommended courses.
  5. Output Guard Agent — Validates the LLM output for hallucinated courses and unsafe content before returning it.

System Architecture (Tree View)

flowchart TD
    MIA[MIA - Course Recommendation Engine]

    MIA --> GUARD[Guardrails]
    MIA --> LLM[LLM Agents]
    MIA --> DET[Deterministic]
    MIA --> DATA[Data]

    GUARD --> IG[Input Guard Agent<br/>validates requests]
    GUARD --> OG[Output Guard Agent<br/>validates responses]

    LLM --> IE[Intent Extraction Agent<br/>extracts user profile]
    LLM --> RG[Response Generation Agent<br/>writes mentor response]

    DET --> REC[Recommendation Agent<br/>matches courses]

    DATA --> CAT[(Course Catalog<br/>courses.json)]
Loading

How to read this tree: the engine splits into four responsibility branches — Guardrails (input/output validation), LLM Agents (Azure OpenAI reasoning), Deterministic (no-LLM course matching), and Data (the course catalog). Each leaf shows the agent and its single responsibility.


Agents

Agent Responsibility Uses LLM?
Input Guard Validates requests, ensures domain relevance, content safety No (Azure inbuilt guardrails)
Intent Extraction Extracts user profile (career goal, skills, missing skills, level) ✅ Azure OpenAI
Recommendation Deterministic course matching from app/data/courses.json ❌ Never
Response Generation Generates natural language mentor responses ✅ Azure OpenAI
Output Guard Validates output for hallucinations and unsafe content No (Azure inbuilt guardrails)

Guardrails (Azure OpenAI Inbuilt)

MIA relies on Azure OpenAI's inbuilt guardrails rather than custom heuristics:

Guardrail Applied to Where
Content filters (Hate, Self-Harm, Sexual, Violence) Prompts & Completions Azure AI Content Safety SDK + server-side
Prompt Shields (jailbreak / prompt injection) User prompts Configured in Azure AI Foundry (server-side)
Protected Material (text & code) Completions Configured in Azure AI Foundry (server-side)

Setup: In Azure AI Foundry → Guardrails + controls → Content filters, enable Prompt Shields and Protected Material detection on the deployments used by the Intent Extraction and Response Generation agents.


Tech Stack

  • Python 3.12+ with type hints
  • FastAPI + Uvicorn — REST API
  • Azure OpenAI — LLM for intent extraction & response generation
  • Azure AI Content Safety — inbuilt content-filter guardrails
  • Pydantic — data validation & settings
  • structlog — structured logging

Project Structure

course-recommendation-engine/
├── app/
│   ├── main.py                  # FastAPI app entry point
│   ├── api/routes.py            # REST endpoints
│   ├── agents/                  # The 5 agents
│   │   ├── input_guard.py       # Input validation (Azure guardrails + domain)
│   │   ├── intent_extraction.py # User profile extraction (LLM)
│   │   ├── recommendation.py    # Deterministic course matching (no LLM)
│   │   ├── response_generation.py # Mentor response (LLM)
│   │   └── output_guard.py      # Output validation (Azure guardrails + hallucination)
│   ├── llm/
│   │   ├── azure_client.py      # Azure OpenAI client
│   │   ├── azure_content_safety.py # Azure AI Content Safety client
│   │   ├── extractor.py         # Intent extraction LLM logic
│   │   ├── explainer.py         # Response generation LLM logic
│   │   └── prompts.py           # Centralized system prompts
│   ├── models/schemas.py        # Pydantic models
│   ├── config/settings.py       # Environment configuration
│   ├── data/courses.json        # Course catalog
│   └── utils/                   # Shared helpers & constants
├── tests/                       # pytest test suite
├── requirements.txt
├── run.py                       # CLI entry point
└── .env.example                 # Environment variable template

Setup

1. Prerequisites

  • Python 3.12+
  • An Azure OpenAI resource (deployment for Intent Extraction + Response Generation)
  • An Azure AI Content Safety resource

2. Install dependencies

python -m venv .venv
.venv\Scripts\activate        # Windows
source .venv/bin/activate     # macOS / Linux
pip install -r requirements.txt

3. Configure environment

cp .env.example .env

Fill in your Azure credentials in .env:

AZURE_OPENAI_ENDPOINT=https://<your-resource>.openai.azure.com/
AZURE_OPENAI_API_KEY=<your-api-key>
AZURE_OPENAI_DEPLOYMENT_NAME=gpt-4o

AZURE_CONTENT_SAFETY_ENDPOINT=https://<your-contentsafety>.cognitiveservices.azure.com/
AZURE_CONTENT_SAFETY_API_KEY=<your-content-safety-key>

4. Run the server

# Windows
.venv\Scripts\python.exe -m uvicorn app.main:app --reload

# macOS / Linux
.venv/bin/python -m uvicorn app.main:app --reload

The API will be available at:

  • Swagger UI: http://localhost:8000/docs
  • Health check: http://localhost:8000/api/v1/health
  • Base URL: http://localhost:8000

API Endpoints

GET /docs

Interactive API documentation (Swagger UI). Open it in your browser:

http://localhost:8000/docs

GET /api/v1/health

Health check.

curl http://localhost:8000/api/v1/health

POST /api/v1/recommend

Get course recommendations for a user query.

curl -X POST http://localhost:8000/api/v1/recommend \
  -H "Content-Type: application/json" \
  -d '{"query": "I know Python and Pandas. I want to become a Data Scientist."}'

Response:

{
  "status": "SUCCESS",
  "response": "Great choice! Here are some courses to help you become a Data Scientist...",
  "recommendations": [
    {
      "course": {
        "id": "course-003",
        "title": "SQL for Data Analysis",
        "url": "https://learn.microsoft.com/training/paths/get-started-querying-with-transact-sql/"
      },
      "score": 0.58,
      "reasoning": "Matches 1 of your missing skills"
    }
  ]
}

Testing

pytest tests -v

Architecture Principles

  • Single Responsibility — each agent does one thing
  • Stateless agents — no shared mutable state
  • Deterministic recommendation engine — no LLM in course matching
  • LLM only for reasoning and explanation
  • Guardrails before and after every LLM interaction (Azure inbuilt)

Future Agents

The architecture supports adding new agents without modifying existing ones:

  • Resume Review Agent
  • Interview Preparation Agent
  • Career Roadmap Agent
  • Skill Gap Analysis Agent
  • Learning Progress Agent

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages