Hawker is an AI-powered news search engine that crawls RSS feeds, filters for AI-related content, embeds articles into vector space, and ranks results using a composite of semantic similarity, freshness, and keyword density.
Fetches articles from 24 curated RSS feeds spanning research labs (OpenAI, DeepMind, Meta AI), developer blogs (Hugging Face, PyTorch), AI newsletters, and tech publications (TechCrunch, MIT News, Wired).
Each feed is parsed with feedparser, then full article text is extracted using newspaper3k with 8 parallel workers. Articles older than 7 days and those that have been crawled in previous runs are dropped before extraction to save bandwidth.
Each article is scored against a curated list of ~50 AI-related terms (machine learning, LLM, transformer, computer vision, etc.). Articles matching at least one keyword pass through.
The keyword score — ratio of distinct matched terms to total terms — is saved and later used as one of three ranking signals. Typical pass rate is ~70%.
Extracts key entities (PERSON, ORG, GPE) using spaCy's en_core_web_sm model from the cleaned article text.
Entities are stored as tags, allowing us to identify the main actors in every story (e.g., 'Sam Altman', 'Google', 'NVIDIA') and use them for topic labeling.
Articles are converted into 384-dim vectors with MiniLM-L6-v2 and grouped into clusters using scikit-learn's K-Means.
Clustering groups semantically similar stories into 'Trending Topics'. Topics are dynamically labeled by looking at the most frequent entities inside each cluster.
Normalized embeddings and topic associations are stored in PostgreSQL using the pgvector extension with an HNSW index.
The system supports both vector searching (for queries) and relational filtering (for topic chips), combined into a single performant pipeline.
score = 0.50 x semantic_sim + 0.20 x time_decay + 0.30 x keyword_score
Cosine similarity between the query embedding and the article embedding. Captures meaning, not just keyword overlap.
Exponential freshness score: 2^(-hours / 48). Rewards recent news while slightly penalizing older evergreen content.
Ratio of distinct AI keywords found in the article. Gives a bonus to articles deeply focused on specialist AI topics.
NER
spaCy (en_core_web_sm)
Clustering
scikit-learn (K-Means)
Embeddings
sentence-transformers (MiniLM-L6-v2, 384-dim)
Vector Search
PostgreSQL + pgvector (HNSW cosine index)
RSS Parsing
feedparser + newspaper3k
Summarization
DistilBART-CNN-12-6 (abstractive, on-demand)
API
FastAPI + Uvicorn
Frontend
Next.js + Tailwind CSS
Database
PostgreSQL + pgvector (Supabase)
Language
Python 3.12 (backend) + TypeScript (frontend)
24 RSS Feeds
feedparser + newspaper3k
PostgreSQL + pgvector
HNSW index, cosine similarity
Composite Ranker
semantic + filter
Summarizer
DistilBART