ガイド2026年4月2日

DifyのテンプレートブロックとJinja2を完全解説:RAG・ループ・コードブロックとの使い分けまで

室谷東吾
監修者室谷東吾(@0x__tom

株式会社MYUUU 代表取締役 / 日本最大級AIコミュニティ「.AI」創設者(累計2,000名超)/ セプテーニ・ホールディングス(電通グループ)と資本業務提携 / 著書「お金を使わず、AIを働かせる『Dify』活用」(ぱる出版、3刷)/ Xフォロワー約2万人

テキトー教師
監修者テキトー教師(@tekitoo_T_cher

.AI 認定講師 / 教育×AIの専門家 / 累計300名以上にAI活用を指導 / 「テキトーに学ぶ」がモットーの実践派講師 / Xアカウント

DifyのテンプレートブロックとJinja2を完全解説:RAG・ループ・コードブロックとの使い分けまで

Difyのテンプレートブロックとは?Jinja2を使ったデータ変換の全貌

室谷室谷
今回はDifyのテンプレートブロックを深掘りしていきましょう。これ、Difyワークフローを組んでいると必ず出てくるのに「なんとなく使ってる」で終わってる人が多いんですよね・・・
テキトー教師テキトー教師
ほんとそうです。講座でDifyのワークフローを教えていると、テンプレートブロックって「変数を結合するだけのもの」だと思っている受講生さんがめちゃくちゃ多い。

でも実際はもっと奥が深い。
室谷室谷
Jinja2テンプレートエンジンが使えるんですよね。Pythonをやったことがある人なら馴染みがあると思いますが、ループや条件分岐まで書けるので・・・
テキトー教師テキトー教師
そうなんです。整理すると、Difyのテンプレートブロックには大きく2種類の使い方があるんですよね。

「データを整形して次のノードに渡す」シンプルな使い方と、「ループや条件分岐を駆使した高度なデータ変換」をする使い方。
室谷室谷
MYUUUでもDifyを使った業務自動化をかなりやってますけど、テンプレートブロックが一番活躍するのは「LLMノードに渡すプロンプトを動的に生成する」場面ですね。
テキトー教師テキトー教師
まさにそれです。RAGワークフローでもプロンプトテンプレートとして活用できますし、ナレッジパイプラインの中でもテンプレートブロックが要所要所に入ってくる。

知識検索ブロックと組み合わせると、検索結果をきれいに整形してLLMに渡せるんですよ。
室谷室谷
というわけで今回は、テンプレートブロックの基礎から実践的な使い方まで、かなり細かく解説していきます。コードブロック(Python)との違いも含めて。

テンプレートブロックの基本: Jinja2テンプレートとは何か

DifyのテンプレートノードUI(公式ドキュメントより)

テキトー教師テキトー教師
まず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に渡す、という流れを作ります。

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のナレッジパイプラインではこういう流れになります。
  1. ユーザーの質問を知識検索ブロックに渡す
  2. 検索結果(複数のチャンク)が返ってくる
  3. テンプレートブロックで検索結果を整形する
  4. 整形されたコンテキストをLLMノードのプロンプトに埋め込む
室谷室谷
ステップ3がまさにテンプレートブロックの出番ですよね。検索結果をそのままLLMに渡すより、番号を振って「参考情報1: ...」のような形に整形してから渡すほうが、LLMの回答精度が上がります。
テキトー教師テキトー教師
この点、「RAGの精度が上がらない」と相談されたとき、テンプレートブロックの整形を見直してもらうだけで改善することが多いです。知識検索の精度を上げようとチャンクサイズや埋め込みモデルをいじる前に、テンプレートの設計を確認してほしいですね。
室谷室谷
まさに。.AIコミュニティでも毎週聞かれる質問なんですけど、「RAGが使えない」という人の半数くらいはテンプレートの問題だったりします。

ループブロックとテンプレートブロックの連携

室谷室谷
Difyのループブロックとテンプレートブロックを組み合わせると、さらに強力になるんですよね。
テキトー教師テキトー教師
ループブロックは「繰り返し処理」をするためのノードで、テンプレートブロックはその中で「各繰り返しの出力を整形する」役割を担うことが多いです。
室谷室谷
具体的には、たとえば複数の商品データがあって、各商品の説明文をLLMで生成したい場合。ループブロックで商品リストを回して、各商品のデータをテンプレートブロックでLLMへのプロンプトに整形してから渡す、という流れです。
テキトー教師テキトー教師
反復処理(イテレーション)ノードもよく似た用途で使われますが、ループブロックは終了条件を自分で設定できる点が違いますね。テンプレートブロックは終了条件の判定にも使えて、ループの各反復で処理した結果をカウントするようなテンプレートを書けます。
室谷室谷
ループブロックの中でテンプレートブロックを使うときのコツとして、前の反復の結果を次の反復で参照する「累積パターン」があります。
{% for item in previous_results %}
{{ loop.index }}. {{ item }}
{% endfor %}

新しい結果: {{ current_result }}
テキトー教師テキトー教師
この累積パターン、最初はハマりやすいですが慣れると便利です。ループブロックの変数の渡し方を理解することがポイントです。

テンプレートブロックのよくあるエラーと対処法

DifyのコードノードUI(公式ドキュメントより)

テキトー教師テキトー教師
実践でよく起きるエラーと対処法もまとめておきましょう。
室谷室谷
これ、.AIコミュニティのメンバーから一番多く質問が来る部分ですよね。
テキトー教師テキトー教師
まずよくある問題と解決策をまとめるとこうなります。
エラー原因対処法
変数が空になる前ノードの出力変数名が異なるテンプレートの入力変数設定を確認
テンプレート構文エラー{{ }}{% %}の閉じ忘れ構文を再確認、特にループや条件分岐の終了タグ
型エラー文字列に数値フィルターを適用defaultで空値を処理してから変換
出力が長すぎるテンプレートの出力が80,000字を超過テンプレートの内容を分割するか短縮
JSONが壊れるテキスト内の特殊文字未エスケープreplaceフィルターでエスケープ処理
室谷室谷
出力の80,000字制限は意外と知られていないんですよね。大量のドキュメントをテンプレートでループ処理しようとして引っかかることがあります。
テキトー教師テキトー教師
その場合はテンプレートブロックを分割するか、コードブロックに切り替えることを検討してください。コードブロックも同じく80,000字制限がありますが、処理の分割はしやすいです。
室谷室谷
あとDifyのテンプレートブロックとは直接関係ありませんが「ドキュメントのインデックス作成に失敗しました」というエラーについて、混同される方もいるので補足しておくと・・・
テキトー教師テキトー教師
これはナレッジ機能でファイルのインデックスを作るときのエラーですね。ファイル形式やサイズの問題、あるいは埋め込みモデルの設定ミスが多いです。

テンプレートブロックの問題とは別ですが、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_querysearch_resultsのような名前にすることで、テンプレートを後から見たときに何をしているか一目でわかる。
室谷室谷
これ地味に重要で・・・。MYUUUでもDifyワークフローの保守を引き継ぐときに、変数名が適当なテンプレートは読み解くのに時間がかかります。
テキトー教師テキトー教師
次が欠損データの処理。さっきも触れましたが、defaultフィルターは積極的に使うべきです。
{{ user.email | default('メールアドレス未登録') }}
{{ score | default(0) | round(2) }}
室谷室谷
実運用では、前のノードが「うまく出力できなかった」ケースを想定しておく必要があります。defaultがあるとその場合でもワークフローが止まらない。
テキトー教師テキトー教師
あとはテストを必ずすること。Difyのワークフローにはサンプルデータでのテスト実行機能があります。

エッジケース、たとえば「検索結果が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の学習の場でも、テンプレートブロックを深く学ぶことで一気に上達する人が多いです。ぜひ今回の内容を参考に、自分のワークフローに取り入れてみてください。

出典・参考資料

.AI TIMES一覧に戻る