bbizinets.life
n8nのワークフロー設計で最初に決めるべきデータ構造|LLMパイプライン設計の基本
判断設計

n8nのワークフロー設計で最初に決めるべきデータ構造|LLMパイプライン設計の基本

# n8nのワークフロー設計で最初に決めるべきデータ構造|LLMパイプライン設計の基本

n8nでLLMを使ったワークフローを作ろうとしたとき、「どのノードを使うか」より先に考えることがあります。それがデータの流れの設計です。

「どこでデータが消えるのか」「なぜ参照できないのか」「Mergeを通ったらおかしくなった」——これらの詰まりは全て、データ設計を後回しにしたことで起きます。

この記事では、私が実際にLLMパイプラインを構築した経験から、最初に決めるべきデータ設計の考え方と、設計→ノードという順番で進める具体的なパターンを整理しています。

結論|ノードではなく「データの流れ」から設計する

n8nで詰まる人の多くは「どのノードを使うか」から考え始めます。しかしLLMを複数使うパイプラインでは、この順番が詰まりの原因になります。

正しい順番は逆です。

先に「何のデータが、どこからどこへ流れるか」を決める。その後でノードを選ぶ。

ここでいう「データ設計」とは、各ノードが受け取るフィールド名・型・構造を事前に書き出しておくことです。

なぜかというと、n8nのノードは「前のノードから来たデータをそのまま使う」という前提で動きます。データの構造が決まっていなければ、ノードをいくら正しく設定しても参照できないフィールドが出てきます。

設計の順番:

  1. 最終的に何のデータが必要か(出力の定義)
  2. そのために途中で何を持ち回るか(中間データの定義)
  3. 最初に何が入力されるか(入力の定義)
  4. 上記3つが決まってからノードを並べる

この順番でワークフローを設計すると、Codeノードで何をすべきかが自然に決まります。

なぜn8nは詰まりやすいのか

n8nの設計でよく起きる詰まりには、2つの思考パターンが関係しています。

ノード中心思考

「OpenAIノードを使う → Mergeで統合する → Codeノードで処理する」という形で、ノードの名前から発想する設計です。

このアプローチの問題は、各ノードが「何を受け取って何を返すか」を先に確認しないまま繋いでしまうことです。LLMノードはoutput[0].content[0].textという深い階層でテキストを返しますが、ノード中心思考で設計すると「$json.textで取れるはず」という誤った前提でコードを書いてしまいます。

データを無視した接続

「繋いでみてから動かして確認する」という進め方も詰まりの原因です。

n8nはノード間でデータが正しく流れていなくてもエラーを出さないケースがあります。空のデータ・undefinedのフィールド・nullのままでも次のノードが実行されます。動いているように見えて、実際には意図したデータが流れていないという状態が発生します。

LLMパイプラインで起きる設計ミス

私が実際に経験した設計ミスを3つ整理します。これらは全てデータ設計を後回しにしたことで起きました。

正直、どのミスも「なぜ動かないのか」が最初はわからず、かなり時間を使いました。

ミス①:データ消失(LLMノードの引き継ぎ忘れ)

LLMノードは「自分への回答」しか返しません。前のノードで持っていたkeywordやslugなどのデータは、LLMノードの出力には含まれません。

LLMノードを通るたびに上流のデータが消えます。Codeノードで明示的に引き継がなければ、後続のノードからは参照できません。

  • 数値:4つのLLMノードのうち2番目でデータ消失が発生・30分以上原因特定できず
  • 構造分析:LLMは自分への回答しか返さない仕様のため、上流データは自動では引き継がれない
  • 判断基準:LLMノードの後でデータが取れない場合 → OUTPUTタブで出力フィールドを確認する

詳しくは「n8nでLLMノードを連続接続するとデータが壊れる原因とCodeノードによる解決」で整理しています。

ミス②:参照不可(Mergeの結合方式の誤解)

Mergeノードで4ファイルを統合しようとしたとき、Combine/Positionで設定すると4アイテムが横結合されて1アイテムに圧縮されました。全てのファイルがdataフィールドを持つため、最後の1件だけが残りました。

原因: 縦結合と横結合の違いを理解せずにMergeノードを設定した

詳しくは「n8nで複数ファイル取得ができない原因|Merge・gzip・Codeノードで詰まった全記録」で整理しています。

ミス③:構造不一致(LLMの出力形式の想定ミス)

LLMにJSON形式で出力するよう指示したつもりが、実際の出力は `json ... ` のマークダウン形式で返ってきました。JSON.parse()に渡すとエラーになります。

また、LLMが返したプロンプトの構造が既存の設計ファイルと全く違う形になっていたというケースもありました。「動いているが正しくない」という状態です。

原因: LLMの出力形式を事前に定義してから処理を設計しなかった

最初に決めるべきデータ設計

「3つのミスを全て経験してから気づいたことがあります。どれも設計を先に決めていれば発生しなかった詰まりでした。」——では具体的に何を先に決めればいいのでしょうか。

上記のミスを避けるために、ワークフロー構築前に以下の3つを書き出します。

入力データの定義

ワークフローに最初に入ってくるデータを定義します。

{
  "keyword": "n8n データ設計",
  "intent": "LLMパイプラインの設計方法を知りたい",
  "slug": "n8n-data-structure-workflow-design"
}

何がどのフィールド名で入ってくるかを先に決めておくことで、後続のノードでの参照方法が決まります。

中間データの定義

各LLMノードを通過した後に何を持ち回るかを定義します。

{
  "keyword": "...",
  "intent": "...",
  "slug": "...",
  "market_research": { ... },
  "context": { ... },
  "design_output": "..."
}

ポイントはLLMを通るたびに上流のデータを引き継いで加算していくことです。LLMの出力だけを返すのではなく、それ以前のデータも一緒に返します。

出力データの定義

最終的に後続の処理(Slack送信・WP投稿など)が必要とするデータを定義します。

{
  "keyword": "...",
  "slug": "...",
  "interview_questions": "...",
  "design_output": "..."
}

出力を先に定義することで「このデータを作るには途中で何が必要か」が逆算できます。

実際の設計パターン(私のパイプライン構成)

私が構築した記事自動生成パイプラインでは、以下のようなデータ設計を先に決めてからノードを並べました。

入力(keyword_queue.csvから取得):

keyword / intent / slug

並列ファイル取得後の統合(Codeノード):

keyword / intent / slug
+ create_article_data(プロンプトファイル)
+ internal_links_data(内部リンク候補)
+ title_rules_data(タイトルルール)
+ index_data(投稿済み記事一覧)

市場調査LLM通過後(Codeノード):

上記全て
+ market_research(競合分析・gap・attack_angle)

記事設計LLM通過後(Codeノード):

keyword / intent / slug
+ market_research
+ internal_link_candidates(絞り込み済み3件)
+ design_output(記事設計サマリ)

インタビュー生成LLM通過後(Slackへ):

keyword / slug / design_output / interview_questions

各LLMノードの後にCodeノードを置き、「次のノードが必要とするデータだけを選んで渡す」という設計です。これにより各Codeノードが翻訳層として機能し、データの消失を防ぎます。

判断基準:

  • LLMノードを追加するたびにCodeノードとセットで考える
  • Codeノードで返すフィールドは「次のノードが参照するもの」に絞る
  • 上流データを引き継ぐ場合は$('ノード名').first().jsonで明示的に参照する

判断基準|設計→ノードの順で考える

データ設計を先に決めることで、以下の判断が自然にできるようになります。

「このLLMの出力から何を取り出すか」を先に決める

LLMノードを追加するとき、まず「このノードの出力から何のフィールドを取り出すか」を決めます。その後でCodeノードのコードを書きます。コードを書いてから何が取れるか確認するのは逆順です。

「次のノードに何を渡すか」を先に決める

Codeノードで返すjsonの形を先に書き出します。return [{ json: { ... } }]の...の部分を先に定義することで、コードの目的が明確になります。

「ここで詰まったらデータを確認する」という習慣

詰まったときは接続やノードの設定を疑う前に、OUTPUTタブでデータの構造を確認します。意図したフィールドが存在するか・値が正しいかを確認することが、最も速い原因特定につながります。

この後どうなったか・よくある質問

このデータ設計を先に決める習慣を持ってからは、新しいLLMノードを追加するときの詰まりが大幅に減りました。「このノードが何を受け取って何を返すか」が明確になっているため、Codeノードを書くときに何をすべきかが迷わずに決まります。

現在は同じ設計パターンをbizinets.biz・jogtime.jp・bizinets.lifeの3サイト向けパイプラインに展開しています。

Q. データ設計を先に書き出すのはどのタイミングですか?

ワークフローを新しく作り始める前と、既存のワークフローに新しいLLMノードを追加する前の2つのタイミングです。既存のワークフローを修正する場合は、まず現在のデータフローを図に書き出してから変更箇所を特定します。

Q. Codeノードで返すフィールドが多くなりすぎる場合はどうすればいいですか?

次のノードが実際に参照するフィールドだけに絞ります。「念のため持っておく」フィールドはデータが肥大化して管理しにくくなります。各Codeノードで「ここから先は何が必要か」を都度判断して、不要なフィールドは返さないのが原則です。

まとめ

n8nでLLMパイプラインを設計するときの基本を整理します。

  • ノードを先に決めない。データの流れを先に決める
  • 入力・中間・出力の3つを書き出してからノードを並べる
  • LLMノードの後には必ずCodeノードを置いて翻訳・整形する
  • 詰まったらOUTPUTタブでデータの構造を確認する
  • 「設計→ノード」の順番を守ることで詰まりが大幅に減る

今日から試せる一歩として、既存のワークフローを開いて各Codeノードが「何を受け取って何を返しているか」を書き出してみてください。データの流れが可視化されるだけで、次に何を改善すべきかが見えてきます。

ここまで整理したデータ設計の考え方は、n8nというツールの話ではありません。「何を先に決めるか」という判断の順番の話です。
ワークフロー設計と判断設計の関係を整理したい方は、こちらをご覧ください。

→ AIの設計を鵜呑みにしたら既存と違っていた理由

bizinets.biz

記事を読んで「もっと知りたい」と思ったあなたへ

bizinets.biz では、ビジネスの仕組みづくりを体系的に学べるコンテンツを用意しています。まずは一度、覗いてみてください。

bizinets.biz へ行く →