srr84/agent-data-layer
Agent-Readable Data Layer
An AI agent that answers from your data — without making things up.
AI agents are useful over business data right up until they hallucinate — inventing a stock level, a store, or a number that was never in the source. This is a small, working system that removes that failure mode by construction: the agent can only reach data through a fixed set of typed, parameterized tools — never a free-form query it could fabricate — and every fact it returns comes stapled to a pointer back to the exact source record it came from. When a question falls outside what the data can answer, it abstains and says so, instead of guessing.
The guarantee is structural, not a prompt or a politeness setting — there is no path for an ungrounded answer to slip through, and that is enforced by an automated test suite on every change. It is already built and deployed live on a $0 stack, with the underlying model swappable between a local engine and a hosted one.
Want to see it answer live? The interactive question-and-answer path is a 2-minute screen-share — happy to walk through it against your data and use case.
What you're looking at
This page is the live deployment of the system. It is an infrastructure component — a typed data layer that an AI agent answers through — so this URL is its health/status surface, not a consumer chat box:
GET /healthz→200 {"status":"ok", ...}once the bundled data + index load.GET /metrics→ operational metrics as JSON.
There is deliberately no public free-text endpoint. The question-answering surface is an in-process typed tool API, exercised by the eval harness and the live demo — keeping it in-process is part of how the system stays contained.
How it guarantees it won't fabricate
- Tools only, no raw query. The agent reaches data only through a fixed, typed, parameterized tool set. There is no free-text query path for it to invent — that's a type error, not a code-review convention.
- Provenance on every fact. Every value returned is attached by code to a pointer to the exact source record. The language model selects a tool and writes prose — it never writes the value or its source.
- Abstains when it can't ground. An out-of-coverage question returns a typed "can't answer that from this data," never a fabricated one.
Run modes
- `RUN_MODE=demo_local` (the $0 path, local only): the answer path reaches a local Ollama OpenAI-compatible endpoint (
http://localhost:11434/v1, modelqwen2.5:7b-instruct). This is the 90-second local demo; it is not this Space (a remote Space cannot reach your localhost). - `RUN_MODE=deployed` (this Space): the answer path uses a hosted OpenAI-compatible endpoint via
MODEL_BASE_URL/MODEL_API_KEY/MODEL_NAME. The validator rejects alocalhost/host.docker.internalbase URL in this mode.
Under the hood
Built from the repo Dockerfile (python:3.12-slim, non-root, precomputed index baked at image-build time). The container binds $PORT → $APP_PORT → 7860 (HF Spaces convention) and runs python -m agent_data_layer.app.server. Deploy is from CI on the release path (.github/workflows/ci.yml); the same containment gates run on every change. The MODEL_API_KEY is never committed — it lives only in the Space repository secret and the CI secret store.
Source code and the full technical write-up (WALKTHROUGH / CODE_TOUR with architecture diagrams) are available on request.
