Difyのテンプレートブロックとは?Jinja2を使ったデータ変換の全貌
室谷今回はDifyのテンプレートブロックを深掘りしていきましょう。これ、Difyワークフローを組んでいると必ず出てくるのに「なんとなく使ってる」で終わってる人が多いんですよね・・・
テキトー教師ほんとそうです。講座でDifyのワークフローを教えていると、テンプレートブロックって「変数を結合するだけのもの」だと思っている受講生さんがめちゃくちゃ多い。
でも実際はもっと奥が深い。
でも実際はもっと奥が深い。
室谷Jinja2テンプレートエンジンが使えるんですよね。Pythonをやったことがある人なら馴染みがあると思いますが、ループや条件分岐まで書けるので・・・
テキトー教師そうなんです。整理すると、Difyのテンプレートブロックには大きく2種類の使い方があるんですよね。
「データを整形して次のノードに渡す」シンプルな使い方と、「ループや条件分岐を駆使した高度なデータ変換」をする使い方。
「データを整形して次のノードに渡す」シンプルな使い方と、「ループや条件分岐を駆使した高度なデータ変換」をする使い方。
室谷MYUUUでもDifyを使った業務自動化をかなりやってますけど、テンプレートブロックが一番活躍するのは「LLMノードに渡すプロンプトを動的に生成する」場面ですね。
テキトー教師まさにそれです。RAGワークフローでもプロンプトテンプレートとして活用できますし、ナレッジパイプラインの中でもテンプレートブロックが要所要所に入ってくる。
知識検索ブロックと組み合わせると、検索結果をきれいに整形してLLMに渡せるんですよ。
知識検索ブロックと組み合わせると、検索結果をきれいに整形してLLMに渡せるんですよ。
室谷というわけで今回は、テンプレートブロックの基礎から実践的な使い方まで、かなり細かく解説していきます。コードブロック(Python)との違いも含めて。
テンプレートブロックの基本: Jinja2テンプレートとは何か

テキトー教師まずJinja2について知らない人のために説明しておくと、Jinja2はPythonで広く使われているテンプレートエンジンです。HTMLの生成やメール本文の動的生成などによく使われてきたものです。
室谷Difyがこれを採用したのは、プログラマーじゃない人でも比較的書きやすいからだと思うんですよね。
{{ }}で変数を埋め込んで、{% %}で制御構文を書く、という構文がシンプルで。
テキトー教師受講生さんには「Excelの数式より直感的」と説明するとわかりやすいって言われます。変数参照は二重波括弧で書きます。
室谷基本的な書き方はこんな感じですよね。まとめるとこうなります。
{{ variable_name }} ← 変数の参照
{{ user.name }} ← ネストされたオブジェクトのプロパティ
{{ items[0].title }} ← 配列の要素
{{ data.metrics.score }} ← 深いネスト
テキトー教師ここが慣れるまで少しハマりどころで、コミュニティのメンバーさんからよく聞くのが「変数名が合ってるのに値が入らない」という相談です。大体の場合はDifyの前のノードで変数名を間違えているか、変数の型が想定と違っていたりします。
室谷型の問題は地味に多いですよね。LLMノードの出力がString型のつもりがJSONになっていたりとか・・・
テキトー教師そうそう。なのでテンプレートブロックの設定画面で、どの変数を入力変数として受け取るかを明示的に設定するのが重要です。
これで型の不一致に気づきやすくなります。
これで型の不一致に気づきやすくなります。
テンプレートブロック vs コードブロック: どちらを使うべきか

室谷これ、DifyワークフローでよくあるテンプレートブロックとPythonコードブロックをどう使い分けるか問題ですね。
テキトー教師講座で必ず出る質問です。整理すると、こんな基準で使い分けるといいと思ってます。
| 用途 | テンプレートブロック | Pythonコードブロック |
|---|---|---|
| テキストの整形・結合 | 最適 | 過剰 |
| 条件による出力切替 | 可能 | 可能 |
| 数値計算・統計処理 | 不向き | 最適 |
| 外部ライブラリ利用 | 不可 | 可能(numpy、pandas等) |
| JSONパース・変換 | 基本的な操作のみ | 高度な操作が可能 |
| LLMへのプロンプト構築 | 最適 | 可能だが冗長 |
室谷要は「テキストを動的に作るならテンプレート、データを複雑に処理するならコード」という感じですね。
テキトー教師よくあるアンチパターンとして、テキストの結合だけなのにコードブロックを使ってしまうケースがあります。コードブロックはサンドボックス環境で実行されるので・・・
室谷セルフホストの場合はDockerのサンドボックスサービスを立ち上げておく必要がありますしね。
その点テンプレートブロックはその制約がない。
docker-compose -f docker-compose.middleware.yaml up -dでサービスを起動してないとコードブロックが動かない。その点テンプレートブロックはその制約がない。
テキトー教師オンプレ環境でDifyを動かしているチームにとっては、テンプレートブロックで済むならコードブロックを避けるメリットがありますね。セキュリティ面でも管理が楽になります。
室谷あと処理速度という意味でも、テンプレートブロックのほうが軽いです。大量のワークフローを並列で流すような業務自動化では、ここの差がじわじわ効いてきます・・・
Jinja2の条件分岐とループを使いこなす
テキトー教師テンプレートブロックで「変数の埋め込みしかできない」と思っていた人が、一番驚くのが条件分岐とループですね。
室谷これを知ってからDifyワークフローの設計がかなり変わった、という声を.AI(ドットエーアイ)コミュニティでも聞きますね。
テキトー教師条件分岐はこんな書き方になります。
{% if user.subscription == 'premium' %}
おかえりなさい、プレミアムメンバー様!全ての機能にアクセスできます。
{% elif user.subscription == 'basic' %}
ベーシックプランでご利用中です。プレミアムへのアップグレードも可能です。
{% else %}
ご利用ありがとうございます。プランを選択してください。
{% endif %}
室谷If-Elseノードを使わなくていいケースが出てくるんですよね。単純な文字列の出し分けならテンプレート内でやったほうがワークフローがスッキリします。
テキトー教師ただ、ここで注意点があって。テンプレートブロック内の条件分岐は「出力するテキストを変える」ためのもので、「ワークフローの分岐を制御する」ものではない。
コミュニティのメンバーさんがたまに混同するんですよ。
コミュニティのメンバーさんがたまに混同するんですよ。
室谷ワークフロー全体の流れを変えたいならIf-Elseノードを使う、テキストの内容を切り替えたいだけならテンプレートブロック内でやる。この使い分けは重要ですね。
テキトー教師ループはこういう書き方です。RAGの検索結果を整形する場面で特に使います。
{% for item in search_results %}
### 検索結果 {{ loop.index }}
**スコア**: {{ item.score | round(2) }}
{{ item.content }}
---
{% endfor %}
室谷loop.indexで連番を振れるのが地味に便利なんですよ。「検索結果1件目・2件目・・・」と番号付きで並べることで、LLMが参照しやすくなりますし・・・
テキトー教師まさに。これが知識検索ブロックと組み合わせたテンプレートブロックの王道パターンですよね。
ナレッジパイプラインでは、検索してきたドキュメントの断片(チャンク)を、テンプレートで整形してからLLMに渡す、という流れを作ります。
ナレッジパイプラインでは、検索してきたドキュメントの断片(チャンク)を、テンプレートで整形してからLLMに渡す、という流れを作ります。
Jinja2フィルターで出力を整える
室谷テンプレートブロックで意外と見落とされがちなのがフィルター機能ですね。
|(パイプ)を使ってデータを変換する。
テキトー教師これ、受講生さんに教えると「こんな機能あったんですか!」って毎回言われます。フィルターをまとめるとこうなります。
{{ name | upper }} ← 大文字変換
{{ price | round(2) }} ← 小数点以下2桁に丸め
{{ content | replace('\n', '<br>') }} ← 改行をHTMLタグに変換
{{ score | default('未計算') }} ← 値がなければデフォルト値
{{ text | truncate(100) }} ← 100文字で切り詰め
{{ items | length }} ← 配列の要素数を取得
室谷defaultフィルターは本当によく使います。前のノードの出力が空だった場合のエラーハンドリングになるので。
テキトー教師受講生さんでDifyのワークフローがエラーで止まる一番多い原因が「前のノードの出力が空でテンプレートが壊れる」なんですよ。
defaultフィルターを使っておくだけでワークフローの安定性がかなり上がります。
室谷あと
roundフィルターもよく使いますね。スコアリングの結果を整形するとき、小数点以下が長いまま出力されてLLMに渡すと、プロンプトが無駄に長くなりますし・・・{{ metrics.accuracy | round(2) if metrics.accuracy else '計算中' }}
テキトー教師この書き方、インラインで条件判定できるのがスマートですよね。
ifをインラインで書く方法を知っていると、テンプレートがすっきりします。テンプレートブロックの実践パターン: プロンプトテンプレートとして使う
室谷ここからは実践的な使い方を見ていきましょう。一番よく使われるのが、LLMノードへのプロンプトを動的に作るパターンですね。
テキトー教師Difyのプロンプトテンプレートとして使う、という感じですね。LLMノードにも直接変数埋め込みはできますが、複雑な整形が必要な場合はテンプレートブロックで事前に作っておくほうが管理しやすい。
室谷たとえばMYUUUで作った業務自動化ワークフローで、こういうパターンをよく使います。
あなたは以下の情報をもとにレポートを作成するアシスタントです。
## 対象ユーザー
名前: {{ user.name }}
役職: {{ user.role }}
{% if user.department %}所属: {{ user.department }}{% endif %}
## 分析データ
{% for metric in metrics %}
- {{ metric.name }}: {{ metric.value | round(2) }}
{% endfor %}
## 指示
上記のデータを元に、{{ report_type }}形式で300字程度のサマリーを作成してください。
テキトー教師これ、見てもらうとわかりますが、ユーザー情報と分析データを動的に組み込んで、LLMへの指示文(プロンプト)を自動生成していますよね。チャットボットテンプレートとして活用するなら、ユーザーが入力した情報を元にパーソナライズされたプロンプトを作れます。
室谷チャットフローでも同じことができるんですよね。会話変数に溜まったユーザーの過去の発言を、テンプレートブロックで整形してコンテキストとしてLLMに渡す、という使い方。
テキトー教師チャットフローテンプレートとして汎用的に作っておくと、ちょっとシステムプロンプトを変えるだけで様々な用途に転用できるので、テンプレート集を作っておくと重宝しますよ。
室谷室谷の著書「お金を使わず、AIを働かせる『Dify』活用」でもこの辺の設計パターンをかなり詳しく書いたんですけど、テンプレートブロックの活用度合いでDifyの使いこなし度がわかると思っています。
JSONテンプレートとRAGワークフローへの応用
テキトー教師次はJSONテンプレートの話をしましょうか。Difyのテンプレートブロックでは、JSONを動的に生成することもできます。
室谷これ、HTTPリクエストノードと組み合わせると強力なんですよね。外部APIに渡すリクエストボディをテンプレートで動的に作る、という使い方。
{
"user_id": "{{ user_id }}",
"query": "{{ search_query | replace('"', '\\"') }}",
"filters": {
"category": "{{ category }}",
"limit": {{ limit | default(10) }}
}
}
テキトー教師ここで一点注意が必要で、JSONを手動で生成するテンプレートは引用符のエスケープが必要です。
replaceフィルターで二重引用符をエスケープしておかないと、JSONが壊れてしまいます。
室谷あるあるですよね・・・。これで詰まったことがMYUUUのチームでも何度かありました。
テキトー教師RAGテンプレートとしての使い方も説明しておくと、Difyのナレッジパイプラインではこういう流れになります。
- ユーザーの質問を知識検索ブロックに渡す
- 検索結果(複数のチャンク)が返ってくる
- テンプレートブロックで検索結果を整形する
- 整形されたコンテキストをLLMノードのプロンプトに埋め込む
室谷ステップ3がまさにテンプレートブロックの出番ですよね。検索結果をそのままLLMに渡すより、番号を振って「参考情報1: ...」のような形に整形してから渡すほうが、LLMの回答精度が上がります。
テキトー教師この点、「RAGの精度が上がらない」と相談されたとき、テンプレートブロックの整形を見直してもらうだけで改善することが多いです。知識検索の精度を上げようとチャンクサイズや埋め込みモデルをいじる前に、テンプレートの設計を確認してほしいですね。
室谷まさに。.AIコミュニティでも毎週聞かれる質問なんですけど、「RAGが使えない」という人の半数くらいはテンプレートの問題だったりします。
ループブロックとテンプレートブロックの連携
室谷Difyのループブロックとテンプレートブロックを組み合わせると、さらに強力になるんですよね。
テキトー教師ループブロックは「繰り返し処理」をするためのノードで、テンプレートブロックはその中で「各繰り返しの出力を整形する」役割を担うことが多いです。
室谷具体的には、たとえば複数の商品データがあって、各商品の説明文をLLMで生成したい場合。ループブロックで商品リストを回して、各商品のデータをテンプレートブロックでLLMへのプロンプトに整形してから渡す、という流れです。
テキトー教師反復処理(イテレーション)ノードもよく似た用途で使われますが、ループブロックは終了条件を自分で設定できる点が違いますね。テンプレートブロックは終了条件の判定にも使えて、ループの各反復で処理した結果をカウントするようなテンプレートを書けます。
室谷ループブロックの中でテンプレートブロックを使うときのコツとして、前の反復の結果を次の反復で参照する「累積パターン」があります。
{% for item in previous_results %}
{{ loop.index }}. {{ item }}
{% endfor %}
新しい結果: {{ current_result }}
テキトー教師この累積パターン、最初はハマりやすいですが慣れると便利です。ループブロックの変数の渡し方を理解することがポイントです。
テンプレートブロックのよくあるエラーと対処法

テキトー教師実践でよく起きるエラーと対処法もまとめておきましょう。
室谷これ、.AIコミュニティのメンバーから一番多く質問が来る部分ですよね。
テキトー教師まずよくある問題と解決策をまとめるとこうなります。
| エラー | 原因 | 対処法 |
|---|---|---|
| 変数が空になる | 前ノードの出力変数名が異なる | テンプレートの入力変数設定を確認 |
| テンプレート構文エラー | {{ }}や{% %}の閉じ忘れ | 構文を再確認、特にループや条件分岐の終了タグ |
| 型エラー | 文字列に数値フィルターを適用 | defaultで空値を処理してから変換 |
| 出力が長すぎる | テンプレートの出力が80,000字を超過 | テンプレートの内容を分割するか短縮 |
| JSONが壊れる | テキスト内の特殊文字未エスケープ | replaceフィルターでエスケープ処理 |
室谷出力の80,000字制限は意外と知られていないんですよね。大量のドキュメントをテンプレートでループ処理しようとして引っかかることがあります。
テキトー教師その場合はテンプレートブロックを分割するか、コードブロックに切り替えることを検討してください。コードブロックも同じく80,000字制限がありますが、処理の分割はしやすいです。
室谷あとDifyのテンプレートブロックとは直接関係ありませんが「ドキュメントのインデックス作成に失敗しました」というエラーについて、混同される方もいるので補足しておくと・・・
テキトー教師これはナレッジ機能でファイルのインデックスを作るときのエラーですね。ファイル形式やサイズの問題、あるいは埋め込みモデルの設定ミスが多いです。
テンプレートブロックの問題とは別ですが、RAGワークフローを組む際に並行して踏む可能性があります。
テンプレートブロックの問題とは別ですが、RAGワークフローを組む際に並行して踏む可能性があります。
テンプレートブロックの応用: インタラクティブフォームの生成
テキトー教師あまり知られていない機能ですが、テンプレートブロックでインタラクティブなHTMLフォームを生成できます。これ、かなり面白い使い方なんですよ。
室谷チャットインターフェースで構造化されたデータを収集するときに使えますよね。ユーザーに自由記述で答えてもらうのではなく、フォームで入力してもらって、そのデータをワークフローで処理する。
テキトー教師書き方はこんな感じになります。
<form data-format="json">
<label for="category">カテゴリ:</label>
<input type="select" name="category"
data-options='["技術","ビジネス","デザイン"]'/>
<label for="priority">優先度:</label>
<input type="select" name="priority"
data-options='["高","中","低"]'/>
<label for="detail">詳細:</label>
<textarea name="detail" placeholder="詳細を入力してください"></textarea>
<button type="submit" variant="primary">送信</button>
</form>
室谷これ、ユーザーがフォームを送信すると、入力内容がJSON形式になって次のノードに流れていく。チケット発行システムとか、問い合わせフォームの自動処理とかに使いやすいです。
テキトー教師コミュニティのメンバーさんで実際にこれを使って「顧客からの要望を受け取ってSlackに自動転送するワークフロー」を作った方がいました。テンプレートブロックの応用として面白い事例でした。
テンプレートブロックのベストプラクティス
室谷ここまで色々と話してきましたが、テンプレートブロックを使う上でのベストプラクティスをまとめてもらいましょうか。
テキトー教師公式ドキュメントにも書かれていますが、実際に多くのワークフローを見てきた経験を踏まえてまとめると、こうなりますね。
室谷まず変数名ですよね。
テキトー教師そうです。変数名は英数字とアンダースコアで意味がわかる名前にする。
data1とかtempじゃなくてuser_queryやsearch_resultsのような名前にすることで、テンプレートを後から見たときに何をしているか一目でわかる。
室谷これ地味に重要で・・・。MYUUUでもDifyワークフローの保守を引き継ぐときに、変数名が適当なテンプレートは読み解くのに時間がかかります。
テキトー教師次が欠損データの処理。さっきも触れましたが、
defaultフィルターは積極的に使うべきです。{{ user.email | default('メールアドレス未登録') }}
{{ score | default(0) | round(2) }}
室谷実運用では、前のノードが「うまく出力できなかった」ケースを想定しておく必要があります。
defaultがあるとその場合でもワークフローが止まらない。
テキトー教師あとはテストを必ずすること。Difyのワークフローにはサンプルデータでのテスト実行機能があります。
エッジケース、たとえば「検索結果が0件だった場合」「スコアがnullだった場合」なども含めてテストしておく。
エッジケース、たとえば「検索結果が0件だった場合」「スコアがnullだった場合」なども含めてテストしておく。
室谷テンプレートのデバッグで便利なのが、テンプレートブロックの出力を「答え」ノードに直接つないで確認する方法ですね。LLMノードを経由せずにテンプレートの出力だけ確認できるので、整形が正しくできているかすぐにわかります。
テキトー教師このやり方、講座で教えると「こんな方法があったんですか」と言われます。デバッグの工数がかなり減りますよ。
テンプレートの一覧管理とチームでの使い方
室谷テンプレートブロックを使いこなしてくると、「よく使うテンプレートを管理したい」という需要が出てきますよね。
テキトー教師Difyには現時点でテンプレート集や一覧管理の専用機能はないので、DSLファイルでエクスポートしてチームで共有するのが現実的です。
室谷MYUUUではGitHubにDifyのDSLファイルを置いて管理してますね。テンプレートから作成した場合もDSLで書き出せるので、バージョン管理しやすいです。
テキトー教師日本語対応のテンプレートを作るとき注意したいのが、Jinja2の変数名に日本語が使えないという点。変数名は英数字とアンダースコアだけにして、表示テキストだけ日本語にするというルールを最初に決めておくといいです。
室谷それは大事なルールですね。日本語テンプレートを作ろうとして、変数名まで日本語にしてエラーになったという話はよく聞きます・・・
テキトー教師Difyのフロントエンドテンプレートという意味では、公式のコミュニティがGitHub上でテンプレートを共有しているので、まずはそこを参考にするのがおすすめです。Difyのアプリ作成画面でも「テンプレートから作成」ボタンがあって、サンプルとして様々な業種・用途のテンプレートが用意されています。
室谷テンプレートボタン機能も覚えておくと便利ですよ。チャットフローのUIにボタンとして選択肢を出せる機能で、ユーザーが入力する代わりにボタンを押すと、そのテキストがプロンプトテンプレートに渡される、という仕組みです。
テンプレートブロックでよくある質問
室谷FAQ的な話もしておきましょうか。「Difyのテンプレート使えない」という声をよく聞くので。
テキトー教師大体パターンが決まっていて、整理するとこうなります。
Q: テンプレートブロックを追加したいがメニューに見当たらない
室谷これはDifyのバージョンやアプリ種別の問題が多いです。チャットボットとチャットフロー、ワークフローで使えるノードが異なります。
テンプレートブロックはワークフローとチャットフローで使えますが、シンプルなチャットボット(チャットフローでない)では一部制限がある場合があります。
テンプレートブロックはワークフローとチャットフローで使えますが、シンプルなチャットボット(チャットフローでない)では一部制限がある場合があります。
テキトー教師バージョンによって機能が増えているので、セルフホスト環境なら最新版にアップデートすることをおすすめします。
Q: Jinjaテンプレートの構文エラーが出る
室谷一番多いのは
入れ子になっていると特に見落としやすい・・・
{% for %}の終了タグ{% endfor %}を書き忘れるケースです。{% if %}も同様で{% endif %}が必要。入れ子になっていると特に見落としやすい・・・
テキトー教師テンプレートの編集画面で見えにくい場合は、一度テキストエディタに貼り付けてインデントを揃えると確認しやすいです。
Q: Dify テンプレート 日本語の文字化けが起きる
テキトー教師これはほぼ発生しませんが、外部からデータを持ってきた際に文字コードがUTF-8でない場合に起きることがあります。HTTPリクエストノードで取得したデータに文字コード変換が必要な場合は、コードブロックで処理してからテンプレートに渡すほうがいいです。
室谷テンプレートブロック自体は日本語を普通に扱えるので、日本語テンプレートという意味では問題ないはずです。変数名だけ英数字にしておけば。
Q: テンプレートブロックの出力をJSONとして次のノードで使いたい
テキトー教師テンプレートブロックの出力はString型です。JSONとして扱いたい場合は、コードブロックで
json.loads()を使って変換するか、パラメータ抽出ノードを使って構造化データとして扱うのが現実的です。
室谷この辺は「テンプレートでJSONを作ったのに、次のノードで変数として使えない」という質問がよく来るパターンですね。String型のJSONとオブジェクト型のJSONは別物として扱われます。
まとめ: テンプレートブロックの使いどころを押さえよう
テキトー教師長かったですが、今回Difyのテンプレートブロックについてかなり詳しく話しましたね。
室谷改めてポイントを整理すると、テンプレートブロックはJinja2テンプレートエンジンを使ったデータ変換ノードで、テキストの動的生成と整形が主な用途です。
テキトー教師コードブロック(Python)と使い分けるなら、テキスト整形・プロンプト構築はテンプレートブロック、数値計算・外部ライブラリ使用が必要な処理はコードブロック、という基準が実践的です。
室谷RAGワークフローでは知識検索ブロックの出力を整形する役割で活躍しますし、LLMノードへのプロンプトを動的に生成する場面では欠かせない存在です。
テキトー教師受講生さんによく言うのが「テンプレートブロックの使いこなしは、Difyの使いこなしそのもの」ということです。ワークフローの品質はここで決まる、くらいに考えてほしいですね。
室谷.AIコミュニティやDifyの学習の場でも、テンプレートブロックを深く学ぶことで一気に上達する人が多いです。ぜひ今回の内容を参考に、自分のワークフローに取り入れてみてください。
