Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

36 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ• Local Restaurant Review Intelligence

CI Python 3.11+ Streamlit License: MIT

A local-first review-intelligence application powered by Ollama and embedded ChromaDB. Explore the bundled restaurant dataset or map almost any review CSV, then filter the evidence and ask grounded questions with validated source citations.

By default, runtime review data, embeddings, and prompts are processed by embedded Chroma and Ollama on the same machine. If OLLAMA_HOST points to another computer or hosted endpoint, prompts and retrieved review excerpts are sent there. Installing dependencies and downloading models also use the network.

Review-intelligence dashboard showing 123 reviews, rating metrics, a five-star distribution chart, a review table, and the grounded-question input

The bundled dataset in its populated dashboard state: adaptive metrics, rating distribution, review evidence, and the question surface in one view.

Highlights

  • Visual dashboard: adaptive metrics, distribution charts, rating/date/category filters, a review browser, and a grounded-question surface.
  • Validated citations: short evidence citations map strictly to stable retrieved source IDs; an invalid or premature-abstention response gets one bounded correction attempt, then invented or missing citations fail safely.
  • Safe offline state: analytics still load when Ollama is unavailable, while the app shows exact setup commands instead of crashing.
  • Adaptive CSV upload: automatically detect common headers, manually map unfamiliar names, and isolate every dataset in content-addressed Chroma storage.
  • Reconciled indexing: content-derived IDs survive reordering; additions, changed records, and deletions are synchronized safely.
  • Measured RAG: a versioned 30-case evaluation across nine answerable domains plus abstention compares semantic retrieval with a deterministic BM25 keyword baseline, then measures citation validity, a transparent reference-term support proxy, expected-action accuracy, answer success, and abstention recall.
  • Installable CLI: the packaged local-ai-agent command exposes status, ask, chat, and evaluate workflows.
  • Local execution by default: Ollama handles embeddings and answer generation unless a remote host is explicitly configured.

See the architecture diagram and boundary notes.

Live workflow demo

Watch the silent 48-second dashboard demo. It shows the real local question trigger, indexing state, generated answer, validated citations, and an expanded source record using the bundled dataset.

Requirements

  • Python 3.11 or newer
  • uv
  • Ollama for semantic indexing, questions, and evaluations; the analytics dashboard still works without it
  • Enough local memory and disk space for the selected models

Quick start

1. Clone and install

git clone https://github.com/dk3yyyy/local_AI_agent.git
cd local_AI_agent
uv sync

2. Start Ollama for semantic questions

The Ollama desktop application starts the service automatically on supported systems. For a manual or headless installation, run:

ollama serve

Keep that process running in another terminal.

You can skip this step for an analytics-only dashboard preview. Metrics, filters, charts, and review browsing remain available while the question input shows the model setup required.

3. Download the required models

ollama pull mxbai-embed-large
ollama pull llama3.2
Model Purpose
mxbai-embed-large Creates embeddings for semantic review retrieval
llama3.2 Generates answers from retrieved review evidence

Model downloads can be several gigabytes. The application never downloads them silently.

4. Launch the dashboard

uv run streamlit run dashboard.py

Open the local URL printed by Streamlit, usually http://localhost:8501.

The dashboard can immediately display dataset metrics and reviews. AI questions are enabled only after Ollama and both required models pass the health check.

Dashboard workflow

  1. Use the bundled 123-review dataset or upload a CSV.
  2. Confirm the suggested column mapping. Only review text is required.
  3. Filter by any mapped ratings, dates, sentiments, restaurants, or countries.
  4. Review the adaptive metrics, distribution chart, and matching rows.
  5. Ask a question and expand the source records beneath the answer.

Common headers are detected automatically, including:

Role Examples
Review text Review, Review Text, Feedback, Comment, Body
Title Title, Review Title, Headline, Subject
Date Date, Review Date, Published On, Created At
Rating Rating, Stars, Score, Review Score
Sentiment Sentiment, Polarity, Label
Restaurant Restaurant Name, Restaurant, Venue, Business
Country Country, Nation, Market, Region

For unfamiliar names, select the role manually in the mapping panel. Unmapped columns are preserved as source metadata and included in indexed context. A dataset such as this works without a rating column:

Country,Restaurant Name,Sentiment,Review Title,Review Date,Review

Review text cannot be empty. Mapped ratings must be integers from 1 through 5, and supplied mapped dates must be valid. Uploads are limited to 10 MB.

Terminal commands

Check the dataset, Ollama service, and required models without starting indexing:

uv run local-ai-agent status

Ask one question:

uv run local-ai-agent ask "What do guests say about the crust?"

Start an interactive terminal session:

uv run local-ai-agent chat

Run the measured RAG evaluation against the configured local models:

uv run local-ai-agent evaluate

Write a reproducible machine-readable report and a Markdown summary:

uv run local-ai-agent evaluate --report-dir evaluation/results/my-run

The versioned case manifest is tied to the dataset SHA-256 and uses immutable content-derived source IDs for gold relevance. The report records model tags and immutable Ollama digests, dataset and case-set hashes, retrieval limit, runtime versions, per-case RAG and BM25 rankings, and aggregate metrics. Report schema v3 additively extends v2 with answer diagnostics; consumers should branch on schema_version before reading those fields. Each RAG observation records the initial and final structured validation reasons and whether a repair was attempted. Raw initial and repair model responses are omitted by default; pass --include-raw-responses only when those diagnostics are needed. The CLI and dashboard continue to expose only validated answers or safe fallback messages. Raw model responses may echo source review text, so treat opted-in evaluation artifacts as potentially sensitive and review or redact them before sharing or committing. Retrieval quality is reported as recall@k, hit rate@k, and MRR@k for both semantic search and the BM25 baseline. Relevance judgments are known-positive, not exhaustive. The generated report is evidence for this fixed benchmark configuration, not a claim about general RAG performance.

The original source-tree command remains available for development:

uv run python main.py

Use --help on the main command or a subcommand to see model, host, dataset, rating, date, sentiment, restaurant, country, and evidence-limit options. The CLI auto-detects recognized aliases; use the dashboard mapping panel for unfamiliar column names.

Configuration

The defaults can be changed through command options, dashboard controls, or these environment variables:

Variable Default
OLLAMA_HOST http://localhost:11434
CHAT_MODEL llama3.2
EMBEDDING_MODEL mxbai-embed-large
LOCAL_AI_STORAGE_ROOT ~/.local/share/local-ai-agent

Storage and indexing

Every normalized review receives a content-derived source ID. The dataset fingerprint is calculated from the sorted record digests, so row reordering does not create a new dataset. The fingerprint automatically derives both the Chroma database directory and collection name under LOCAL_AI_STORAGE_ROOT.

Validated uploads are retained under <storage-root>/uploads/. Their embedded Chroma databases live under <storage-root>/chroma/<dataset-fingerprint>/. Identical content and mapping reuse storage; changed datasets are isolated automatically.

On startup, reconciliation compares desired content IDs with Chroma. New IDs are embedded, changed records receive new IDs, and stale IDs from deleted or changed records are removed. Interrupted embedding runs retry the records that are still missing.

To remove local application data and indexes, stop the application and delete the configured LOCAL_AI_STORAGE_ROOT. This deletes local indexes and retained uploads; it does not remove Ollama models.

Tests and quality checks

Run the complete test suite:

uv run python -m unittest discover -s tests -v

The suite covers:

  • schema alias detection and manual column mapping;
  • optional rating, date, sentiment, restaurant, and country fields;
  • content-derived IDs and order-independent dataset fingerprints;
  • Chroma recovery plus addition, change, and deletion reconciliation;
  • automatic database and collection isolation;
  • adaptive rating, date, and categorical filtering;
  • Ollama health states;
  • evidence-alias-to-source citation validation and model abstention;
  • the 30-case evaluation set, BM25 baseline, retrieval metrics, and decomposed answer, citation, support-proxy, and abstention metrics;
  • evaluation-report serialization and credential-safe provenance;
  • deterministic upload storage;
  • Streamlit rendering without Ollama.

Run the same quality gates used by CI:

uv run --with coverage==7.13.4 coverage run -m unittest discover -s tests -v
uv run --with coverage==7.13.4 coverage report
uv run --with mypy==1.18.2 mypy
uvx --from ruff==0.16.1 ruff check .
uvx --from ruff==0.16.1 ruff format --check .
uv export --frozen --no-dev --format requirements-txt \
  --no-emit-project -o /tmp/runtime-requirements.txt
uvx --from pip-audit==2.10.1 pip-audit \
  -r /tmp/runtime-requirements.txt --progress-spinner off \
  --ignore-vuln CVE-2026-45829

GitHub Actions tests Python 3.11 and Python 3.14 and reports coverage for all six core Python modules, including evaluation.py. On Python 3.11 it also runs static typing, Ruff, formatting, the runtime-dependency audit, package build, and an installed-CLI smoke test. Coverage remains visible without an arbitrary pass threshold.

Project layout

.
β”œβ”€β”€ agent.py                         # Answer generation and source-ID validation
β”œβ”€β”€ dashboard.py                     # Streamlit review-intelligence dashboard
β”œβ”€β”€ dashboard_support.py             # Validated, content-addressed CSV uploads
β”œβ”€β”€ evaluation.py                    # RAG evaluation runner and metrics
β”œβ”€β”€ main.py                          # Status, ask, chat, and evaluate CLI
β”œβ”€β”€ ollama_health.py                 # Ollama and model preflight checks
β”œβ”€β”€ vector.py                        # Validation, identity, reconciliation, and retrieval
β”œβ”€β”€ local_ai_agent/                  # Installed entry point and packaged data
β”‚   └── data/rag_cases.json          # Curated RAG evaluation set
β”œβ”€β”€ docs/architecture.md             # Architecture and privacy boundaries
β”œβ”€β”€ docs/architecture.svg            # Editable architecture diagram
β”œβ”€β”€ evaluation/results/               # Versioned JSON and Markdown benchmark reports
β”œβ”€β”€ SECURITY.md                       # Reporting policy and scoped risk acceptance
β”œβ”€β”€ tests/                            # Unit, integration, evaluation, and dashboard tests
β”œβ”€β”€ pyproject.toml
└── uv.lock

Dependency audit

ChromaDB is declared directly at the newest PyPI release verified during this update (1.5.9). pip-audit still reports PYSEC-2026-311 / CVE-2026-45829, and the advisory currently lists no fixed release. It concerns an unauthenticated Chroma HTTP server endpoint that accepts trust_remote_code; this application uses embedded Chroma and does not start that server. CI ignores only this finding and fails on every other known vulnerability. The scope and removal conditions are documented in SECURITY.md.

Current limitations

  • Semantic questions and measured evaluations require a reachable Ollama service and both configured models.
  • Browser uploads remain limited to 10 MB. Large datasets require a future chunked/local-path ingestion path rather than merely increasing Streamlit's limit.
  • Rating, date, sentiment, restaurant, and country filters are applied after semantic ranking. This is suitable for small local datasets but not optimized for very large collections.
  • Automatic mapping is conservative. Unfamiliar or ambiguous headers require confirmation in the dashboard.
  • Sentiment labels are displayed and filtered as supplied. The application does not infer sentiment when the dataset lacks a sentiment column.
  • The reference-term support proxy checks expected terms against answers and cited source text; it is not an LLM judge or proof that every claim is correct.
  • Topic modeling, hybrid keyword retrieval, and reranking are not implemented.
  • The application does not provide authentication or multi-user isolation and should not be exposed directly as a shared public service.

License

Licensed under the MIT License.

About

A Python-based AI agent that processes and analyzes restaurant reviews using vector embeddings and local language models.

Topics

Resources

Security policy

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages