CoolFace
Apppublic

ehildebrandtrojo/censusGPT

sourceHugging Faceupdated 5mo agoView on Hugging Face
0likes
App README

CensusGPT

Link: https://ehildebrandtrojo-censusgpt.hf.space

A stateful chat agent that answers natural-language questions about US population demographics using the SafeGraph / ACS 2019 5-year estimates stored in Snowflake.


Architecture

User Browser
     │
     ▼
Chainlit (app.py)           — real-time streaming chat UI, per-session history
     │
     ▼
Agent Loop (agent.py)       — drives Anthropic tool-use conversation
     │
     ├── Anthropic Claude (claude-sonnet-4-5)   — reasoning + SQL generation
     │
     └── Tools (tools.py)
           ├── list_table_fields        → browse all fields in an ACS table series
           ├── search_census_metadata   → 9-column ILIKE search with word-fallback
           ├── get_geography            → FIPS code resolution
           └── execute_census_query     → read-only SQL execution
                    │
                    ▼
              Snowflake (db.py)
              US_OPEN_CENSUS_DATA (Marketplace share)

Key design decisions

DecisionChoiceWhy
UI frameworkChainlitBuilt-in streaming, Step visibility for tool calls, easy deployment
LLMclaude-sonnet-4-5Best speed/quality balance for agentic tool use
Field discoverylist_table_fields browse + ILIKE searchTwo-layer approach: search ACS terms, browse by table series when search misses
Metadata search9-column ILIKE + phrase→word fallbackCatches vocabulary mismatches between user language and ACS terminology
Snowflake accessRead-only connection, statement timeout 45 s, row cap 200Defence-in-depth against runaway queries
SQL safetyKeyword blocklist + SELECT-only enforcementPrevents prompt-injection-driven DDL/DML
Conversation memoryChainlit user_sessionScoped to browser tab; stateless server

Agentic loop

  1. 1.Scope check — system prompt rejects off-topic questions without any tool call.
  2. 2.Field discovery — multi-strategy lookup to find the right ACS column:
  3. 3.Check the pre-cached COMMON_METRICS cheat-sheet (30+ common metrics)
  4. 4.Search metadata with search_census_metadata() — 9 columns, two-pass (phrase → word OR)
  5. 5.If search fails: identify the ACS table series from the system prompt index, then call list_table_fields() to browse its full field hierarchy
  6. 6.Geography resolutionget_geography() translates "Cook County" → STATE='IL', COUNTY='Cook' (GEOMETRY-style, no suffix).
  7. 7.SQL executionexecute_census_query() runs the generated SELECT; errors surface back to Claude for one automatic retry.
  8. 8.Synthesis — plain-English answer with every statistic bolded and a one-line data caveat.

ACS Table Coverage

The system prompt includes a comprehensive index of all major ACS table series so the agent knows where to look for any topic:

TopicACS Series
Population, sex, ageB01
Race / Hispanic originB02, B03
Nativity & citizenshipB05, B06
Commute & transportationB08
Household type / familyB11, B12
School enrollmentB14
Educational attainmentB15
Language / English proficiencyB16
PovertyB17
DisabilityB18
IncomeB19
VeteransB21
SNAP / food stampsB22
Employment & unemploymentB23
Occupation & industryB24, C24
Housing (rent, value, tenure, rent burden)B25
Health insuranceB27
Internet & broadbandB28
Income-to-poverty ratioC17

Local Setup

Prerequisites

Installation

bash
git clone <repo-url>
cd censusGPT

python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

cp .env.example .env
# Fill in your credentials in .env

chainlit run app.py
# → open http://localhost:8000

Environment variables

VariableRequiredDefaultDescription
SNOWFLAKE_ACCOUNTAccount identifier (e.g. xy12345.us-east-1)
SNOWFLAKE_USERSnowflake username
SNOWFLAKE_PASSWORDSnowflake password
SNOWFLAKE_WAREHOUSECOMPUTE_WHVirtual warehouse
SNOWFLAKE_DATABASEUS_OPEN_CENSUS_DATADatabase name for the share
SNOWFLAKE_SCHEMAPUBLICSchema within the database
SNOWFLAKE_ROLE(default role)Optional read-only role
ANTHROPIC_API_KEYAnthropic API key
ANTHROPIC_MODELclaude-sonnet-4-5Model override
MAX_QUERY_ROWS200Row cap injected when LIMIT is absent
STATEMENT_TIMEOUT_SECONDS45Snowflake statement timeout

Running Tests

bash
pytest tests/ -v

Tests mock both Snowflake and Anthropic — no live credentials needed.


Deployment (Railway)

  1. 1.Push this repo to GitHub (private).
  2. 2.Create a new Railway project → Deploy from GitHub repo.
  3. 3.Set all environment variables in Railway → Variables.
  4. 4.Railway auto-detects the Dockerfile and deploys.
  5. 5.The public URL is shown in the Railway dashboard.

Example Questions

Income & Housing

  • What is the median household income in Cook County, Illinois?
  • How many renters in Chicago spend more than half their income on rent?
  • What is the median home value in King County, Washington?

Education & Demographics

  • What percentage of adults in Los Angeles County have a bachelor's degree or higher?
  • What is the racial composition of Miami-Dade County?
  • What share of households in Harris County speak Spanish at home?

Poverty & Social Programs

  • Which counties in Texas have the highest poverty rates?
  • What share of households in Cook County receive food stamps?
  • Compare the income-to-poverty ratio in Bronx County vs. Manhattan.

Employment & Commute

  • What percentage of workers in King County commute by public transit?
  • What is the unemployment rate in Wayne County, Michigan?

Health & Disability

  • What is the uninsured rate in Harris County, Texas?
  • What share of the population in Maricopa County has a disability?

Project Structure

censusGPT/
├── app.py             Chainlit entry point, session lifecycle, error handling
├── agent.py           Agentic loop (real-time streaming + tool-call dispatch)
├── tools.py           Tool implementations + Anthropic tool definitions
├── prompts.py         System prompt (ACS table index, vocab hints, golden SQL patterns)
├── db.py              Snowflake connection singleton + async wrapper
├── config.py          Environment-variable configuration
├── tests/
│   ├── conftest.py        Shared fixtures (Snowflake mock)
│   ├── test_tools.py      Unit tests for all four tools
│   └── test_agent.py      Integration tests for the agentic loop
├── .chainlit/
│   └── config.toml        UI theme (dark, wide layout, blue accent)
├── chainlit.md            Welcome screen content
├── Dockerfile
├── railway.toml
└── .env.example