mcpField
D
di-agent-query-substrait

di-agent-query-substrait

github.com/ibm数据与数据库138 次安装2 天前更新
代码仓库

关于 di-agent-query-substrait

将自然语言数据需求转换为可编译的 Substrait JSON,供使用项目数据资产的分析流程生成查询计划。该技能从资产元数据核验列名、类型和可空性,并通过 DSL 编译验证结果。

主要功能

  1. 01将自然语言需求转为 Substrait DSL
  2. 02从项目资产核验表结构
  3. 03映射列类型与可空性
  4. 04支持连接、筛选和聚合
  5. 05编译检查并按错误修正
  6. 06按需执行查询或转换为 Elyra JSON

适用场景

  1. 01根据实际资产结构生成查询计划
  2. 02为多表连接和聚合编写查询
  3. 03将已验证的 DSL 转为 Elyra 流水线 JSON

MCP 相关

工作流调用 Substrait 相关 MCP 工具检索示例、读取规范与项目资产、编译 DSL,并可按要求执行或转换。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/ibm/ibm-watsonx-data-integration-skills --skill di-agent-query-substrait

安装后在 Claude Code 中输入/di-agent-query-substrait确认已加载。

附带文件examples/aggregate-with-sort.mdexamples/join-with-filter.md

详细介绍

生成 Substrait DSL

通过 Substrait DSL 将自然语言数据请求转换为可执行的 Substrait JSON。

必需输入

我们需要流程描述和输入架构。正确获取输入架构非常重要,并且它应与资源浏览器中的名称和类型一致。使用 list_project_assets 按名称查找相关资源,并使用资源 ID 调用 inspect_project_asset,以获取权威的列名、类型和可空性。不要使用少镜头示例或先验知识等其他信息来猜测架构——必须从项目资源中推导架构,以确保生成的 Substrait 计划对实际数据有效。

如果用户提供了表架构(一个或多个源表的列名和 Substrait 类型),请使用 list_project_assets 和 inspect_project_asset 对照项目中的实际资源进行验证。如果存在不一致之处,请告知用户。除非用户明确指定要覆盖,否则以资源工具提供的架构为准。

如果用户未提供表架构,请直接通过调用 list_project_assets 和 inspect_project_asset 从项目资源中推导架构。

获取资源后,通过将资源映射到 DSL 类型来构建一个 NamedStruct,映射关系如下:

资源类型映射

从检查过的资源构建 NamedStruct 时,请按以下方式将资源列类型映射为 DSL 类型:

资源类型DSL 类型
longvarchar、varchar、char、textstring
bigint、int8i64
integer、int、int4i64
smallint、int2i16
real、float4fp32
numeric、decimalfp64
double precision、float8fp64
boolean、boolboolean
datedate
timestamp、timestamp without time zonetimestamp

对于资源元数据中 nullable: true 的列,请在 DSL 类型后添加 ?(例如,string?)。

工作流

按照以下步骤,根据自然语言请求生成 Substrait 计划。

1. 获取少镜头示例

调用 get_substrait_dsl_examples 获取相关 DSL 示例。

关键规则——user_request 参数必须是用户的完整原始消息,逐字复制,不得进行任何修改。 检索系统使用句子级语义嵌入,需要完整上下文才能正确匹配。传入关键词或摘要会返回无关示例,并导致后续步骤失败。

get_substrait_dsl_examples(user_request="<FULL VERBATIM USER MESSAGE — EVERY WORD, NO SUMMARIZATION>", collection="draft_generation", n=5)

错误(关键词/摘要):user_request="join two tables aggregate count sum divide cast round NPS score" 正确(完整原文):user_request="Given a fct_reviews table (listing_id, review_date, reviewer_name, review_text, review_sentiment) and a dim_listings table (listing_id, listing_name, minimum_nights, host_id, room_type, price, created_at, updated_at), produce a per-listing NPS aggregation result set. For each listing: listing_id, listing_name, room_type, nps_total (overall NPS in [-100, 100] across all reviews of that listing, computed as (positive - negative) / total * 100, rounded to 0 decimals), reviews_total (total review count). Inner join on listing_id; only include listings that have at least one review."

user_request 字符串的长度应与用户消息的长度一致。如果你的 user_request 比用户消息短,就说明做错了。

仔细研究返回的示例,以了解 DSL 语法。切勿使用少镜头示例推导任何输入架构,即使示例看起来更合适——架构必须按下一步所述从项目资源中获取。

2. 从资产验证架构

必须使用资产工具验证架构。否则,生成的计划将无效且无法执行!

  1. 调用 list_project_assets,按名称查找项目中的资产
  2. 使用资产 ID 调用 inspect_project_asset,并设置 asset_type="data_asset",以获取列元数据
  3. 对每一列,根据上方的 资产类型映射 表将资产类型映射为 DSL 类型
  4. 必须在可空列的类型后追加 ?(例如,string?)
  5. 将得到的架构用作 ReadTable 的 NamedStruct

资产浏览器中找到的架构优先于少样本示例中提及的任何架构。如果与用户提供的架构不一致,请指出差异并询问用户要使用哪一个。

3. 生成 DSL

调用 get_substrait_dsl_spec 获取语言规范。编写任何 DSL 代码前,请仔细研读规范。根据用户的请求,使用已验证的表架构编写 DSL 查询,并遵循规范中关于如何构造查询、命名和引用列以及使用别名的规则。

  • 使用经过 Constructs 转换的不可变 VirtualTable 对象
  • 每行采用以下形式:variable = Construct(...)
  • 以 return <vtable> 结束
  • 表达式必须内联——不要使用表达式变量
  • 在 Join 条件中使用 left. 和 right. 前缀,且只能在 Join 条件中使用
  • 在聚合函数和分组表达式中使用 alias
4. 通过 compile_substrait_dsl 编译

调用 compile_substrait_dsl MCP 工具并传入生成的 DSL:

compile_substrait_dsl(substrait_dsl_code="<your_dsl>", read_tables=[...])

仅当 compile_substrait_dsl 成功时才能继续。如果成功,响应中将包含 Substrait JSON——继续执行第 6 步。如果失败,则继续执行第 5 步。

5. 自行纠错(最多 3 次尝试)

发生错误时:

  1. 仔细阅读错误消息
  2. 可选:调用 get_substrait_dsl_examples,并设置 collection="generation_with_error_correction",获取纠错示例
  3. 根据错误反馈修正 DSL
  4. 再次调用 compile_substrait_dsl

常见错误及修复方法:

  • 找不到列:检查每次构造后的 vtable 架构——只使用现有列
  • 类型不匹配:使用 cast() 转换类型,或检查字面量类型
  • 作用域错误:同一构造的 exprs 列表中的别名无法相互引用——再串接一个 Select/Project
  • Join 列错误:使用 left. 和 right. 前缀

如果 3 次尝试均失败:向用户报告最终错误,展示最后一次 DSL 尝试,并建议用户完善查询或检查表架构。

6. 执行或转换

根据用户的请求执行或转换 DSL。只有用户明确要求时,才执行该请求。

  • 执行 Substrait DSL(如果用户要求运行):

    有两种执行工具可用。两者都会编译 DSL 并运行生成的流程。只有在 compile_substrait_dsl 验证成功后,才能调用其中任一工具。

    run_substrait_dsl(substrait_dsl_code="<dsl>", project_id="<project_id>", source_asset_ids=["<id1>", ...])
    
    run_substrait_dsl_static(substrait_dsl_code="<dsl>", project_id="<project_id>")
    

    如果其中一个失败,则使用另一个工具重试作为后备方案——在某些情况下,一个工具会失败,而另一个可以成功。

  • 转换为 Elyra 流水线 JSON(如果用户提出此请求):

    convert_substrait_dsl_to_elyra(substrait_dsl_code="<dsl>", read_tables=[...])
    

    返回 {"success": bool, "elyra_json": dict|null, "errors": str|null}。

7. 返回结果

向用户提供:

  • 成功编译得到的 Substrait JSON
  • 生成的 DSL 代码(以便了解过程)

输出格式

### Generated DSL

\`\`\`query
<DSL code, excluding ReadTable lines>
\`\`\`

### Substrait JSON

\`\`\`json
<substrait_json from compile_substrait_dsl>
\`\`\`

重要说明

  • get_substrait_dsl_examples 的 user_request 参数:必须将用户完整且未经修改的消息作为 user_request 值传入。不要提取关键词、概括或以任何方式缩短消息。另外,始终传入 collection="draft_generation" 和 n=5。违反此规则会导致示例不相关。
  • 生成任何 DSL 代码之前,必须调用 get_substrait_dsl_spec 并研读规范。 该规范是所有构造、表达式、类型和作用域规则的权威参考;语法细节不能只依赖少量示例或既有知识
  • Select 只保留列出的列;Project 会保留所有列并添加新列
  • 聚合度量不得用 cast() 包裹
  • 最终输出的列名不得包含点号;请使用带别名的 Select 重命名

运行时注意事项

  • 可空性:资产元数据中标记为 nullable: true 的任何列都必须使用可空类型后缀(例如 string?、i64?)。如果将 NULL 值读入不可空字段,DataStage 会在运行时崩溃。
  • 不区分大小写的筛选:筛选文本/枚举列时,使用 lower() 进行不区分大小写的比较(例如 equal(lower(col("status")), literal("pending", "string"))),不要假设数据使用特定大小写。
  • 列消歧:联接多个表时,在联接前通过 Select 预先重命名重叠列(例如,使用源自表名的前缀,将 customer_id 重命名为 orders_customer_id)。除 Join 条件外,不要依赖 left./right. 前缀。

评论

支持 Markdown