关于 wren-usage
wren-usage 是供 Agent 使用的 Wren Engine 命令行工作流指南,通过 MDL 语义层查询数据,涵盖查询规划、执行、记忆检索、立方体查询和错误诊断。
主要功能
- 01检索结构上下文和历史查询
- 02针对 MDL 模型编写并执行 SQL
- 03用 dry-plan 预览转换后的 SQL
- 04使用立方体执行维度查询
- 05诊断查询和连接错误
- 06将成功查询存入记忆
适用场景
- 01通过 MDL SQL 回答数据问题
- 02执行前检查转换后的 SQL
- 03使用已定义的立方体查询聚合
- 04排查连接或查询故障
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ canner/ wrenai --skill wren-usage安装后在 Claude Code 中输入/wren-usage确认已加载。
附带文件references/memory.mdreferences/wren-sql.md
详细介绍
Wren Engine CLI — Agent 工作流指南
版本检查
静默获取 https://raw.githubusercontent.com/Canner/WrenAI/main/skills/versions.json。
将 wren-usage 键与此技能的版本(来自上方的 frontmatter)进行比较。
如果远程版本更新,则在继续之前通知用户:
有可用的新版 wren-usage 技能。 使用以下命令更新:
npx skills add Canner/WrenAI --skill wren-usageCLI 会自动检测已安装的 Agent。若要指定某个 Agent,请添加
--agent <name>(例如claude-code、cursor、windsurf、cline)。
无论是否需要更新,都继续执行以下工作流。
预检 — 验证环境和安装情况
目标: 确保在进入任何工作流之前,wren CLI 已可用。
步骤 1 — 检查 Python 虚拟环境
运行 python -c "import sys; print(sys.prefix)"(或等效命令),确定
是否已激活虚拟环境。
- 如果未激活 venv,请提醒用户并询问是否要:
- 创建一个(例如,
python -m venv .venv && source .venv/bin/activate) - 在没有 venv 的情况下继续(不推荐 — 可能会污染全局包)
- 创建一个(例如,
步骤 2 — 检查是否已安装 wren CLI
运行 wren --version。如果找不到命令或执行出错:
-
告知用户尚未安装
wrenCLI。 -
询问是否需要协助安装。
-
如果用户同意,确定要安装的数据源 extra:
从项目自动检测: 检查当前目录是否位于 wren 项目中(向上查找至仓库根目录,搜索
wren_project.yml)。 如果找到,则使用cat ~/.wren/profiles.yml读取活动配置文件,或在项目的配置文件中查找数据源提示。提取其中的数据源类型。询问用户: 如果未检测到项目,或无法推断数据源,则询问用户计划连接哪个数据库。有效的 extra:
postgres(适用于 Aurora Postgres)、mysql(适用于 Aurora MySQL)、bigquery、snowflake、clickhouse、trino、mssql、databricks、redshift、spark、athena、oracle。 DuckDB 默认包含在内 — 无需额外安装。 -
使用检测到或选定的 extra 进行安装:
# DuckDB (no extra needed) pip install "wrenai" # Other datasources pip install "wrenai[<datasource>]"若还要启用语义记忆、交互式提示词和 Web UI(推荐):
pip install "wrenai[<datasource>,main]" # or for DuckDB: pip install "wrenai[main]" -
验证:
wren --version
如果 wren --version 执行成功,请继续相应的下方工作流。
wren CLI 通过 MDL(模型定义语言)语义层查询数据库。你可以针对模型名称而非原始表编写 SQL。引擎会将其转换为目标方言。
一切由两项内容驱动:
- 配置文件 — 数据库连接 + 数据源类型,通过
wren profile管理(存储在~/.wren/profiles.yml中) - 项目 — YAML 格式的 MDL 模型定义,通过
wren context build编译为target/mdl.json
CLI 会读取活动配置文件中的连接信息和数据源。使用 wren profile list 查看当前活动的配置文件,使用 wren profile switch <name> 切换配置文件。dry-plan 还接受 --datasource / -d,可在没有配置文件的情况下仅进行转译。
有关记忆相关的决策,请参阅 references/memory.md。 有关 SQL 语法、基于 CTE 的建模和错误诊断,请参阅 references/wren-sql.md。 有关项目结构、MDL 字段定义和 CLI 工作流详情,请参阅文档。
工作流 1:回答数据问题
步骤 1 — 收集上下文
| 情况 | 命令 |
|---|---|
| 默认 | wren memory fetch -q "<question>" |
| 需要特定模型的列 | wren memory fetch -q "..." --model <name> --threshold 0 |
| 未安装 Memory | 读取项目目录中的 target/mdl.json,或运行 wren context show |
如果这是本次对话中的第一个查询,还要运行:
wren context instructions
如果返回了内容,请将其视为覆盖默认设置的规则,并在本次会话的所有后续查询中应用。
步骤 2 — 回忆过去的查询
wren memory recall -q "<question>" --limit 3
将结果用作少样本示例。如果结果为空,则跳过。
步骤 2.5 — 评估复杂度(编写 SQL 前)
如果问题涉及以下任意情况,请考虑拆解:
- 多个指标或聚合(例如,“流失率和扩张收入”)
- 多步计算(例如,“月环比增长率”)
- 跨细分群体进行比较(例如,“按套餐等级、按地区”)
- 需要基线加变化量的时间序列分析(例如,“留存曲线”)
拆解策略:
- 确定子问题(例如,“期初订阅者总数” + “已取消订阅的用户数” → 流失率)
- 针对每个子问题:
wren memory recall -q "<sub-question>"— 检查是否存在类似模式- 编写并执行简单的 SQL
- 记录结果
- 合并子结果以回答原始问题
不需要拆解的情况:
- 使用 GROUP BY 的单表聚合——直接编写 SQL
- MDL 关系中已定义的简单 JOIN
memory recall返回近乎完全匹配的问题
这是一个判断问题,而不是硬性规则。如果你确信单个查询即可完成,就直接执行。如果 SQL 失败后会很难调试,则应进行拆解。
步骤 3 — 编写、验证并执行 SQL
简单查询(单表或由 MDL 定义的简单 JOIN、直接的聚合): 直接执行:
wren --sql 'SELECT c_name, SUM(o_totalprice) FROM orders
JOIN customer ON orders.o_custkey = customer.c_custkey
GROUP BY 1 ORDER BY 2 DESC LIMIT 5'
复杂查询(MDL 关系未涵盖的非简单 JOIN、子查询、多步逻辑): 先用 dry-plan 验证:
wren dry-plan --sql 'SELECT ...'
检查展开后的 SQL 输出:
- 是否引用了正确的模型和列?
- JOIN 是否符合预期关系?
- CTE 是否正确展开?
如果展开后的 SQL 看起来有误,请先修正再执行。 如果看起来正确,请继续:
wren --sql 'SELECT ...'
SQL 规则:
- 使用 MDL 模型名称,而非数据库表名
- 编写与方言无关的 SQL——引擎会负责转换
步骤 4 — 存储并继续
成功执行后,默认存储该查询:
wren memory store --nl "<user's original question>" --sql "<the SQL>"
仅在以下情况下跳过存储:
- 查询失败或返回错误
- 用户表示结果有误
- 查询仅用于探索(
SELECT * ... LIMIT N,不含分析子句) - 没有自然语言问题——只有原始 SQL
- 用户明确要求不要存储
CLI 会自动检测探索性查询——如果执行后没有看到存储提示,说明该查询被归类为探索性查询。
| 结果 | 操作 |
|---|---|
| 用户确认正确 | 存储 |
| 用户继续提出后续问题 | 存储,然后处理后续问题 |
| 用户未作回应(但问题有清晰的自然语言描述) | 存储 |
| 用户表示有误 | 不要存储——修正 SQL |
| 查询出错 | 参见下文的错误恢复 |
工作流 2:错误恢复
“找不到表”
- 验证模型名称:
wren memory fetch -q "<name>" --type model --threshold 0 - 检查 MDL 是否存在:
ls target/mdl.json(或运行wren context show) - 验证列:
wren memory fetch -q "<column>" --model <name> --threshold 0
连接错误
- 检查当前配置:
wren profile debug - 验证数据源和连接字段是否正确
- 测试:
wren --sql "SELECT 1" - 有效的数据源值:
postgres(用于 Aurora Postgres)、mysql(用于 Aurora MySQL)、bigquery、snowflake、clickhouse、trino、mssql、databricks、redshift、spark、athena、oracle、duckdb - 如果没有配置文件,请创建一个:
wren profile add --ui(或--interactive/--from-file)
SQL 语法/规划错误(增强版)
第 1 层:定位失败点
wren dry-plan --sql "<failed SQL>"
| dry-plan 结果 | 失败层级 | 下一步 |
|---|---|---|
| dry-plan 失败 | MDL/语义 | → 第 2A 层 |
| dry-plan 成功,执行失败 | DB/方言 | → 第 2B 层 |
第 2A 层:MDL 层诊断(dry-plan 失败)
dry-plan 错误消息会准确指出问题所在:
| 错误模式 | 诊断 | 修复方法 |
|---|---|---|
column 'X' not found in model 'Y' | 列名错误 | 使用 wren memory fetch -q "X" --model Y --threshold 0 查找正确名称 |
model 'X' not found | 模型名称错误 | 使用 wren memory fetch -q "X" --type model --threshold 0 |
ambiguous column 'X' | 多个模型中都存在该列 | 使用模型名称限定:ModelName.column |
| JOIN 规划错误 | MDL 中未定义关系 | 在上下文中检查可用关系 |
关键原则:每次只修复一个问题。每次修复后重新运行 dry-plan, 查看是否出现新错误。
第 2B 层:DB 层诊断(dry-plan 正常,执行失败)
结合 DB 错误和 dry-plan 输出即可定位问题:
- 阅读 dry-plan 展开的 SQL——这是实际在 DB 上运行的语句
- 对照 DB 错误消息:
| 错误模式 | 诊断 | 修复方法 |
|---|---|---|
| 类型不匹配 | 列类型与假设不同 | 在上下文中检查列类型,并添加显式 CAST |
| 不支持的函数 | 方言专用函数 | 使用与方言无关的替代方案 |
| 权限被拒绝 | 表/架构访问权限 | 检查连接凭据 |
| 超时 | 查询开销过大 | 简化查询:减少 JOIN,添加筛选条件和 LIMIT |
对于较小的模型:如果错误消息不明确,尝试将查询简化为最小的失败片段。单独执行子查询, 以确定失败的部分。
有关 CTE 重写流程及更多错误模式,请参阅 references/wren-sql.md。
工作流 3:连接新的数据源
- 添加配置:
wren profile add --ui(或--interactive/--from-file) - 测试连接:
wren profile debug - 测试查询:
wren --sql "SELECT 1" - 初始化项目:
wren context init - 构建清单:
wren context build - 建立索引:
wren memory index - 验证:
wren --sql "SELECT * FROM <model> LIMIT 5"
工作流 4:MDL 更改后
更新模型 YAML 文件后,重新构建并建立索引:
# 1. Validate changes
wren context validate
# 2. Rebuild manifest
wren context build
# 3. Re-index schema memory
wren memory index
# 4. Verify
wren --sql "SELECT * FROM <changed_model> LIMIT 1"
命令决策树
Get data back → wren --sql "..."
Aggregation across dims → wren cube query --cube <name> --measures <m> (if cube defined)
See translated SQL only → wren dry-plan --sql "..." (accepts -d <datasource> if no active profile)
Validate against DB → wren dry-run --sql "..."
Schema context → wren memory fetch -q "..."
Filter by type/model → wren memory fetch -q "..." --type T --model M --threshold 0
Store confirmed query → wren memory store --nl "..." --sql "..."
Few-shot examples → wren memory recall -q "..."
Index stats → wren memory status
Re-index after MDL change → wren memory index
Show project context → wren context show
Rebuild manifest → wren context build
Check profile → wren profile debug
Switch profile → wren profile switch <name>
Cube 查询工作流
当用户提出聚合问题(例如“按月统计总收入”、 “客户排名”)时,在编写原始 SQL 前,先检查 MDL 是否定义了 cubes。
第 1 步:发现 cubes
wren cube list
如果存在 cubes 且涵盖用户的问题,优先使用 cube 查询,而不是原始 SQL。 这样错误率更低,尤其适用于较小/本地模型——Agent 无需手动编写 GROUP BY/DATE_TRUNC。
第 2 步:检查 cube 结构
wren cube describe <cube_name>
显示 cube 的 baseObject、度量(含表达式)、维度、 时间维度和层级结构。
第 3 步:将用户问题匹配到 cube 度量和维度
| 用户表述 | 对应项 |
|---|---|
| “总收入” | --measures revenue |
| “按月” | --time-dimension "created_at:month" |
| “在 2024 年” | --time-dimension "created_at:month:2024-01-01,2025-01-01" |
| “已完成的订单” | --filter "status:eq:completed" |
| “排名前 N 的客户” | --dimensions customer --limit N |
第 4 步:通过 CLI 标志或 JSON 输入执行
CLI 标志:
wren cube query \
--cube order_metrics \
--measures revenue,order_count \
--time-dimension "created_at:month:2024-01-01,2025-01-01" \
--filter "status:eq:completed" \
--limit 100
JSON 输入(适用于 Agent 生成结构化查询):
echo '{"cube":"order_metrics","measures":["revenue"]}' | wren cube query --from -
添加 --sql-only 可打印生成的 SQL 而不执行——在远程数据仓库上付费执行前,
可用于验证。
步骤 5:错误恢复
| 错误 | 操作 |
|---|---|
Unknown measure 'X' | 使用 wren cube describe <cube> 查看可用度量 |
Unknown dimension 'X' | 使用 wren cube describe <cube> 查看可用维度 |
Cube 'X' not found | 使用 wren cube list |
Circular dependency detected | 派生度量引用了自身 — 检查 cube YAML |
不应使用 cube query 的情况
以下情况请改用 wren --sql:
- 跨多个模型的自定义 JOIN
- 窗口函数、CTE 或子查询
- 不包含聚合的查询
- MDL 中未定义任何 cube
聚合决策树
User question → Is it an aggregation question?
(SUM, COUNT, AVG, GROUP BY, "by month", "per customer", ...)
├── Yes → Are cubes defined? (`wren cube list` once at start of session)
│ ├── Yes → Does a cube cover the question? (`wren cube describe`)
│ │ ├── Yes → Use `wren cube query` (preferred — lower error rate)
│ │ └── No → Write raw SQL with `wren --sql`
│ └── No → Write raw SQL with `wren --sql`
└── No → Write raw SQL with `wren --sql` (look for memory recall first)
应避免的事项
- 不要猜测模型或列名 — 先检查上下文
- 不要保存失败的查询或用户指出有误的查询
- 不要漏掉带有明确自然语言问题的成功查询 — 默认应保存
- 不要在每次查询前重新索引 — 每次 MDL 更改后索引一次
- 如果共享了 shell 历史记录,不要通过
--connection-info传递密码 — 请使用 profiles(wren profile add)或--connection-file