Companion code for the Let's Data Science tutorial Build an On-Prem AI Agent with Actian VectorAI DB. Shiftbook is a local warehouse shift-handover agent. It retrieves the procedure and records that apply to one site, equipment version and task, shows its sources, drafts a short brief with a local model and saves a note to memory only after a person approves it.
All warehouse records are synthetic. Nothing here operates equipment, releases a carton or represents a real warehouse policy.
Read the full tutorial on Let's Data Science: Build an On-Prem AI Agent with Actian VectorAI DB. Model weights and local credentials are not included.
| Path | What you run |
|---|---|
| One file | quickstart/shift_memory.py: load, scoped search, approved memory and restart. No language model. |
| Full application on Linux | Local Ollama inference plus the complete retrieval, review, approval and memory workflow. |
| Full application on Apple Silicon | The same workflow, with local MLX inference. |
Use Python 3.11, Docker and SDK actian-vectorai-client==1.0.3. The pinned
VectorAI DB image is release 1.0.3, build 8d222ff5; Docker selects the image for
your CPU architecture. Actian lists 8 GB RAM minimum (16 GB or more recommended)
and 10 GB disk minimum (100 GB or more recommended) for the database. The local models and Python environment
need additional disk and memory. The Linux CPU test ran in an 8 GiB Docker VM;
16 GiB or more is a sensible starting allocation for the complete demonstration,
not a load-tested production sizing recommendation.
See quickstart/README.md. This path does not require Ollama or MLX.
Both full-application paths create their Python environment with
uv. If it is not installed,
run curl -LsSf https://astral.sh/uv/install.sh | sh or pipx install uv first.
Install Ollama using its official Linux instructions.
Keep its service bound to localhost (127.0.0.1:11434). Download the local model
once, while connected:
ollama pull qwen3:4b-instruct
uv venv --python 3.11
uv pip install --python .venv/bin/python -r requirements-core-linux.txt \
--extra-index-url https://download.pytorch.org/whl/cpu --index-strategy unsafe-best-match
.venv/bin/python -m scripts.download_models --embeddings-onlyThe app checks that the installed model's digest is
0edcdef34593eac1aa2be9c7d06c432dcf81945adca5eca2f27662c18f168ba0
(Qwen3 4B Instruct, Q4_K_M, approximately 2.5 GB). A missing or changed model
stops generation; a query never downloads a model or falls back to the cloud.
For a deliberate model change, set both SHIFTBOOK_OLLAMA_MODEL and
SHIFTBOOK_OLLAMA_DIGEST after reviewing the new local model and rerunning the
checks. Different runtimes and quantizations can produce different drafts.
If the tutorial's vectorai quickstart container is still running, stop only
that container (docker stop vectorai). Its volume keeps the quickstart data.
Then start this repository's separate database and enable its authentication:
docker compose -p lds-shiftbook up -d
.venv/bin/python -m scripts.wait_database
cp .env.example .env # only if no private .env exists yet
.venv/bin/python -m scripts.configure_auth
.venv/bin/python -m scripts.generate_data
.venv/bin/python -m scripts.ingest
SHIFTBOOK_MODEL_BACKEND=ollama .venv/bin/python -m uvicorn app.server:app --host 127.0.0.1 --port 8077Open http://127.0.0.1:8077/app. Ollama must remain running locally.
Authentication setup is explained in docs/AUTHENTICATION.md.
Do not stop unrelated services to free a port.
uv venv --python 3.11
uv pip sync --python .venv/bin/python requirements-macos-arm64.lock.txt
.venv/bin/python -m scripts.download_models
docker compose -p lds-shiftbook up -d
.venv/bin/python -m scripts.wait_database
cp .env.example .env # only if no private .env exists yet
.venv/bin/python -m scripts.configure_auth
.venv/bin/python -m scripts.generate_data
.venv/bin/python -m scripts.ingest
SHIFTBOOK_MODEL_BACKEND=mlx .venv/bin/python -m uvicorn app.server:app --host 127.0.0.1 --port 8077Open http://127.0.0.1:8077/app. Models are downloaded explicitly during setup;
normal operation loads local files. The API key stays in the Python process.
scripts.ingest prints 60 source records, 48 knowledge points and 12 memory points. Running it again keeps the same counts because point IDs are stable.
scripts.evaluate should report, for the original 60-record corpus:
- without filters: 14 of 72 returned sources in the expected sets, 0 of 12 complete sets;
- with filters: 32 of 32, 12 of 12 complete sets and 12 of 12 proceed or stop decisions.
Run it before you approve your own notes. Every approved note can change later results.
scripts.verify_core checks idempotent loading, filter placement (32 of 32 needed records with the filter inside the search, 14 of 32 when the same filter is applied afterwards to the top results), an approved memory write, payload updates and export with restore. It removes its test note and fixture collections. Add --restart-container NAME to restart a dedicated test container and read the note from a fresh process. Do not point it at a database someone else is using.
scripts.verify_runtime and scripts.verify_local_only exercise the configured
local model on Linux/Ollama or Apple Silicon/MLX. verify_runtime does not restart
anything by default. Pass --restart-container NAME only when intentionally
checking a dedicated test database. Optional egress probes are enabled with
--probe-egress-container NAME; do not run these against an unrelated service.
.venv/bin/python -m scripts.evaluate
.venv/bin/python -m pytest -q
.venv/bin/python -m scripts.verify_core
.venv/bin/python -m scripts.verify_runtime
.venv/bin/python -m scripts.verify_local_onlyFor isolated verification, SHIFTBOOK_STATE_DIR selects a separate local cache
and workflow state directory; SHIFTBOOK_ARTIFACTS_DIR selects a receipt directory.
These settings do not change the VectorAI DB endpoint or erase database data.
Saved baseline receipts retain their original dates and SDK versions.
The tutorial's interactive figures read article/v2/shiftbook-evidence.json, so they work for readers who have installed nothing. scripts.build_article_evidence builds that file from the synthetic corpus, cached local embeddings and the recorded receipts. It refuses to write the file unless its similarity simulation reproduces every recorded VectorAI DB ranking exactly.
.venv/bin/python -m scripts.build_article_evidence \
--run mac=artifacts/evaluation.json --run linux=artifacts/v2/evaluation-linux-x86_64.json| Path | Purpose |
|---|---|
quickstart/ |
The one-file version and its instructions. |
app/store.py |
Collections, upserts, filters, payload updates, export and restore. |
app/ingestion.py |
Markdown, JSON and SQLite adapters with stable provenance. |
app/embedding.py |
Local embeddings, token-limit checks and a disk cache. |
app/agent.py / app/inference.py |
Source checks and approval, with explicit local MLX or Ollama inference. |
app/server.py |
Loopback-only web application. |
data/ |
Synthetic sources and the 12 fixed scenarios. |
scripts/ |
Setup, ingestion, audit, verification, packaging and article evidence. |
tests/ |
Behavioral tests against the local database. |
artifacts/ |
Receipts from the Mac runs. artifacts/v2/ holds the Linux receipts. |
article/v2/ |
Saved evidence behind the tutorial's interactive figures. |
app/config.py sets AS_OF_DAY = 20260926. New approved notes expire seven days after that fixed date, on October 3, 2026. Retrieval also uses the fixed date, so passing real calendar time does not age notes out. This keeps the supplied scenarios reproducible. A shared deployment must use an explicit clock and retention policy; changing the date requires reviewing the fixtures and rerunning the audit.
The base corpus is 60 vectors, and each approved note adds one. The application stops at 500 vectors. Actian's Community signup includes a free 30-day trial for up to one million vectors. The original small-corpus run used the no-key Community capacity (5,000 vectors); this demonstration does not need the trial's larger capacity. Check the current signup terms rather than treating the trial allowance as a permanent free limit.
The database and application bind to 127.0.0.1. Follow the authentication step;
its teaching key has broad database permissions for collection management and
verification. Shiftbook itself remains a trusted-user local UI, not a multi-user
security boundary.
Actian engineering has explained that the database attempts a deployment-count ping at startup and every 30 days. It cannot be disabled. They state that it does not control licensing or functionality, and that an unreachable ping endpoint in an air-gapped environment does not affect operation. This is the vendor's explanation, not a packet-capture or air-gap certification. Images and model files still require an initial download or approved offline transfer. The Python audit guard and Docker network controls have narrower, explicit verification limits; see SETUP.md.
Keep the Docker volume when you stop the demo:
docker compose -p lds-shiftbook stopDo not use docker compose down -v unless you intend to delete this demo's database and memory.
Ownership and reuse follow the parties' written agreement. This repository does not grant an open-source license. Third-party packages keep their own licenses and are installed from their publishers. Model weights are downloaded from their official repositories and are not included. Web fonts include their OFL notices under web/assets/licenses.