A privacy-first local AI chat assistant that recommends places and renders interactive Google Maps directly in the chat interface. All LLM processing runs on your own machine — no cloud AI, no query logging.
User
│
▼
┌─────────────────────┐ ┌──────────────────────┐
│ Open WebUI │────>│ Ollama │
│ (Frontend) │ │ Qwen3.5-9B │
│ localhost:8080 │ │ localhost:11434 │
└──────────┬──────────┘ └──────────────────────┘
│
│ (place queries via custom Tool)
▼
┌─────────────────────┐ ┌──────────────────────┐
│ FastAPI Backend │────>│ Google Maps APIs │
│ localhost:8000 │ │ (Places, Embed, │
│ │ │ Geocoding, Dirs) │
└─────────────────────┘ └──────────────────────┘
Data flow for a place or directions query:
- User types: "Best sushi near Ciputat" or "How do I get to Monas?"
- Qwen3.5-9B detects spatial intent → triggers
search_placesorget_directionstool - Tool calls
POST /api/placesorGET /api/directionson the local backend - Backend calls Google Maps APIs → builds embed HTML and fallback links
- Map iframe (if not sanitized) or Markdown link renders inline in the chat
| Component | Minimum | Recommended (this project's target) |
|---|---|---|
| CPU | 4 cores, AVX2 support | AMD Ryzen 5 3400G or equivalent |
| RAM | 16 GB | 24 GB DDR4 |
| GPU | Not required | Not required (CPU-only inference) |
| Storage | HDD (slow) | SSD (required for reasonable load times) |
| OS | Windows 10 | Windows 10/11 |
| Internet | Required | Required (Google Maps API calls) |
| Component | Port | URL |
|---|---|---|
| Open WebUI (frontend) | 8080 | http://localhost:8080 |
| Ollama (LLM runtime) | 11434 | http://localhost:11434 |
| FastAPI backend | 8000 | http://localhost:8000 |
- Python 3.11+ installed and on PATH
- Ollama installed (ollama.com)
- Docker Desktop installed (optional — needed for Docker install path only)
- Google Cloud account with billing enabled
# 1. Pull the LLM model (6.6 GB download — do this first while setting up other things)
ollama pull qwen3.5:9b
# 2. Start Ollama (runs as background service on Windows after install)
ollama serve
# 3. Configure backend environment
copy backend\.env.example backend\.env
# Edit backend\.env and set GOOGLE_MAPS_API_KEY
# 4. Start the backend
cd backend
python -m venv venv
venv\Scripts\activate
pip install -r requirements.txt
uvicorn main:app --host 127.0.0.1 --port 8000 --reload
# 5. Start Open WebUI and open http://localhost:8080
docker run -d -p 8080:8080 \
--add-host=host.docker.internal:host-gateway \
-e OLLAMA_BASE_URL=http://host.docker.internal:11434 \
-v open-webui:/app/backend/data \
--name open-webui \
ghcr.io/open-webui/open-webui:mainAfter completing step 5, register the search_places custom tool in Open WebUI admin panel — see docs/integration/open-webui-tool.md.
- Prerequisites — system requirements, tools to install
- Ollama Setup — install Ollama, pull Qwen3.5-9B, verify performance
- Open WebUI Setup — install and configure the chat frontend
- Google Cloud Setup — create API key, enable APIs, set quotas
- Backend Setup — configure and start the FastAPI backend
- API Overview — base URL, CORS, rate limiting, error format
- Endpoints — full reference for all 4 endpoints
- Error Codes — error code catalog
- Open WebUI Tool — register the
search_placestool (primary approach)
- Environment Variables — all
.envvariables documented - Hardware & Performance — benchmarks, tuning, upgrade path
- Troubleshooting — symptom → diagnosis → fix
- Contributing — dev workflow, code conventions, how to add endpoints/tools
- PRD — full product requirements document
- Response time: CPU-only inference on Ryzen 5 3400G produces ~3-8 tokens/second. Expect 5-15 seconds for LLM processing and 10-25 seconds end-to-end for a place query. Tuning
think=falseis highly recommended. - Ollama tool-calling bug: Qwen 3.5 tool calling in Ollama has a known template mismatch bug. This project uses Open WebUI's Python Tool system to reliably pass arguments to the backend.
- iframe rendering: Open WebUI aggressively sanitizes
<iframe>tags in newer versions. The tools automatically provide a clean "Open in Google Maps" Markdown link as a fallback if the map embed HTML is stripped by the UI. - Single user only: The system is designed for one concurrent user.
OLLAMA_NUM_PARALLEL=1is intentional. - Google Maps API cost: Personal use stays within the $200/month free credit. See Google Cloud Setup for quota limits.
MVP Completed (Phase 4 Reached). The system successfully integrates local Qwen3.5-9B inference with a local FastAPI mapping backend, serving place searches and directions.
See TODO.md for the history of executed phases.