メインコンテンツへスキップ

概要

Jinba Flowは以下を可能にする強力なテンプレート機能をサポートしています:
  • 前のステップの結果を参照する
  • 設定済みのシークレットに安全にアクセスする
  • 複雑なロジックにNunjucksテンプレートを使用する
  • 動的で再利用可能なワークフローを作成する

変数プレースホルダー

基本構文

変数は二重波括弧で囲みます:{{ 変数 }}

利用可能な変数

item、itemIndex、itemCountは、forEachを設定したステップの入力でのみ使用できます。

ステップ結果へのアクセス

フィルターを付けない{{steps.<step_id>.result...}}プレースホルダーは、次のようにテキストとして埋め込まれます:
  • オブジェクトと配列はJSONになります
  • 文字列はクォートなしでそのまま入ります
  • nullや存在しない値は空文字になります
この自動変換が働くのは、フィルターのないsteps.<step_id>.result...プレースホルダーだけです。それ以外のオブジェクト(アイテムがオブジェクトのときの{{item}}など)は[object Object]と表示されるため、{{item | json}}と書いてください。 別のステップの結果を読むステップは、そのステップをneedsに指定してください。指定しないと、結果ができる前に実行される場合があります。詳しくはステップモジュールオプションを参照してください。
PYTHON_SANDBOX_RUNの出力はresult.dataに入るため、後続のステップでは{{steps.<step_id>.result.data}}で読み取ります。

シークレットの使用

シークレットはワークスペースレベルで設定され、安全にアクセスされます:
セキュリティに関する注意:
  • シークレットは保存時に暗号化されます
  • ワークフローに機密値をハードコーディングしないでください
  • APIキー、トークン、認証情報にはシークレットを使用してください

Nunjucksテンプレート

Jinba FlowはテンプレートをNunjucksで処理します。構文はJinja2に近いものの、同一ではありません。テンプレートはステップ実行前に処理されます。

制御構造

Forループ

条件文

インデックス付きループ

loop.indexは1から、loop.index0は0から数えます。

組み込み関数

Nunjucksにはzip()がありません。2つのリストを並べて処理するには、一方をループし、もう一方をloop.index0で参照します:

フィルター

値に変換を適用します:
defaultが置き換えるのは存在しない値だけです。null、空文字、falseも置き換えるにはdefault('フォールバック値', true)と書きます。 jsonはJinba Flowが追加しているフィルターで、厳密なJSONを出力します(文字列はクォート付き、nullはnullのまま)。tojsonフィルターはありません。 forEachステップの出力向けに、次のフィルターも追加されています:

空白の制御

{%-と-%}を使用して空白を制御します:
  • {%- はタグの前の空白を削除
  • -%} はタグの後の空白を削除

一般的なパターン

以下のPythonの例では、前のステップの結果をjson.loads(r'''{{steps.<step_id>.result}}''')で読み取っています。結果をPythonコードにそのまま埋め込むと、null、true、falseなどのJSONの値でエラーになります。PYTHON_SANDBOX_RUNは最後の行の値を結果として返します。構造化データを返すには、data_typeをOBJECTにして最後の行をjson.dumps(...)にします。

リストの処理

条件付きデータ選択

複数ソースの結合

ここでのzipはサンドボックス内で動くPythonの関数です。テンプレートでは、上の「組み込み関数」で示したloop.index0の方法を使ってください。

リストのフィルタリング

NunjucksはJinja2の{% for x in list if condition %}に対応していません。条件がリスト全体に対して一度だけ評価されるため、通常ループは何も出力しません。条件はループの内側に書いてください:

動的プロンプトの構築

ベストプラクティス

変数参照

  • 明確さのために説明的なステップIDを使用する
  • 必要なプロパティのみにアクセスする
  • デフォルト値でnull/undefined値を処理する

テンプレート

  • 適切なインデントでテンプレートを読みやすく保つ
  • きれいな出力のために空白制御を使用する
  • 複雑なロジックは複数のステップに分割する

シークレット

  • シークレット値をログに記録したり公開したりしない
  • チーム共有にはワークスペースレベルのシークレットを使用する
  • シークレットを定期的にローテーションする

パフォーマンス

  • 深くネストしたテンプレートを避ける
  • ループ回数を制限する
  • 可能な場合はデータを事前処理する

トラブルシューティング

よくある問題

変数が見つからない・空になる
  • ステップIDのスペルを確認
  • 参照するステップがneedsに指定されていることを確認
  • プロパティパスが正しいことを確認(PYTHON_SANDBOX_RUNの出力はresult.dataの下にあります)
テンプレート構文エラー
  • 波括弧{{ }}のバランスを確認
  • Nunjucksタグの構文{% %}を確認
  • 文字列内のクォートが不足していないか確認
予期しない出力
  • デバッグステップを使用して中間値を検査
  • 空白の処理を確認
  • データ型を確認(文字列 vs オブジェクト)
  • [object Object]と表示される場合は、オブジェクトが変換されずに埋め込まれています。| jsonを付けてください
TemplateSecurityError: ... is not allowed in templates
  • テンプレートはフロー作成者が書くものなので、コードの実行やファイルの読み取りにつながる記述はエンジンが拒否し、ステップはレンダリングされずに失敗します
  • 使えないもの: 任意の値に対するconstructor、prototype、__proto__の参照(その名前を持つ結果フィールドを含む)、{% asyncEach %}・{% asyncAll %}、変数・ループ変数・マクロ・フィルター・テストの名前として通常の識別子(英字、数字、_、$)でないもの
  • {% include %}・{% import %}・{% extends %}は別のエラー(“template not found” のレンダリングエラー)で失敗します。フローから読み込めるテンプレートファイルが存在しないためです
  • 通常のメンバー参照、{{ steps.x.result.trim() }}のような値のメソッド呼び出し、フィルター、range、マクロはそのまま使えます
  • 独自の{{ }}補間を含むフロントエンドのコード(HTMLスニペット内の{{ user?.name }}など)は{% raw %} ... {% endraw %}で囲んでください

関連ドキュメント