▲ 0 r/irving+1 crossposts

I built CivicLens AI — ask a city’s official budget book questions in plain English

City budget PDFs are public, but they are hundreds of pages of tables, staffing notes, and comparison columns. Most people never open them. I wanted something a resident could actually use: pick a city, ask a normal question, and get an answer grounded in that city’s adopted budget — with page citations.

**What it does ?**

CivicLens AI is a RAG app over official municipal budget books. You pick a city, ask something like “How much is police funded this year?” or “What changed in parks staffing?”, and it answers from that city’s book only. Figures from Irving never leak into a Frisco answer.

Right now it covers Irving, TX and Frisco, TX for FY 2025-26.

**How it works ?**

Offline pipeline: pdfplumber extracts page text, a token sliding window (512 / 64 overlap) chunks it, Gemini embeds the chunks, Qdrant stores them.

At query time: hybrid retrieval — vector search plus BM25 — both filtered by the selected city.

The LLM answers only from retrieved context. If the book doesn’t have it, it says so instead of guessing.

Frontend is Next.js; API is FastAPI. Deployed on Vercel + Render + Qdrant Cloud.

The prompt work was the unglamorous part. Budget tables have comparison years, OCR-split numbers, merged job titles (“5Logistics”), and decimals like 109.0 that models love to turn into 1,090. A lot of the system prompt is “copy the figure, don’t invent a total, cite the page.”

**What I learned ?**

Municipal PDFs are hostile RAG data. Dot leaders, layout-broken numbers, and one table with five fiscal-year columns will wreck a naive chunk-and-embed pipeline. City-scoped retrieval mattered more than a fancier model. Hybrid search helped when the answer was one sentence buried in a mixed-topic page.

**Limitations ?**

It’s two cities and one fiscal year. Answers are only as good as extraction + retrieval. Changing chunk size means re-embedding the whole corpus. The API is public, so it’s rate-limited.

**Website Link ?** \- https://civic-lens-black.vercel.app/

reddit.com
u/Used_Direction8216 — 12 days ago
▲ 5 r/localgovernment+1 crossposts

I built CivicLens AI — ask a city’s official budget book questions in plain English

City budget PDFs are public, but they are hundreds of pages of tables, staffing notes, and comparison columns. Most people never open them. I wanted something a resident could actually use: pick a city, ask a normal question, and get an answer grounded in that city’s adopted budget — with page citations.

**What it does ?**

CivicLens AI is a RAG app over official municipal budget books. You pick a city, ask something like “How much is police funded this year?” or “What changed in parks staffing?”, and it answers from that city’s book only. Figures from Irving never leak into a Frisco answer.

Right now it covers Irving, TX and Frisco, TX for FY 2025-26.

**How it works ?**

Offline pipeline: pdfplumber extracts page text, a token sliding window (512 / 64 overlap) chunks it, Gemini embeds the chunks, Qdrant stores them.

At query time: hybrid retrieval — vector search plus BM25 — both filtered by the selected city.

The LLM answers only from retrieved context. If the book doesn’t have it, it says so instead of guessing.

Frontend is Next.js; API is FastAPI. Deployed on Vercel + Render + Qdrant Cloud.

The prompt work was the unglamorous part. Budget tables have comparison years, OCR-split numbers, merged job titles (“5Logistics”), and decimals like 109.0 that models love to turn into 1,090. A lot of the system prompt is “copy the figure, don’t invent a total, cite the page.”

**What I learned ?**

Municipal PDFs are hostile RAG data. Dot leaders, layout-broken numbers, and one table with five fiscal-year columns will wreck a naive chunk-and-embed pipeline. City-scoped retrieval mattered more than a fancier model. Hybrid search helped when the answer was one sentence buried in a mixed-topic page.

**Limitations ?**

It’s two cities and one fiscal year. Answers are only as good as extraction + retrieval. Changing chunk size means re-embedding the whole corpus. The API is public, so it’s rate-limited.

**Website Link ?** \- https://civic-lens-black.vercel.app/

reddit.com
u/Used_Direction8216 — 13 days ago