# Dash: a self-learning data agent that keeps its own memory of SQL mistakes

> Agno's Dash is a Python data agent that answers questions against PostgreSQL by combining six layers of context with a learning loop. It is a reference system to read and adapt, not a package to pip install.

**agno-agi/dash** — A self-learning data agent built with systems engineering principles. It grounds answers in 6 layers of context and improves with every query.

- Repository: https://github.com/agno-agi/dash
- Website: https://agno.com
- Stars: 2,265 · Forks: 253
- Language: Python
- License: Apache-2.0
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/agno-agi-dash

## The problem Dash attacks: an LLM writing SQL against a schema it cannot understand

A language model asked "Which plan has the highest churn rate?" has no idea what a plan is, which column encodes churn, or whether the company counts a cancelled trial as churn. The README states the failure mode plainly: schemas lack meaning, types are misleading, tribal knowledge is missing, there is no way to learn from mistakes, and results lack interpretation. That list is the design brief.

Dash is for teams that already have a PostgreSQL warehouse and want the agent to answer in English against it. It is not a BI replacement and it is not a general chatbot. The intended reader is an engineer who is willing to run a Docker stack, load their own knowledge files, and treat the agent's SQL as something to audit. The repository is a working system with an evaluation directory and a knowledge directory, not a published library: pyproject.toml declares the package name as dash with version 1.0.0, but the README's install path is git clone plus docker compose, never pip install.

## How Dash works: a coordinating team, two agents, and a dual-schema boundary

The entry point is AgentOS in app/main.py, started with scheduler=True and tracing=True. It runs FastAPI and Uvicorn, optionally a Slack interface, and a Dash Team defined in dash/team.py in coordinate mode. The team has two members with different database privileges.

The Analyst in dash/agents/analyst.py reads the public schema with read-only SQLTools, can call introspect_schema against both schemas, can call save_validated_query to write into the knowledge base, and has ReasoningTools. The Engineer in dash/agents/engineer.py reads public but writes only to the dash schema with full SQLTools; it can call introspect_schema and update_knowledge when schemas change. The leader carries SlackTools when Slack is configured. Knowledge lives in a dash_knowledge table holding schemas, queries, business rules and dash views. Learnings live in dash_learnings, holding error patterns, type gotchas and fixes.

The six context layers are concrete files and tools, not a marketing list. Table usage comes from knowledge/tables/*.json. Human annotations come from knowledge/business/*.json. Query patterns come from knowledge/queries/*.sql. Institutional knowledge arrives over MCP and is optional. Learnings come from the Agno Learning Machine. Runtime context comes from the introspect_schema tool. The self-learning loop runs a question through retrieval, reasoning, SQL generation and execution; on error the agent diagnoses, fixes, and saves a learning so the same mistake is not repeated, and on success the query can optionally be saved as knowledge.

The dual-schema split is the part worth stealing even if you never run Dash. public is owned by the company and loaded externally; agents never modify it. dash is owned by the Engineer agent and holds views and summary tables. That gives you a structural guarantee rather than a prompt instruction, which is a stronger position than telling a model to please not run DELETE.

## Quick start: clone, compose up, then generate data and load knowledge

The README's quick start assumes Docker and an OpenAI key. Clone the repository and create the environment file first.

```bash
git clone https://github.com/agno-agi/dash.git && cd dash
cp example.env .env
```

Edit .env and add OPENAI_API_KEY. Then build and start the stack. compose.yaml defines two services: dash-db on the agnohq/pgvector:18 image, and dash-api built from the Dockerfile, running uvicorn app.main:app on port 8000 with the source mounted at /app.

```bash
docker compose up -d --build
```

The API container waits for the database because WAIT_FOR_DB is set to True, and it connects using DB_HOST=dash-db, DB_USER=ai, DB_PASS=ai and DB_DATABASE=ai unless you override them. Once it is up, load the sample dataset and the knowledge base from inside the container.

```bash
docker exec -it dash-api python scripts/generate_data.py
docker exec -it dash-api python scripts/load_knowledge.py
```

The README says to confirm the service at http://localhost:8000/docs. To use the web UI, open os.agno.com, log in, choose Add OS, Local, enter http://localhost:8000, and click Connect. The README's own test questions against the SaaS metrics dataset are: What's our current MRR? Which plan has the highest churn rate? Show me revenue trends by plan over the last 6 months. Which customers are at risk of churning?

Deployment to Railway is a separate path. You copy example.env to .env.production, run railway login and ./scripts/railway_up.sh, then generate a JWT key pair in AgentOS and place the public key in .env.production as JWT_VERIFICATION_KEY wrapped in single quotes. The README warns that the app crash-loops until that key is added. Then ./scripts/railway_env.sh pushes the environment and ./scripts/railway_redeploy.sh restarts the service. Database scripts must run inside Railway's network via railway ssh --service dash, because the internal hostname pgvector.railway.internal is not reachable from a laptop.

## Where Dash breaks: OpenAI only, a crash-looping first deploy, and no published package

The dependency list in pyproject.toml pins agno[os]==2.7.0 and openai, and no other model provider appears in the dependencies. If your organisation cannot send schema text and query results to OpenAI, the current architecture has no documented alternative path. That is a hard constraint, not a configuration detail.

Railway deployment has a known rough edge that the README admits: the first ./scripts/railway_up.sh leaves the service crash-looping until JWT_VERIFICATION_KEY is generated in AgentOS and pushed. Anyone treating that script as a one-shot deploy will spend time reading logs that only say the app exited.

There is also no package to depend on. pyproject.toml declares a project named dash with a setuptools build backend, but the README never shows pip install or uv add. The Dockerfile copies requirements.txt and runs uv pip sync --system, so the supported consumption model is the repository itself. If you wanted to embed Dash's learning loop inside an existing service, you would be copying modules out of dash/agents/ and dash/team.py rather than importing a stable API.

Finally, the learning loop is only as good as its storage. Learnings accumulate in dash_learnings, and the README does not document a pruning policy, a review step, or a way to roll back a bad learning. A wrong fix saved once becomes context for later queries. Nothing in the repository layout suggests an approval gate for that table.

## Dash versus a plain text-to-SQL agent or a semantic layer

The obvious alternative is a single LLM agent with a SQL tool and the schema in the prompt. That approach is simpler to stand up and has no database schema of its own. The difference in mechanism is memory: the plain agent re-derives context on every request, while Dash persists validated queries in dash_knowledge and error fixes in dash_learnings, so the second question about churn starts from a better position than the first. The cost is that Dash needs a knowledge directory populated with knowledge/tables/*.json and knowledge/business/*.json, and someone has to write those files.

A semantic layer such as a dbt-style metrics project takes the opposite route: it encodes metric definitions once, in a place humans control, and every consumer reads the same definition. Dash keeps definitions in knowledge/business/*.json too, but the agent can also add to that knowledge base through save_validated_query and update_knowledge. That is more flexible and less governed. If your organisation already treats metric definitions as reviewed artefacts, Dash's agent-writable knowledge table will feel like a second, unaudited source of truth.

## Maintenance, upgrades and what Apache-2.0 means here

The repository is not archived, and the last push was on 2026-07-10, which is roughly two months before the date of this article. That is recent enough to suggest the project is still being worked on, but the repository has no retrieved releases, so there is no tagged version to upgrade to. The declared version in pyproject.toml is 1.0.0, and the Docker image tag defaults to latest via IMAGE_TAG, which means a rebuild can pull different code than the last one.

Upgrade cost is dominated by the Agno pin. agno[os]==2.7.0 is exact, and requirements.txt lists agno==2.7.0 plus agnoctl==0.1.0, fastapi==0.135.3, pydantic==2.12.5 and sqlalchemy==2.0.49 among many others. Because the file is generated by ./scripts/generate_requirements.sh from uv, bumping Agno means regenerating it and re-testing the agent team, since agent APIs are the part most likely to shift between Agno versions.

The licence is Apache-2.0, with license-files = ["LICENSE"] in pyproject.toml. Apache-2.0 permits commercial use and modification and includes an explicit patent grant, but it also requires that you keep the licence and notice files and state significant changes. If you fork Dash into a product, the obligation is on you to preserve attribution. This is a description of the licence text, not legal advice; have your own counsel review a redistribution plan.

## Conclusion

Adopt Dash if you run PostgreSQL, already accept an OpenAI dependency, and want a working reference for grounded text-to-SQL rather than a library to import. Do not adopt it if you need a pip-installable package, a non-OpenAI model path, or a system that runs without AgentOS, because the repository is structured around the AgentOS app and a Docker Compose stack. Before committing, verify three things in your own checkout: that scripts/generate_data.py and scripts/load_knowledge.py complete inside the container, that the Analyst agent can only read the public schema, and that the dash schema is the only place the Engineer agent writes.

## FAQ

### What is agno AI?

Agno is the framework Dash is built on. Dash pins agno[os]==2.7.0 and runs inside AgentOS, Agno's app layer, which provides the FastAPI entry point, authentication and the web UI at os.agno.com.

### How do I install Dash from agno-agi?

You clone the repository, copy example.env to .env, add an OPENAI_API_KEY, and run docker compose up -d --build. There is no documented pip install path; the Dockerfile installs requirements.txt inside the image.

### Which database does Dash use for its knowledge and learnings?

PostgreSQL with pgvector, run from the agnohq/pgvector:18 image defined in compose.yaml. Knowledge is stored in the dash_knowledge table and learnings in dash_learnings, alongside the read-only public schema that holds company data.

## Sources

- [agno-agi/dash on GitHub](https://github.com/agno-agi/dash)
- [Issues](https://github.com/agno-agi/dash/issues)
- [License: Apache-2.0](https://github.com/agno-agi/dash/blob/main/LICENSE)
- [Project website](https://agno.com)
- [README](https://github.com/agno-agi/dash/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/agno-agi-dash
