di-agent-query-substrait について
自然言語のデータ要求を、コンパイル可能な Substrait JSON プランに変換するスキルです。プロジェクトのデータ資産を使うクエリ作成向けで、生成前に資産メタデータからスキーマを検証します。
主な機能
- 01要求を Substrait DSL に変換
- 02プロジェクト資産からスキーマを検証
- 03列の型と NULL 許容性をマッピング
- 04結合・フィルター・集計に対応
- 05DSL をコンパイルしてエラーを修正
- 06必要に応じて実行または Elyra JSON に変換
活用シーン
- 01実際の資産スキーマに基づくクエリプラン作成
- 02複数テーブルの結合や集計クエリの作成
- 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 を使用して名前から関連するアセットを見つけ、inspect_project_asset にアセット ID を渡して、正式な列名、型、NULL 許容性を取得してください。スキーマを推測するために、few-shot の例や事前知識など、ほかの情報は使用しないでください。生成された Substrait プランが実際のデータに対して有効であることを保証するには、スキーマをプロジェクトのアセットから導き出す必要があります。
ユーザーがテーブルスキーマ(列名と Substrait 型を含む 1 つ以上のソーステーブル)を提示した場合は、list_project_assets と inspect_project_asset を使用して、プロジェクト内の実際のアセットと照合してください。不一致があればユーザーに伝えてください。ユーザーが明示的に上書きを指定しない限り、アセットツールのスキーマが優先されます。
ユーザーがテーブルスキーマを提示しない場合は、list_project_assets と inspect_project_asset を呼び出して、プロジェクトのアセットから直接スキーマを導き出してください。
アセットを取得したら、次のマッピングに従ってアセットを DSL 型に変換し、NamedStruct を構築します。
アセット型のマッピング
検査したアセットから NamedStruct を構築する際は、アセットの列型を次のように DSL 型にマッピングします。
| アセット型 | DSL 型 |
|---|---|
longvarchar、varchar、char、text | string |
bigint、int8 | i64 |
integer、int、int4 | i64 |
smallint、int2 | i16 |
real、float4 | fp32 |
numeric、decimal | fp64 |
double precision、float8 | fp64 |
boolean、bool | boolean |
date | date |
timestamp、timestamp without time zone | timestamp |
アセットのメタデータで列の nullable: true が指定されている場合は、DSL 型に ? を付加します(例:string?)。
ワークフロー
次の手順に従って、自然言語のリクエストから Substrait プランを生成します。
1. Few-Shot の例を取得する
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 の構文を理解してください。入力スキーマを導き出すために、たとえより適切に見える場合でも、few-shot の例は決して使用しないでください。スキーマは、次の手順で説明するように、必ずプロジェクトのアセットから取得してください。
2. アセットからスキーマを確認する
アセットツールを使用してスキーマを確認することが必須です。確認しない場合、実行に失敗する無効なプランになります!
list_project_assetsを呼び出し、プロジェクト内で名前からアセットを特定します- アセット ID を指定し、
asset_type="data_asset"としてinspect_project_assetを呼び出し、列のメタデータを取得します - 各列について、上記のアセットタイプのマッピング表を使って、アセットタイプを DSL タイプに対応付けます
- null 許容の列の型には、必ず
?を付けます(例:string?) - 得られたスキーマを
ReadTableのNamedStructとして使用します
アセットブラウザーで確認したスキーマは、few-shot の例に記載されたスキーマより優先されます。ユーザーが提示したスキーマと相違がある場合は、その旨を伝え、どちらを使用するかユーザーに確認してください。
3. DSL を生成する
get_substrait_dsl_spec を呼び出して言語仕様を取得します。DSL コードを書く前に、仕様を注意深く確認してください。クエリの構築方法、列の命名と参照方法、エイリアスの使い方について仕様のルールに従い、確認済みのテーブルスキーマを使ってユーザーのリクエストに沿った DSL クエリを記述します。
- 不変の VirtualTable オブジェクトを Constructs で変換します
- 各行は
variable = Construct(...)とします - 最後は
return <vtable>とします - 式はインラインで記述し、式変数は使いません
- Join 条件では
left.とright.のプレフィックスを使用し、Join 条件以外では使用しません - 集計関数とグループ化式には
aliasを使用します
4. compile_substrait_dsl でコンパイルする
生成した DSL を指定して compile_substrait_dsl MCP ツールを呼び出します:
compile_substrait_dsl(substrait_dsl_code="<your_dsl>", read_tables=[...])
compile_substrait_dsl が成功した場合のみ、次に進んでください。成功した場合、Substrait JSON がレスポンスに含まれているので、ステップ 6 に進みます。失敗した場合は、ステップ 5 に進みます。
5. 自己修正(最大 3 回)
エラーが発生した場合:
- エラーメッセージを注意深く読みます
- 必要に応じて、修正例を得るために
collection="generation_with_error_correction"を指定してget_substrait_dsl_examplesを呼び出します - エラーのフィードバックに基づいて DSL を修正します
compile_substrait_dslをもう一度呼び出します
よくあるエラーと修正方法:
- 列が見つからない:各 Construct の後に vtable スキーマを確認し、存在する列のみを使用します
- 型の不一致:
cast()を使って型を変換するか、リテラルの型を確認します - スコープエラー:同じ Construct の
exprsリスト内のエイリアスは互いに参照できません。2 つ目の Select/Project をつなげます - Join の列エラー:
left.とright.のプレフィックスを使用します
3 回すべて失敗した場合:最後のエラーをユーザーに報告し、最後に試した DSL を提示して、クエリを調整するかテーブルスキーマを確認するよう提案します。
6. 実行または変換する
ユーザーのリクエストに応じて、DSL を実行または変換します。ユーザーが明示的に実行を求めた場合のみ、リクエストを実行してください。
-
Substrait DSL を実行する(ユーザーが実行を求めた場合):
実行ツールは 2 つあります。どちらも 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を使用してください。
実行時の考慮事項
- NULL 許容性:アセットのメタデータで
nullable: trueとされている列には、NULL 許容型のサフィックス(例:string?、i64?)を必ず使用してください。NULL 値を NULL 非許容フィールドに読み込むと、DataStage は実行時にクラッシュします。 - 大文字と小文字を区別しないフィルタリング:テキスト列または列挙型の列をフィルタリングする場合は、データ内の表記を決めつけず、
lower()を使用して大文字と小文字を区別せずに比較してください(例:equal(lower(col("status")), literal("pending", "string")))。 - 列の曖昧さの解消:複数のテーブルを結合する場合は、結合前に
Selectを使用して、重複する列名を変更してください(例:テーブル名に由来するプレフィックスを使い、customer_idをorders_customer_idに変更します)。Join 条件以外では、left./right.のプレフィックスに頼らないでください。