aws-samples/sample-agentic-data-governance
GitHub: aws-samples/sample-agentic-data-governance
通过四层治理上下文消融实验证明数据 Agent 准确率来源于治理产物而非 Agent 循环本身的可运行演示项目。
Stars: 1 | Forks: 0
# Agentic 数据治理 —— 上下文阶梯
这是一个可运行的演示,旨在说明对于那些在杂乱企业数据上回答问题的数据 agent 来说,**agent 循环只是一种轻量级的通用组件,而准确性则来源于你输入给它的治理上下文**。该仓库包含一个固定的约 250 行代码的 agent、四个累积的治理上下文层,以及一个评估流水线,用于精确测量在开放 [BIRD benchmark](https://bird-bench.github.io/) 的两个数据库上,每一层到底有多大价值——并使用 BIRD 自有的 Execution Accuracy (EX) 指标进行评分。
我们的重点不在于排行榜性能。我们的重点在于一种你可以直接复制到自己数据上的治理方法论:对数据进行画像、编写一个小型字典、将高风险的指标封装在语义层中、将失败模式提炼为技能,并通过消融阶梯来证明其效果提升。
## 核心结果
170 个问题(BIRD dev,`financial` + `debit_card_specializing`),在每个层级使用相同的 agent 代码,严格的 Execution Accuracy:
| 层级 | 注入的治理上下文 | Claude Sonnet 5 | Claude Opus 4.8 |
|---|---|---:|---:|
| **L0** | 仅包含裸 schema | 47.1% | 51.8% |
| **L1** | + 数据字典 | 39.4% | 48.8% |
| **L2** | + 语义层(可调用指标) | 43.5% | 55.9% |
| **L3** | + 技能 + 挖掘出的知识 | **67.6%** | **70.6%** |
四个值得你关注的发现:
1. **约 52 KB 的治理产物带来了约 20 个百分点的提升。** 技能层在两个数据库中大小为 14.2 KB;单个数据库完整的 L3 上下文不到 35 KB,大约仅占模型上下文窗口的 1%。
2. **这种提升经受住了泄漏审计。** 移除唯一一个从评估问题中派生出的产物(挖掘出的 `knowledge/` 文件)仅导致了 1.8/3.5 pp(Sonnet/Opus)的损失。技能规则仅从训练集中挖掘;训练集和测试集的准确率同步上升(Sonnet 训练集 46.2→71.2,测试集 48.1→70.4),没有任何过拟合的迹象。
3. **将字典直接堆砌到上下文中反而会使情况变糟。** L1 将 Sonnet 5 的准确率从 47.1% 下降到了 39.4%。文档只有在语义层和技能对其使用方式施加了约束之后才能带来收益——这是对“治理 = 把文档堆进 RAG”的直接反例。
4. **治理红利超过了模型层级的差距。** 具备完整治理的 Sonnet 5(67.6%)击败了在裸 schema 下的 Opus 4.8(51.8%);在 L3 层级,这两个模型仅相差 3 pp。在这份数据上,投入到治理层的预算比投入到模型升级的预算回报更高。
## 治理究竟起了什么作用 —— 一个问题,四个层级
理解这个仓库最快的方法是观察一个真实的评估问题是如何在四个上下文层级中流转的。下面图表中的所有内容均逐字摘自该仓库:schema、字典条目、指标定义、技能规则,以及 agent 在每个层级实际生成的 SQL。
### L0 → L1:将约定记录下来
在 L0 层级,agent 只能看到原始 schema,因此它做出了一个看似合理但错误的猜测——它无法知道 `Consumption` 中保存的是年化数值。L1 增加了一条经过人工审核的字典条目来声明该约定,这个问题随即被纠正:

注意右侧的判定结果:问题虽然被修复了,但**总体准确率却下降了**(Sonnet 5 上 47.1% → 39.4%)。将松散的文档堆砌到上下文中也会增加噪音——这正是上文提到的发现 3,也是接下来两个层级存在的原因。
### L2:将约定编译为可调用的指标
字典条目只是模型可能遵循也可能不遵循的建议。而语义层将其转化为了代码:`/12` 现在存在于 agent 调用的一个命名指标内部,因此在构造上,每个调用者都会应用相同的约定。

### L3:将诊断出的失败提炼为技能
到了 L2,约定错误已经被处理了,但仍然存在另一类错误:即那些*逻辑*正确但*输出格式*错误的查询——比如多了一列、缺少了 DISTINCT——严格的 Execution Accuracy 会将其评分为零。技能就是从这些诊断出的失败中挖掘出的小型规则。在从 L2 到 L3 恢复的问题中,约有 60% 是格式修复,而不是新的逻辑:

这就是整个阶梯的全貌:L1 记录下了领域知识,L2 将高风险的约定编译成可调用的指标,L3 将诊断出的失败转化为可重用的规则。产物总计:在两个数据库中约 52 KB——每个问题注入的上下文不到 35 KB,大约仅占模型上下文窗口的 1%。
## 流水线的工作原理

该流水线包含三个阶段——数据设置、agent 循环和评分——外加一个治理产物层,该层会输入到流水线的中段。完整流程如下:
### 阶段 1 —— 数据设置(`scripts/setup_data.sh`,运行一次)
1. 从官方来源下载 BIRD dev 数据集(约 330 MB)并解压 SQLite 数据库(`financial`、`debit_card_specializing`)。
2. `governance/extract_knowledge.py` 从中派生出两个本地产物:`eval/trading_eval.json`(包含 170 个评估问题及 gold SQL 的评估子集)和 `governance/knowledge/.md`(从 BIRD 的 `evidence` 字段中挖掘出的业务规则——这些是原始 schema 中缺失的制度化知识)。
3. 一个无 LLM 的自检程序会确认每一条 gold SQL 都能成功执行并与自身 100% 匹配,因此任何后续的准确率下降都归因于 agent,而不是测试框架。
### 阶段 2 —— agent 循环(`agent/run.py`,在每个层级固定不变)
对于每一个问题,`eval/run_eval.py` 都会使用一个 **level** 参数来调用 agent。agent 的代码永远不会改变;层级仅控制 `agent/context.py` 如何将内容组装进 prompt:
| 层级 | 注入的上下文(累积) | 来源 |
|---|---|---|
| L0 | 仅表名/列名 | 对 SQLite 数据库执行实时的 `PRAGMA` |
| L1 | + 数据字典:解码的代码、单位、数据质量说明 | `governance/dictionary/.yaml` |
| L2 | + 语义层:agent 可调用的命名受管指标 | `governance/semantic/.yaml` |
| L3 | + 执行技能(路由、输出格式化、join 约定)以及挖掘出的业务知识 | `governance/skills/*.md`、`governance/knowledge/.md` |
然后,agent 使用恰好两个工具针对 Claude 最多运行 6 轮:`call_metric` 执行来自语义层中预定义的指标(受控路径——诸如“月度 = 年度 / 12”的约定已被内置于 SQL 模板中);`run_sql` 是只读的 SQLite 回退方案,用于处理语义层未涵盖的所有内容。它最终确定的 SQL 即为预测结果。
### 阶段 3 —— 评分与分析
4. `run_eval.py` 使用 BIRD 的 **Execution Accuracy (EX)** 对每个预测进行评分:预测的 SQL 和 gold SQL 都在同一个数据库上执行,并且只有当结果集作为与顺序无关的多重集匹配时,预测才被判定为正确。一个较宽松的诊断指标(`correct_soft`)也会将那些包含 gold 答案但带有额外列或重复行的结果标记为通过——这两者之间的差距可以将“错误逻辑”与“逻辑正确但输出格式错误”区分开来。每个层级的记录都会保存在 `eval/results*/.json` 中。
5. `eval/analyze_cmp.py` 将两个模型 x 四个层级聚合成一个 JSON:准确率阶梯、按问题划分的网格、层级间的转换(每一层获得/丢失了哪些问题)、带有 SQL 对的共性失败案例,以及两个泄漏审计模块(知识移除消融、训练集/测试集划分检查)。
由于 agent 是冻结的,且各层级是累积的,因此该阶梯是一个纯净的消融实验:任意两个层级之间的准确率差异都是由其间添加的治理产物引起的——这就是整个测量设计的核心。
## 仓库结构
```
agent/ the thin agent (run.py), context assembly, semantic layer
governance/
dictionary/.yaml curated data dictionary (human-owned)
semantic/.yaml metric definitions with conventions baked in
skills/*.md distilled execution skills (one rule per diagnosed failure)
profile.py machine profiling of a raw database
extract_knowledge.py mines BIRD `evidence` fields into knowledge/*.md + eval set
eval/
run_eval.py ablation runner, BIRD EX scorer, ladder report
analyze_cmp.py two-model comparison, transitions, leakage-audit blocks
split_train_ids.json train/test split used for the generalization check
scripts/setup_data.sh downloads BIRD dev data and builds local artifacts
```
BIRD 数据及从中派生出的所有内容(`data/`、`eval/trading_eval.json`、`governance/knowledge/`)**均未**被提交——`setup_data.sh` 会在本地从官方下载中重新生成它们。
## 快速开始
前置条件:Python 3.10+、`curl`、`unzip`、约 2.5 GB 磁盘空间。
```
pip install -r requirements.txt
# 下载 BIRD dev 数据(约 330 MB)并构建 eval set + knowledge files。
# 以无 LLM 自检结束:每条 gold SQL 都能执行并自比较。
bash scripts/setup_data.sh
# 配置 auth(任选一种路径):
export ANTHROPIC_API_KEY=sk-ant-... # Claude API
# 或 Amazon Bedrock:
export CLAUDE_CODE_USE_BEDROCK=1 AWS_REGION=us-west-2
# Smoke run —— 20 个问题,两个级别(约 2 分钟,花费几美分):
python3 eval/run_eval.py --levels L0_bare L3_skills --db financial --sample 20 \
--model claude-sonnet-5 # Bedrock: global.anthropic.claude-sonnet-5
# 完整 ladder,单个 model(约 170 个问题 x 4 个级别):
python3 eval/run_eval.py --levels L0_bare L1_dict L2_semantic L3_skills \
--model claude-sonnet-5 --concurrency 8 --results-dir eval/results_sonnet5
# 比较两个 model 并生成分析 JSON:
python3 eval/analyze_cmp.py \
--a-name "Claude Sonnet 5" --a-dir eval/results_sonnet5 \
--b-name "Claude Opus 4.8" --b-dir eval/results_opus48 \
--out analysis.json
```
在 Bedrock 跨区域推理上,一次完整的 2 个模型 x 4 个层级 x 170 个问题的比较总成本约为 5 美元。
## 将此适配到您自己的数据
这里的治理产物并不是一次性写就的。它们源自一个五步循环,您可以在任何数据库上重复运行该循环:
1. **画像** —— `governance/profile.py` 扫描原始数据库:null 率、编码值、可疑的列名。
2. **字典** —— 将画像结果转换为 `dictionary/.yaml`。每一条目由人工负责维护;不确定的条目会被标记为 `status: draft`。
3. **基线** —— 在 L0/L1 上运行评估,以查看模型在编写任何技能*之前*会在哪里出错。
4. **错误剖析** —— 阅读失败案例。每一个被诊断出的失败类别都会在技能文件中成为一条规则,并标记上导致该错误的具体疏漏。没有任何规则是仅凭直觉加入的。
5. **泛化门控** —— 预留出一个测试集。只有当训练集和测试集的准确率同步上升时,该规则集才会发布;曾有一套过于特定的规则集在训练集上升至 65→69 的同时,测试集却下降至 69→63,随后被回滚。
通过这个循环保留下来的技能都很小。本仓库中最大的产物是 9 KB 的字典;影响最大的单个技能文件仅为 3.7 KB。
## 将治理上限与基准噪声区分开来
在 BIRD `financial` 上,纯治理的准确率在 69% 左右进入平台期(严格 EX)。逐项失败剖析显示,在剩余的失误中,约有三分之一属于 **BIRD gold-SQL 标注歧义**——即 gold 查询在几个等价的 join 路径中只选了一个、返回了额外的 id 列,或者对于 top-N 问题没有排序——这并不是治理层能够弥合的差距。真实的商业数据通常不存在这些问题:指标定义归业务方所有,因此什么是“正确”的是明确无误的。
为了证明上限是数据的固有属性,而非方法的局限,本仓库提供了一个小型的**人工编写、无歧义**的测试集(`eval/handcrafted_test.json`,25 个模仿日常客户需求的问题:每个问题都有一个清晰的定义,明确列出了返回的列,且 gold SQL 不依赖于对 join 路径的猜测)。
每一条 gold 查询都能通过可执行的 `--self-check`。使用 `--eval-set` 参数,针对同一个 agent 和治理产物运行该测试:
```
# 无 LLM sanity:每条 gold SQL 都能执行且 EX 自比较
python3 eval/run_eval.py --eval-set eval/handcrafted_test.json --self-check
# 在 clean set 上进行 ablation
python3 eval/run_eval.py --eval-set eval/handcrafted_test.json \
--levels L0_bare L3_skills --results-dir eval/results_handcrafted
```
| 测试集 | L0 裸 schema | L3 完整治理 |
|---|---:|---:|
| 人工编写,无歧义(25 Q) | 88% | **100%** |
| BIRD `financial`(54 Q,gold 有歧义) | 44% | 69% |
相同的 agent,相同的产物。在定义清晰且无歧义的数据上,受控系统能够回答每一个问题;在 BIRD 上看到的约 69% 的准确率很大程度上是该基准测试自身的标注噪声,而不是治理方法本身的极限。(n=25 的样本量只是用于概念验证的对比,并非大型基准测试——重点在于这两行之间的*差距*。)
## 注释与归属
- **BIRD benchmark**:Li et al., *Can LLM Already Serve as a Database Interface?* (NeurIPS 2023),数据采用 CC BY-SA 4.0 许可,从[官方网站](_URL_1/>)下载。本仓库未对其中的任何内容进行再分发。
- 已发表的研究表明 BIRD 中存在大量的标注噪声(例如 Wretblad et al., ACL 2024;对 Mini-Dev 数据集的专家重新标注研究)。请将绝对的 EX 数值视为不同治理层级之间的比较工具,而不要当作模型能力的排名。
- 这是用于实验的示例代码。它并非生产级软件:agent 会在本地只读的 SQLite 数据库上执行模型生成的 SQL;在将其用于真实数据之前,请务必审查其访问模型。
## 安全
更多信息请参见 [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications)。
## 许可证
本库采用 MIT-0 许可证授权。请参见 [LICENSE](LICENSE) 文件。
标签:AI, DLL 劫持, Text-to-SQL, 代码示例, 大语言模型, 效果评估, 数据分析, 数据治理, 自动化代码审查, 逆向工具