开源AI4BI项目 WrenAI 解读

WrenAI 入门:从零到会用的核心机制指南

这是一篇整理了WrenAI核心工作机制的技术博客,面向刚开始接触AI4BI,AI-Databot的数据工程师,串联起这类项目结构、知识管理、技能编排和 如何保证AI写SQL正确性这几条主线。


一、WrenAI要解决什么问题

给LLM一个原始数据库schema,让它直接写SQL,常见的失败模式是:表名歧义(customers vs customers_v3)、不知道status=4是什么意思、幻觉出不存在的join。
而WrenAI的核心思路是在数据库和agent之间加两样东西:

  • 一层显式、可版本控制的语义层——MDL(Modeling Definition
    Language,一种用YAML描述Models、Relationships、Views、Cubes的语义契约,规定哪些数据集存在、暴露哪些字段、如何关联、哪些计算逻辑可复用)
  • 业务知识(knowledge/rules、knowledge/sql)

让agent只能在这层"经过审查的现实"上操作,而不是直接面对原始表 。


二、四个知识载体:MDL如何管理业务背景知识

WrenAI把知识拆成四层显式文件,全部可Git版本控制、审查、回滚:

产物内容更新方式
MDLmodels/views/relationships.yml结构与语义契约:数据是什么、如何关联、可复用的计算逻辑wren context build、手动编辑、agent提议
knowledge/rules/schema无法表达的业务规则(如软删除默认过滤条件)手动编辑或agent提议
knowledge/sql/确认过的自然语言→SQL对,一个markdown文件一对wren memory store、手动编辑
Memory index.wren/memory/基于前三者派生的检索索引(可选LanceDB,否则grep)wren memory index

关键区分:前三者是源文件,memory index是派生产物,随时可从源重建、不是真相来源 3


三、Model / View / Cube:MDL中的三种语义对象

类比关键字段
ModelSQL表或存储的SELECTtable_reference(物理表)或ref_sql(SQL SELECT)二选一,加columns
ViewSQL VIEW完整statement,schema从语句推断,可递归引用其他view
Cube预聚合语义对象(借用OLAP/维度建模词汇,不是完整方法论)base_object(model或view)+ measures/dimensions/time_dimensions

Cube的价值在于把agent最容易出错的四类问题(join错误、聚合层级错误导致重复计数、日期截断歧义、指标定义不一致)提前声明清楚,agent查询时用结构化命令wren cube query --cube revenue --measures total --dimensions status,不需要手写GROUP BY/DATE_TRUNC 7

YAML源 vs JSON编译产物

三者都用YAML写(snake_case字段),编译成target/mdl.json供引擎读取(camelCase字段,wire format) 8 。YAML是给人编辑维护的多文件结构,JSON是给Rust引擎(wren-core)消费的扁平manifest——类似TypeScript源码 vs 编译出的JS,源格式便于协作review,产物格式便于机器消费、随时可重建。


四、六个技能(Skills):agent的操作手册

WrenAI没有把"怎么用WrenAI"写死在prompt里,而是做成CLI内置、按需拉取的技能文档:

技能定位触发时机
onboarding入口技能,编排环境检查→项目脚手架→连接配置→MDL生成→首次查询用户说"set up wren"
generate-mdl一次性设置:探索数据库schema,生成初始MDLonboarding的Step 5调用;项目初始化时跑一次
usage日常查询主循环:fetch context→recall→写SQL→执行→store每次查询
enrich-context深挖业务含义(枚举值、单位、canonical表、命名指标)用户抱怨/发现新术语时按需触发,非每次查询
dlt-connector通过dlt连接SaaS数据源(HubSpot/Stripe等)到DuckDB接入新数据源时
genbi把context层转成可分享的GenBI web应用需要分享/部署时

两拍哲学:Scaffold Fast → Enrich Deep

按需触发

写入

读取

用户: set up wren

onboarding (入口)

generate-mdl (Step 5, Scaffold Fast, 一次性)

usage (每次查询循环)

用户抱怨/新术语出现

enrich-context (Enrich Deep)

MDL / knowledge/

generate-mdl只覆盖"数据库能自我描述的部分"——表结构、列类型、外键推断的关系 10 。真正的业务含义(哪张表是canonical、status=4是什么意思)活在文档、Slack、分析师的SQL里,需要enrich-context通过Grill模式(逐问题澄清确认)或Auto-pilot模式(批量读取raw/推断)补进MDL或knowledge/ 11 。两种模式都只新增、不覆盖已有字段,冲突留人工处理 12


五、usage:每次查询怎么保证准确

usage不是简单地"把问题丢给LLM生成SQL",而是一套多阶段流程:

用户提问

wren memory fetch: 检索相关model/column/relationship

wren memory recall: 检索相似历史NL-SQL对

评估复杂度

写SQL, 针对MDL model名字

复杂查询: wren dry-plan先验证

wren --sql 执行

wren memory store: 存入knowledge/sql/

定向检索而非全量塞schema

两种常见失败模式——把整个schema塞进prompt(模型被无关表干扰)、让模型自己猜哪张表相关(容易选错)——usage都不做。Memory索引MDL + knowledge/rules/ + 确认过的NL-SQL对,只检索匹配当前问题的那一小片 13

复杂度判断影响是否要dry-plan验证

  • 简单(单表、MDL已定义的简单JOIN)→ 直接执行
  • 复杂(非MDL relationships覆盖的JOIN、子查询、多步逻辑)→ 先wren dry-plan验证展开后的SQL再执行 14

这是个判断而非硬规则:“如果对单条查询有信心,可以直接执行;如果失败后难以调试,就该验证” 15


六、dry-plan:给agent一个"编译器"

这是最容易被误解的一点:agent写的SQL和最终跑在数据库上的SQL不是同一句

agent写的是"模型层SQL"

针对MDL model名字写查询,比如SELECT c_name FROM orders JOIN customer ON ...,这里的orderscustomer是MDL声明的逻辑对象,不是必然对应数据库里同名的物理表。

引擎(不是LLM)负责展开

WrenEngine.dry_plan()是纯规则化的转译管道,不涉及任何LLM推理:sqlglot解析 → 识别引用的models/columns → wren-core按MDL语义展开每个model → 注入为CTE → 生成目标方言SQL 16

真实展开例子(来自wren-core测试):用户写SELECT c_custkey, count(distinct c_name) FROM customer GROUP BY c_custkey,展开后customer被替换成多层嵌套子查询,最内层才是FROM customer AS __source真实表访问 17 。如果model有跨表计算字段,展开时会自动注入JOIN,即使用户没写;如果MDL定义了row-level policy,展开时会自动加WHERE过滤条件。

为什么"agent检查agent写的SQL"不是空转

因为检查所依据的信息不是LLM自己复述的,而是引擎解析MDL manifest后返回的确定性事实——SQL到底引用了哪些真实存在的model/column,JOIN到底展开成什么样。这类似程序员写代码后跑compiler/linter:代码是自己写的,但编译器的报错是独立于生成过程的外部反馈。如果列名写错了,dry-plan直接返回可用列名列表,agent据此重试而不是靠"自我反思" 18

dry-plan vs dry-run vs query

连接数据库?输出用途
dry-plan展开后的SQL文本转译预览,MDL层校验
dry-runOK / Error: <reason>验证SQL能否在DB上跑通,不取数据
query(真正执行)结果数据内部先跑一次dry-plan再交给connector执行

对应两层错误诊断策略:dry-plan失败 = MDL层问题(模型/列名错、缺关系);dry-plan成功但执行失败 = DB层问题(类型不匹配、权限、dialect) 20


七、整体心智模型总结

每次查询

一次性/低频

持续输入

onboarding

generate-mdl: 生成Model+Relationships

enrich-context: 补充knowledge/rules,sql,cubes

usage

memory fetch/recall: 定向检索context

写模型层SQL

dry-plan: 引擎展开SQL(确定性), agent核对

真实执行, memory store存结果

对初学者而言,记住三个分层就够用:

  1. 知识分层:MDL(结构语义)+ knowledge/rules(业务规则)+ knowledge/sql(confirmed范例),全是可审查的文本文件,memory index只是它们的派生检索层。
  2. 技能分层onboarding/generate-mdl是一次性搭台,enrich-context是按需深挖,usage是唯一贯穿每次查询的主循环。
  3. SQL分层:agent写的是针对MDL对象的"意图SQL",dry-plan把它展开成数据库能理解的"事实SQL",两者之间的差异就是WrenAI给agent架的一层安全网。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱知菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值