unhinged-panda/linkedin-sourcing-agent
0
Synapse Sourcing Agent
An autonomous sourcing pipeline that discovers LinkedIn profiles for a job description, ranks them with heuristics plus LLM reasoning, deep-scrapes the most promising profiles, and produces personalised outreach โ all through a single FastAPI endpoint or CLI.
๐ Key capabilities
- Multi-engine discovery โ Google / DuckDuckGo / SerpAPI queries (
site:linkedin.com/in). - Semantic filter โ MiniLM embeddings keep only semantically relevant profiles.
- Heuristic rubric โ Education, trajectory, company pedigree, skills, location & tenure.
- LLM refinement โ Gemini re-scores the top N candidates and crafts outreach copy.
- Deep enrichment (optional) โ Headless Chrome +
linkedin-scraperto pull full Experience / Education sections when a valid LinkedIn session cookie (LI_AT) is provided.
๐ Quick start (local)
# Python โฅ3.10
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
# Mandatory โ Google Gemini
export GOOGLE_API_KEY="***"
# (Optional) richer search & enrichment
export SERPAPI_KEY="***" # SerpAPI quota >0
export LI_AT="Aqu3..." # Your LinkedIn session cookie
export MAX_DEEP_SCRAPES=10 # Limit Selenium calls per run
# ๐ CLI
python main.py --top 10 job_description.txt
# ๐ REST API
uvicorn synapse.api:app --host 0.0.0.0 --port 8000
curl -X POST http://localhost:8000/source -H 'Content-Type: application/json' -d '{"job_description": "Software Engineer, ML Research โฆ"}'๐ณ Docker
The included Dockerfile builds a slim container with Chromium + ChromeDriver so deep scraping works out-of-the-box.
# Build
docker build -t synapse-agent .
# Run (without enrichment)
docker run -p 7860:7860 -e GOOGLE_API_KEY=$GOOGLE_API_KEY synapse-agent
# Run (with enrichment)
docker run -p 7860:7860 \
-e GOOGLE_API_KEY=$GOOGLE_API_KEY \
-e SERPAPI_KEY=$SERPAPI_KEY \
-e LI_AT=$LI_AT \
synapse-agentThe REST endpoint will be available at POST /source on port 7860.
๐ค Hugging Face Spaces
- Create a new Docker Space.
- Add the same
GOOGLE_API_KEY(and optionallyLI_AT,SERPAPI_KEY) under Settings โ Secrets. - Push this repo โ Spaces automatically builds the Dockerfile and exposes port 7860.
- Call the public URL:
curl https://<username>-synapse.hf.space/source \
-H 'Content-Type: application/json' \
-d '{"job_description": "โฆ"}'โ ๏ธ If no LI_AT secret is provided, the agent will skip deep enrichment and still return high-level data (headline, snippet, location) using SerpAPI & public scraping.๐ Environment variables
๐๏ธ Project layout
synapse/
__init__.py
agent.py โ pipeline orchestration
search.py โ discovery + semantic filter
profile_enrich.py โ SerpAPI + jina.ai fallback
deep_enrich.py โ Selenium + linkedin-scraper
rubric.py โ heuristic scoring
outreach.py โ Gemini message generation
api.py โ FastAPI wrapper
main.py โ CLI entry-point
Dockerfile โ production image
requirements.txt๐งช Test run
curl -X POST http://localhost:7860/source \
-H 'Content-Type: application/json' \
-d '{"job_description": "Senior ML Research Engineer โ focus on LLMs, Bay Area preferred"}' | jqExpected output (truncated):
{
"job_id": "ab34cd1e",
"candidates_found": 30,
"top_candidates": [
{
"name": "Alice Zhang",
"linkedin_url": "https://www.linkedin.com/in/alicez",
"headline": "Staff ML Engineer | GPT-4, LLAMA-3, applied research",
"semantic_score": 0.82,
"score_breakdown": { โฆ },
"fit_score": 9.3,
"outreach_message": "Hi Alice, โฆ"
}
]
}Happy sourcing! :rocket:
