| --- |
| title: PhDScout |
| emoji: π |
| colorFrom: blue |
| colorTo: indigo |
| sdk: gradio |
| sdk_version: "5.23.3" |
| app_file: app.py |
| pinned: false |
| license: mit |
| short_description: AI-powered search agent for PhD and academic positions |
| --- |
| |
| <h1 align="center">PhdScout π</h1> |
|
|
| <p align="center"> |
| <strong>AI-powered search agent for PhD positions, postdocs, research fellowships, and academic staff roles.</strong> |
| </p> |
|
|
| <p align="center"> |
| π <strong>100% free</strong> β no subscriptions, no API costs, no sign-up required.<br> |
| Live demo on HuggingFace Spaces: <a href="https://huggingface.co/spaces/HipFil98/PhDScout">HipFil98/PhDScout</a><br> |
| π <a href="https://hipsterfil998.github.io/PhDScout">Full documentation</a> |
| </p> |
|
|
| --- |
|
|
| ## What it does |
|
|
| Upload your CV, set a research field and country, and PhdScout will: |
|
|
| - **Search** multiple academic job boards for open positions |
| - **Score** each position against your profile (0β100 match score) |
| - **Rank** all results and highlight the best fits |
| - **Generate** a personalized cover letter draft for every position |
| - **Export** all approved applications as a ZIP (cover letters + position details) |
|
|
| --- |
|
|
| ## How to use |
|
|
| 1. Upload your CV (PDF, DOCX, or TXT) |
| 2. Enter your research field (e.g. `machine learning`, `computational biology`) |
| 3. Select a country or region from the dropdown (40+ options, or type a custom value) |
| 4. Choose the position type (`PhD`, `postdoc`, `fellowship`, `predoctoral`, `research staff`) |
| 5. Set a minimum match score (used as a recommendation threshold β all positions are reviewable) |
| 6. Click **Parse CV & Search Positions** and wait (~2β3 minutes) |
| 7. In the **Results** tab, browse all scored positions |
| 8. In the **Review & Edit** tab, load any position, read CV tailoring hints, and edit the cover letter |
| 9. Click **Approve & Save** for positions you want to apply to |
| 10. In the **Export** tab, download all approved applications as a ZIP |
|
|
| --- |
|
|
| ## Running locally |
|
|
| ```bash |
| git clone https://github.com/Hipsterfil998/PhDScout.git |
| cd PhDScout |
| pip install -r requirements.txt |
| ``` |
|
|
| Create a `.env` file: |
|
|
| ```env |
| LLM_BACKEND=groq |
| GROQ_API_KEY=your_groq_api_key |
| ``` |
|
|
| Get a free Groq API key at [console.groq.com/keys](https://console.groq.com/keys). |
|
|
| Then run: |
|
|
| ```bash |
| python app.py |
| ``` |
|
|
| The app will be available at `http://localhost:7860`. |
|
|
| --- |
|
|
| ## Project structure |
|
|
| ``` |
| PhDScout/ |
| βββ app.py # Gradio web interface |
| βββ config.py # Runtime settings (model, thresholds, delays) |
| βββ requirements.txt |
| βββ agent/ |
| βββ __init__.py # Public API: JobAgent, LLMQuotaError |
| βββ pipeline.py # JobAgent orchestrator |
| βββ base_service.py # BaseLLMService base class |
| βββ llm_client.py # Groq / HuggingFace / Ollama client |
| βββ utils.py # Shared utilities |
| βββ prompts/ # LLM prompts β one file per service |
| β βββ cv_parser.py |
| β βββ job_matcher.py |
| β βββ cv_tailor.py |
| β βββ cover_letter.py |
| βββ cv/ # CV-related services |
| β βββ parser.py # CV extraction + LLM parsing |
| β βββ tailor.py # Tailoring hints generator |
| β βββ cover_letter.py # Cover letter writer |
| βββ matching/ |
| β βββ matcher.py # LLM-based scoring + PhD eligibility cap |
| βββ search/ |
| βββ searcher.py # JobSearcher (orchestrates scrapers) |
| βββ scrapers/ |
| βββ base.py # BaseScraper ABC + shared helpers |
| βββ euraxess.py # EU/worldwide research portal |
| βββ mlscientist.py # ML & AI academic positions |
| βββ jobs_ac_uk.py # UK academic jobs (UK/worldwide only) |
| βββ scholarshipdb.py # Worldwide aggregator (28k+ positions) |
| βββ nature_careers.py # Nature.com/careers β multidisciplinary |
| ``` |
|
|
| --- |
|
|
| ## Model |
|
|
| Powered by [Groq](https://groq.com) free API β fast inference, no subscription required. |
| Uses `llama-3.1-8b-instant` by default. To change the model, edit `default_model` in `config.py`. |
|
|
| For local use, the app also supports **Ollama** β set `LLM_BACKEND=ollama` in `.env`. |
|
|
| --- |
|
|
| ## Credits |
|
|
| Job data sourced from: |
| - [Euraxess](https://euraxess.ec.europa.eu) β European Commission portal for research careers |
| - [mlscientist.com](https://mlscientist.com) β ML & AI academic job board |
| - [jobs.ac.uk](https://www.jobs.ac.uk) β UK academic jobs portal |
| - [scholarshipdb.net](https://scholarshipdb.net) β Worldwide academic jobs and scholarships aggregator |
| - [nature.com/careers](https://www.nature.com/naturecareers) β Multidisciplinary global research job board |
|
|
| LLM inference powered by [Groq](https://groq.com) free API. |
|
|
| --- |
|
|
| ## Cite this work |
|
|
| If you use PhdScout in your research or project, please cite it as: |
|
|
| ```bibtex |
| @software{pellegrino2026phdscout, |
| author = {Pellegrino, Filippo}, |
| title = {{PhdScout}: an AI-powered search agent for academic positions}, |
| year = {2026}, |
| url = {https://github.com/Hipsterfil998/PhDScout}, |
| license = {MIT} |
| } |
| ``` |
|
|
| --- |
|
|
| ## License |
|
|
| MIT |
|
|