Datum

Datum

Enables natural-language querying of SQLite databases through a governed semantic layer, with citations and typed abstention for PII or uncertified data.

Category
访问服务器

README

Datum

A semantic context layer that keeps data agents honest.

Datum answers natural-language questions over a database by grounding an LLM on a governed semantic layer. It writes SQL that is validated against the schema, cites the tables and columns it used, and refuses instead of guessing when a question needs data that doesn't exist, is personal (PII), or isn't certified for analytics. It ships with an MCP server, a reliability eval harness, and unit tests for the guardrail.

A confident wrong answer is worse than no answer.


Results

Datum vs. a naive single-prompt text-to-SQL baseline, gpt-4o-mini, averaged over 3 runs. CWR = Confidently-Wrong Rate (wrong answers plus answers that should have been refused — PII, uncertified, out-of-scope) — the number a trust layer exists to minimize.

Benchmark Engine Execution Acc. ↑ Refusal Recall ↑ CWR ↓ Answer faithfulness ↑
Synthetic (30 Q) Datum 96.3% 100% 0.0% 100%
Baseline 88.9% 27.8% 35.6% 81.5%
Chinook (20 Q, real DB) Datum 92.9% 100% 0.0% —
Baseline 100% 33.3% 20.0% —

The critic + semantic layer drives confidently-wrong answers to zero and catches 100% of PII / uncertified / out-of-scope queries — without lowering execution accuracy. The baseline, by contrast, leaks PII (SELECT email FROM employees), queries uncertified tables, and even aliases AVG(csat_score) AS average_nps to answer a question about a metric that doesn't exist.

Reproduce:

python evals/run_evals.py --runs 3 --judge        # synthetic
python evals/run_external.py evals/chinook_eval.yaml --runs 3   # real Chinook DB

Why

Point an LLM at a database and it will happily invent an nps_score column, join on the wrong key, leak an email address, or return a confident number that's just wrong. Datum puts two things between the model and the data:

  1. A governed semantic layer — definitions, ownership, trust levels, metrics and PII flags — so the agent reasons over meaning, not raw table names.
  2. A deterministic critic — a real SQL parser (sqlglot, not the LLM) that blocks hallucinated columns, PII, uncertified tables and any non-read-only statement before a query ever runs.

If neither can make the question safe to answer, Datum abstains — with a typed reason.

Architecture

flowchart TD
    Q[Natural-language question] --> R[Retriever<br/>relevant semantic assets]
    R --> P[Planner<br/>answerable? which assets?]
    P -->|no| X[Abstain<br/>pii · missing · untrusted · out-of-scope]
    P -->|yes| A[SQL Author<br/>grounded SELECT]
    A --> C{Critic<br/>sqlglot guardrail}
    C -->|violations| A
    C -->|clean| E[(SQLite<br/>read-only)]
    E --> Ans[Answerer<br/>NL answer + citations]
    SM[[Semantic layer<br/>trust · PII · metrics]] -.governs.-> P
    SM -.governs.-> A
    SM -.governs.-> C

Multi-agent pipeline: Planner → SQL Author → Critic → Answerer, with a repair loop (the Critic's feedback goes back to the Author). Citations are extracted from the validated SQL's AST, so they reflect what the query actually touched.

Features

  • Grounded NL→SQL over SQLite, with citations and typed abstention.
  • Governed semantic layer (context/semantic_model.yaml): trust levels, PII flags, ownership, business metrics with reference SQL.
  • Deterministic critic (sqlglot): rejects unknown/hallucinated columns, PII columns (even hidden behind a CTE or renamed alias), uncertified tables, and non-read-only SQL.
  • Schema-linking: FK-neighbour expansion pulls join-partner tables into context.
  • Context retrieval over semantic assets — OpenAI embeddings, with a lexical fallback so the pipeline runs with no key.
  • MCP server — expose the engine to Claude Desktop / Cursor.
  • Auto-introspection adapter — build a semantic layer from any SQLite schema.
  • Reliability eval harness with a naive baseline, an LLM-as-judge faithfulness check, and multi-run averaging.
  • Unit tests for the guardrail (pytest, no API needed).

Quickstart

python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env          # add your OPENAI_API_KEY

python -m datum seed          # build the demo database
python -m datum ask "What is our monthly recurring revenue?"
python -m datum ask "List the email addresses of our account owners."   # abstains (PII)
python -m datum eval          # reliability scorecard vs baseline
pytest -q                     # guardrail unit tests (no API)

Example

$ python -m datum ask "What is our monthly recurring revenue?"
╭─ Answer ─────────────────────────────────────────────────────────╮
│ Our monthly recurring revenue is $1,241,366.00.                   │
│ Source: plans.monthly_price, subscriptions.seats                  │
╰───────────────────────────────────────────────────────────────────╯
SELECT SUM(p.monthly_price * s.seats) AS mrr
FROM subscriptions s JOIN plans p ON p.plan_id = s.plan_id
WHERE s.status = 'active'

$ python -m datum ask "List the email addresses of our account owners."
╭─ Abstained · pii ────────────────────────────────────────────────╮
│ I can't answer that because it requires personal data (PII) that  │
│ policy does not expose.                                            │
╰───────────────────────────────────────────────────────────────────╯

Benchmarks

Metrics (standard text-to-SQL + governance):

Metric Meaning
EX Execution Accuracy answerable questions whose result matched gold
RP Refusal Precision of everything it refused, how much should be refused
RR Refusal Recall of the should-refuse questions, how many it caught
CWR Confidently-Wrong wrong answers + policy leaks, over all questions (lower better)
Answer faithfulness LLM-as-judge: are the answer's numbers grounded in the rows?

Synthetic (evals/eval_set.yaml, 30 questions, deterministic DB) is the primary benchmark. Chinook (evals/chinook_eval.yaml, 20 questions) runs the same harness against the real third-party Chinook DB via schema auto-introspection.

Adding a Spider dev database (or any SQLite): the harness is dataset-agnostic. Drop the .sqlite file in benchmarks/, copy chinook_eval.yaml, point database: at it, list its pii_columns, and paste the Spider dev questions + gold SQL as items — then python evals/run_external.py evals/your_spec.yaml. (Public benchmarks ship no trust/PII labels; hand-annotating them in the YAML is exactly what the semantic layer is for.)

# fetch the Chinook demo DB used above (~1 MB)
curl -sL -o benchmarks/chinook.sqlite \
  https://github.com/lerocha/chinook-database/raw/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite

Tests

pytest -q      # 37 tests, ~0.4s, no API

The guardrail is tested directly with adversarial SQL — stacked-statement injection, write keywords hidden in comments, PII behind a renamed CTE alias, hallucinated columns, unqualified columns shared across two tables — so the "trust layer" claim is proven, not just asserted.

Use it from Claude Desktop / Cursor (MCP)

python -m datum serve starts an MCP server exposing list_certified_tables, describe_table, and ask:

{
  "mcpServers": {
    "datum": {
      "command": "/ABSOLUTE/PATH/datum/.venv/bin/python",
      "args": ["/ABSOLUTE/PATH/datum/mcp_server.py"]
    }
  }
}

Project layout

datum/
├── datum/
│   ├── db.py            # sqlite access + read-only guardrail + result compare
│   ├── seed.py          # deterministic synthetic SaaS database
│   ├── semantic.py      # loads/queries the governed semantic layer
│   ├── introspect.py    # auto-build a semantic layer from any SQLite schema
│   ├── retrieval.py     # embeddings (or lexical fallback) over assets
│   ├── agents.py        # Planner · Author · Critic · Answerer + Engine
│   ├── baseline.py      # naive single-prompt baseline (the comparison point)
│   └── cli.py           # `python -m datum ...`
├── context/semantic_model.yaml   # the governed context layer
├── evals/
│   ├── eval_set.yaml            # synthetic benchmark (incl. must-refuse questions)
│   ├── chinook_eval.yaml        # real-DB benchmark spec
│   ├── run_evals.py             # harness + baseline + faithfulness judge
│   └── run_external.py          # run the harness on any external SQLite DB
├── tests/                       # pytest guardrail suite (no API)
└── mcp_server.py                # MCP server (FastMCP)

Design notes, limitations & next steps

  • Benchmarks are small and partly self-authored (30 synthetic + 20 Chinook). They demonstrate the mechanism and the delta vs. baseline; they are not a large-scale study.
  • Single dialect. Only SQLite is implemented and tested. The design (semantic layer + AST critic) is dialect-agnostic, but porting to a warehouse dialect is future work, not a claim being made here.
  • The critic proves validity and governance, not semantic correctness. It guarantees SQL is read-only and touches only real, certified, non-PII columns; whether the query answers the user's intent is what the eval's execution accuracy measures.
  • Columns behind derived-table/CTE aliases are skipped by the critic to avoid false positives (the read-only + certified-table checks still apply).
  • Next: Spider/BIRD subsets through run_external.py; a warehouse dialect; caching embeddings; expanding the eval sets.

License

MIT

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选