Public service search and recommendations
Search that reads "I want to quit smoking" and finds the city's anti-smoking program.
My role
Main author of the discovery layer, with 73 of 106 commits. Before it, I maintained the previous Typesense-based search.
- 519
- req/s peak in the load test
- 0%
- errors across 238k requests
- 3
- ranked lists fused with RRF
Problem
People type the way they talk, while the catalog uses official service names, so plain full-text search missed. Services, courses and jobs also lived in separate stores.
Solution
A Go discovery layer on PostgreSQL with pgvector, pg_trgm and unaccent. The query is expanded with synonyms and fires two calls in parallel, one embedding the question and one generating a HyDE document with Gemini and embedding that. Portuguese full-text, the question vector and the HyDE vector are fused with Reciprocal Rank Fusion, and the top 20 go through a cross-encoder reranker.
Highlights
- Staged degradation. If Vertex AI doesn't answer within 4 s, search drops to two lists and, if needed, to plain full-text.
- Profile-based recommendations across 6 dimensions (education, income, location, accessibility, age group and context).
- CPFs (Brazilian taxpayer IDs) are never stored in clear text, only as salted hashes, in the database and in the cache.
- On the previous Typesense version I added crawling and an LLM service for document ingestion.
Result
The staging load test pushed 238k requests at a 519 req/s peak with zero errors. The analysis also traced the slow tail to retries against a deprecated embedding endpoint.