Multi-agent interview package generator built with CrewAI Flows and exposed via FastAPI.
Given a candidate profile (role, career, experience) and the company's job offer, Intervia produces a complete interview package:
- Market analysis — live web research via Tavily (salary range, responsibilities, in-demand skills, market/industry trends).
- Tailored question bank — questions split by section (soft / hard skills), generated to be answerable on the spot, matching the skills the company asks for.
- Quality review — an evaluator agent judges every question against a fixed rubric and either approves them or sends them back for rework (only the flagged questions are regenerated; approved ones are kept verbatim).
intervia/
├── backend-app/
│ ├── app/
│ │ ├── api/ # FastAPI app, routes, JSON error handlers
│ │ ├── schemas/ # Pydantic v2 models (strict JSON at every layer)
│ │ ├── llm/ # LLM provider Strategy: deepseek (default) | anthropic
│ │ ├── agents/ # Agent factories + prompts (one focused agent per stage)
│ │ ├── flows/ # InterviewFlow (@start/@router/@listen) + typed state
│ │ └── core/ # config (pydantic-settings) + exceptions
│ ├── examples/ # curl smoke script + REST Client requests
│ ├── tests/ # mocked end-to-end suite (no live LLMs/Tavily)
│ └── README.md # setup, endpoints, examples — start here
├── AGENTS.md # guidance for coding agents working in this repo
└── openspec/ # archived spec-driven design documents
The pipeline is a CrewAI Flow (InterviewFlow) with a deterministic router:
analysis agent → routing → question agents (soft and/or hard, in parallel) →
evaluator agent loop (approve / rework, capped at 2 rounds) → final package.
The models decide the interview focus and the question counts; the code only
reads those decisions and assembles the package.
cd backend-app
uv sync
cp .env.example .env # set LLM_PROVIDER, DEEPSEEK_API_KEY, TAVILY_API_KEY
uv run uvicorn app.api.main:app --reloadThen hit POST /api/v1/interviews/analyze — full usage, endpoints and examples
are documented in backend-app/README.md.
- Models do the work, not the code. Each agent returns a Pydantic schema the next agent consumes; no count math, no grouping helpers, no difficulty labels.
- Consistent evaluation. The evaluator judges against a fixed rubric (relevance, clarity, one-focus, skill coverage, standalone form, immediacy), and questions already approved are never re-judged.
- JSON everywhere, validated by Pydantic v2. Successes return a validated
schema; failures return
ErrorResponseJSON (error,detail,stage). - No vendor lock-in.
LLM_PROVIDERenv var selects the strategy at startup (defaultdeepseek, Claude swappable via config only).
cd backend-app
uv run pytestThe suite never calls live LLMs or Tavily — agents are stubbed at the factory level and the flow is tested end-to-end with mocks.