An AI-native apartment search and neighborhood intelligence platform that transforms NYC public datasets into a conversational, queryable intelligence layer. Built on the NVIDIA DGX Spark (Acer Veriton GN100) with Llama 3.3 70B via speculative decoding.
Track: Human Impact | Bounty: Most Impactful Use of OpenClaw
- NVIDIA DGX Spark (or any machine with 128GB+ GPU memory)
- Docker running (
docker start openclaw-pgfor pgvector) - Ollama running (for 8B router model)
- Python 3.11+ with venv
docker start openclaw-pg
# If first time: docker run -d --name openclaw-pg --restart unless-stopped \
# -p 5433:5432 -e POSTGRES_PASSWORD=openclaw -e POSTGRES_USER=openclaw \
# -e POSTGRES_DB=openclaw pgvector/pgvector:pg17~/openclaw/start-llm.sh
# Wait for "server is listening on http://127.0.0.1:8090"~/openclaw/start-app.sh
# Wait for "Application startup complete"
# Open http://localhost:8000/ui/DATABASE_URL=postgresql://openclaw:openclaw@127.0.0.1:5433/openclaw
EMBEDDING_BACKEND=bge-small
OPENCLAW_LLM_ENABLED=1
OPENCLAW_LLM_BASE_URL=http://127.0.0.1:8090/v1
OPENCLAW_LLM_MODEL=llama-3.3-70b-spec
OPENCLAW_HYDRATE_PGVECTOR=1
No external API keys required. Everything runs locally.
cp .env.example .env
# Edit if needed — defaults work for DGX Spark setup┌─────────────────────────────────────────────────────────┐
│ React SPA (frontend/) │
│ Chat (multi-conversation) · Analysis · Rentals · Map │
└──────────────────────────┬──────────────────────────────┘
│ HTTP/JSON
┌──────────────────────────▼──────────────────────────────┐
│ FastAPI (backend/) │
│ /query · /compare · /rank · /trend · /rentals · /geojson│
└──────────────────────────┬──────────────────────────────┘
│
┌──────────────────────────▼──────────────────────────────┐
│ Hybrid Agent (Think → Execute → Answer) │
│ 8B routes datasets → queries run → 70B writes answer │
└───┬──────────────┬───────────────┬──────────────────────┘
│ │ │
┌───▼────┐ ┌────▼─────┐ ┌────▼──────────┐
│ Vector │ │ Index │ │ Rental │
│ Search │ │ Engine │ │ Listings │
│(pgvec) │ │(compute) │ │(SQL filter) │
└───┬────┘ └────┬─────┘ └────┬──────────┘
└─────────────▼──────────────┘
│
┌─────────────────▼──────────────────────────┐
│ Data Layer │
│ pgvector: 5,751 embedded documents │
│ In-memory: 14 neighborhood snapshots │
│ Synthetic: 2,500 rental listings │
│ GeoJSON: 262 NYC NTA boundary polygons │
└─────────────────▲──────────────────────────┘
│
┌─────────────────┴──────────────────────────┐
│ LLM Inference (NVIDIA GB10 Blackwell) │
│ 70B main + 3B draft (speculative decoding) │
│ llama.cpp · BLACKWELL_NATIVE_FP4 · 11t/s │
│ + Ollama 8B router · BGE-small embeddings │
└─────────────────────────────────────────────┘
| Layer | Technology |
|---|---|
| LLM (answer) | Llama 3.3 70B Instruct Q4_K_M via llama.cpp speculative decoding |
| LLM (router) | Llama 3.1 8B Instruct via Ollama |
| Embeddings | BAAI/bge-small-en-v1.5 (384-dim) via fastembed (ONNX Runtime) |
| Vector DB | PostgreSQL 17 + pgvector 0.8.2 (Docker) |
| Backend | Python 3.12, FastAPI, uvicorn |
| Frontend | React 18, TypeScript, Vite |
| Map | SVG-rendered NYC NTA boundaries from NYC DCP (real GeoJSON) |
| Hardware | NVIDIA DGX Spark (GB10 Blackwell, 128GB unified memory) |
All data sourced from public NYC Open Data (data.cityofnewyork.us) via Socrata API:
| Dataset | Source | Records | Format |
|---|---|---|---|
| 311 Complaints | erm2-nwe9 |
1,500 | Real (via SoQL aggregation) |
| DOB Building Violations | 3h2n-5cm9 |
1,172 | Real (via SoQL) |
| Squirrel Census 2018 | vfnx-vebw |
3,023 | Real (full dataset) |
| NTA Boundaries | 9nt8-h7nd |
262 polygons | Real GeoJSON |
| Rental Listings | Synthetic | 2,500 | Generated from curated NYC neighborhood baselines |
| Neighborhood Indices | Computed | 14 neighborhoods × 8 indices | Deterministic from raw metrics |
Synthetic rental listings are generated from real NYC neighborhood rent medians with ±30% variance, real street names, and deterministic seeding. They are clearly marked as synthetic in the codebase.
The generalized abstraction at backend/skill/:
from backend.skill import OpenClawSkill, DatasetSpec, SocrataSource
skill = OpenClawSkill(
name="my-project",
datasets=[
DatasetSpec(
name="complaints",
description="Customer complaints with severity and location",
source=SocrataSource(endpoint="data.example.com/resource/abc.json"),
content_template="{category}: {description} ({location})",
),
],
vector_store_dsn="postgresql://...",
llm_base_url="http://localhost:8090/v1",
llm_model="llama-3.3-70b-spec",
)
skill.ingest()
result = skill.query("what are the top issues")Add any dataset → LLM automatically becomes aware of it via auto-generated prompts from dataset metadata.
- Clone the repo
python -m venv .venv && source .venv/bin/activatepip install -r requirements.txt- Start pgvector:
docker start openclaw-pg - Hydrate data:
python -m scripts.ingest.pgvector_hydrate - Start 70B:
~/openclaw/start-llm.sh - Start app:
~/openclaw/start-app.sh - Open
http://localhost:8000/ui/
Try:
- Chat: "Where should I live for best squirrel watching and Chinese food?"
- Chat: "Find me a 2-bed under $4,000 in Harlem"
- Analysis: Compare Harlem vs Park Slope (click Compare button)
- Rentals: Click a neighborhood on the map → browse listings → "Chat about this property"
pytest # 147+ backend tests
cd frontend && npm run test # 11 frontend tests
OPENCLAW_TEST_PG=1 pytest # + pgvector integration
python scripts/test_skill_battery.py # 11 skill integration testsLimitations:
- Rental listings are synthetic (not from a real listing API)
- 14 curated neighborhoods (not all 262 NYC NTAs)
- No real-time transit/routing (estimates based on neighborhood data)
- pgvector cosine distance operator (
<=>) has compatibility issues with psycopg3; using L2 distance (<->) as workaround - vLLM cannot run on GB10 Blackwell yet (SM 12.1 not supported by PyTorch)
Next Steps:
- OSM Overpass POI integration (restaurants, bars, libraries, parks, grocery)
- Open-Meteo weather history + FEMA flood risk per address
- Real MTA GTFS transit data for commute estimates
- All 262 NYC NTAs with real metrics from 311 aggregation
- Interactive Leaflet map (react-leaflet v5 has runtime issues with Vite; using SVG for now)
- NemoClaw integration for sandboxed deployment (blocked by network namespace isolation)
Apache 2.0