n8nのAI Agent Nodeで18ノード→5ノードに削減!手動実装との比較検証
1. はじめに
この記事は『カンリー Advent Calendar 2025』、12月12日分の記事として執筆しています。
こんにちは。
株式会社カンリーで「カンリー福利厚生」の開発をしている小泉です。
「カンリー福利厚生」ではモバイルアプリとWebアプリにGA4を導入しており、収集したデータはBigQueryにエクスポートしています。分析はRedash上でSQLを書いて行っていますが、新しい分析のたびにSQLを書く必要があること、そしてBigQueryのGA4のデータは構造が複雑でSQL作成のコストが高いことが課題でした。
「SQLを書かずにGA4のデータを分析できたら...」
そんな思いから、自然言語でBigQueryを操作できるSlackbotを作ることにしました。
自然言語でのGA4のデータ分析の手段として、以下などの他の選択肢も考えました。
- ローカルのClaude DescktopやCursorでGoogle Analytics MCPを利用する
- → 各メンバーでセットアップが必要
- 外部サーバーにMCPサーバーを立て、n8nから呼び出す
- → 外部サーバーの保守・管理コストがかかる
今回はチーム全員が手軽に使えること・コストを抑えることを優先し、Slackbotとn8nで構築することを決め、Claude Desktopに相談しながら実装を進めていました。
しかしできあがったワークフローを見ると、複雑で長い、面倒な構成になっていました。

.... そこで思います。
「これ、AI Agent Node使えばもっと簡単にできるのでは?」

AI Agent Node
気になって両方のアプローチで実装してみたところ、手動実装では18ノード必要だった処理が、AI Agent Nodeならたった5ノードで完結することがわかりました。
この経験からAI Agent Nodeが裏側でやってくれていることのありがたみを十分すぎるほど感じたので、手動実装との比較を通じて解説します。
作りたいもの
Slackで自然言語で質問すると、GA4のデータを自動で分析して回答してくれるbotです。

処理の流れは以下です。
- ユーザーがSlackでbotにメンション
「@bot 昨日のアクティブユーザー数は?」
↓ - n8nがSlackからメッセージを受信
↓ - Claudeが質問を解釈し、SQLを生成
↓ - BigQueryでSQLを実行
↓ - Claudeが結果を自然言語で要約
↓ - Slackに回答を返信
「昨日のアクティブユーザー数はxxxx人でした」
2つのアプローチ
| アプローチ | 概要 |
|---|---|
| 手動実装 | Claude APIのTool Use機能を使い、ループ処理を自分で構築 |
| AI Agent Node | n8nのAI Agent Nodeを使い、Tool Useのループを自動処理 |
本記事では、上記2つのアプローチで実装し、速度・コスト・正確性を比較検証した結果をお伝えします。
2. 手動版の実装
構成図

手動版では、Claude APIのTool Use(Function Calling)を自分で制御する必要があります。
Tool Useとは
Claudeに外部ツールを使わせる仕組みです。公式ドキュメントでは以下のように説明されています。
Tool use allows Claude to interact with external services and APIs, fetch data, and perform actions through tools you provide.
(Tool Useを使うと、Claudeは外部サービスやAPIと連携し、提供されたツールを通じてデータを取得したりアクションを実行したりできます。)
例えば「昨日のDAUは?」と質問すると、Claudeは「BigQueryでSQLを実行する必要がある」と判断し、実行すべきSQLを生成して返します。
Tool Useのポイントは、Claudeは「SQLを実行してほしい」というリクエストを返すだけで、実際の実行は行わないということです。そのため、n8n側でSQLを受け取り、BigQueryで実行し、結果をClaudeに返す、という処理を自分で組む必要があります。
さらに複雑な質問では、Claudeが「もう1つデータが必要」と判断して複数回Tool Useを要求することがあります。このループ処理も手動で実装する必要があり、ワークフローが複雑になる原因になっています。
主なノード構成は以下です。
- Slack Trigger - メッセージを受信
- Workflow Configuration - 後方で必要な変数を設定
- Claude API - Generate SQL - SQLを生成
- Check Tool Use - Tool Useかどうか判定
- Extract SQL - レスポンスからSQLを抽出
- BigQuery - SQLを実行
- Aggregate - 結果を集約
- Init Loop State - ループ状態を初期化
- Claude API (Loop) - 追加のTool Useに対応
- Update Loop State - ループ状態を更新
- Slack - Send Response - 結果を送信
合計 約18個のノード が必要でした。
ハマったポイント
1. JSONの構文エラー地獄
n8nのHTTP Request BodyでJSONを書く際、データ型によってクォートの有無を使い分ける必要があります。これで何度もエラーになりました。
| データ型 | 正しい書き方 | 間違い |
|---|---|---|
| 文字列 | "{{ $json.value }}" |
{{ $json.value }} |
| オブジェクト/配列 | {{ $json.object }} |
"{{ $json.object }}" |
例えば、Claude APIのmessagesを組み立てる際:
{
"role": "user",
"content": "{{ $json.user_question }}" // 文字列 → クォートあり
},
{
"role": "assistant",
"content": {{ $json.assistant_content }} // 配列 → クォートなし
}
さらに、Slackから受け取ったメッセージに改行が含まれているとJSONが壊れるため、事前に置換する必要がありました。
{{ $json.user_question.replace(/\n/g, ' ') }}
2. tool_resultのcontent形式
Claude APIの仕様で、tool_resultのcontentは文字列でなければなりません。BigQueryの結果(オブジェクト)をそのまま渡すとエラーになります。
// エラーメッセージ
tool_result.content must be a string or list of content blocks
解決策として、Set Nodeで事前にJSON.stringify()して文字列化し、HTTP Request Bodyではクォートで囲みます。
// Set Node
bq_result: {{ JSON.stringify($json.results) }}
// HTTP Request Body
"content": "{{ $json.bq_result }}" // クォートで囲む
3. ループ処理で .first() と .last() を間違える
複数回のTool Useに対応するためループ処理を実装したのですが、loop_countがいつまでも更新されない問題が発生。原因は.first()を使っていたことでした。
// ❌ 常に初回の値を取得してしまう
const loopCount = $('Init Loop State').first().json.loop_count;
// ✅ 最新の値を取得
const loopCount = $('Init Loop State').last().json.loop_count;
n8nでは同じノードが複数回実行された場合、.first()は最初の実行結果、.last()は最新の実行結果を返します。ループ処理では.last()を使う必要があります。
4. BigQueryで日本語エラー
Claudeが生成したSQLに日本語が含まれると、BigQueryでエラーになりました。
-- ❌ エラー
SELECT COUNT(*) AS ユーザー数
-- ✅ OK
SELECT COUNT(*) AS user_count
システムプロンプトで「SQLには日本語を使用しないでください」と指示することで解決しました。
実装時間
Slack AppsやBigQueryのOAuth周りも含みますが、実装には約4〜5時間ほどかかりました。
3. AI Agent版の実装
構成図
さて、エラーハンドリングに苦しんだ手動実装も終わったところで、AI Agent Nodeで書き直してみます。
出来上がったワークフローがこちら↓

驚くほどシンプルです。
解説も不要かもしれないですが、ノード構成は以下です。
- Slack Trigger - メッセージを受信
- Workflow Configuration - 変数を設定
- Prepare AI Prompt - プロンプトを準備
- AI Agent - AIエージェント(BigQuery Toolを内蔵)
- Slack - Send Response - 結果を送信
合計 約5個のノード で完成しました。
設定のポイント
1. BigQuery用のサブワークフロー
AI Agent NodeからBigQueryを直接呼び出すため、サブワークフローを作成しました。

なぜサブワークフローが必要か?
AI Agent NodeのToolには「Google BigQuery Tool」も存在しますが、SQLを固定値でしか設定できず、AIが動的にSQLを生成して渡すことができませんでした。
そのため、「BigQueryを実行するだけのサブワークフロー」を作成し、それをCall n8n Workflow Toolで呼び出す構成にしています。
各ノードの役割
| ノード | 役割 |
|---|---|
| Execute Workflow Trigger | AI Agentから呼び出されたときに、queryパラメータでSQLを受け取る |
| Google BigQuery | 受け取ったSQL({{ $json.query }})を実行し、結果を返す |
サブワークフローは2ノードだけなので、1分で作成できます。
2. Call n8n Workflow Tool の設定
| 設定 | 値 |
|---|---|
| Name | run_bigquery |
| Description | Execute a SQL query against BigQuery to retrieve GA4 analytics data... |
| Workflow | BigQuery Executor |
3. 手動版で苦労したポイントはどうなった?
手動版で苦労した4つのポイントが、AI Agent版ではどうなったかを比較します。
| ポイント | 手動版 | AI Agent版 |
|---|---|---|
| JSONの構文エラー | クォートの有無を細かく制御 | 発生しない(自動処理) |
| tool_resultのcontent形式 | JSON.stringifyで文字列化 | 不要(自動処理) |
| ループ処理(loop_count) | 自分で実装・管理 | Max Iterationsを設定するだけ |
| BigQueryのエラーハンドリング | Continue On Failを設定し、エラー情報をClaudeに渡す処理を実装 | 自動(エラーもClaudeに渡される) |
つまり、手動版で苦労したポイントはすべてAI Agent Nodeが自動で処理してくれます。
特に大きいのは以下の2点です:
-
ループ処理が簡単
- 手動版では「Claudeが追加のデータを要求した場合にループを回す」処理を自分で実装しました。loop_countの管理、messagesの蓄積、
.first()と.last()の使い分けなど。AI Agent Nodeでは、Options内のMax Iterationsを設定するだけで、Tool Useのループ回数を制限でき、無限ループの心配も不要です。
- 手動版では「Claudeが追加のデータを要求した場合にループを回す」処理を自分で実装しました。loop_countの管理、messagesの蓄積、
-
JSONの構文エラーが起きない
- 手動版では「文字列はクォートあり、オブジェクトはクォートなし」というルールを理解するのに時間がかかりました。AI Agent Nodeではこのような処理を意識する必要がありません。
4. 唯一の手動設定:システムプロンプト
AI Agent版で唯一設定が必要なのは、システムプロンプトです。
手動版と同様に、以下の点をプロンプトに含めました。
- BigQueryのテーブル構造
- SQLには日本語を使用しないルール
あなたはGA4分析アシスタントです。
【データベース情報】
- テーブル: project.dataset.events_*
- 日付フィルター: _TABLE_SUFFIX を使用
【ルール】
1. SQLのカラム名、エイリアス、文字列リテラルには日本語を使用しないでください
2. 英語のみを使用してください
3. 期間指定がない場合は過去7日をデフォルトとする
4. 最終回答は日本語でわかりやすく
システムプロンプトさえ適切に設定すれば、あとはAI Agent Nodeにお任せです。
実装時間
約30分〜45分であっけなく完成しました。
4. 比較検証
目的
上記までの実装工数に加えて、ワークフローとしての精度から手動版とAI Agent版、どちらを使うべきか判断するために、以下の観点で比較検証を行いました。
| 観点 | 検証内容 |
|---|---|
| 動作の正確性 | 同じ質問に対して正しく回答できるか |
| レスポンス時間 | 質問してから回答が返るまでの時間 |
| トークン消費量 | Claude APIの利用コストに直結する指標 |
| Tool Use回数 | BigQueryが何回実行されるか |
結果
結論:ほとんどのケースでAI Agent版が優秀
| 観点 | 勝者 | 理由 |
|---|---|---|
| レスポンス時間 | AI Agent | 複雑な質問で2〜3倍速い |
| トークン消費量 | AI Agent | 複雑な質問で最大62%削減 |
| Tool Use回数 | AI Agent | 無駄なAPI呼び出しが少ない |
| 正確性 | 引き分け | どちらも同等の精度 |
手動版が勝るのは「シンプルな質問のレスポンス時間」くらいで、実用上はAI Agent版を選ぶべきという結果になりました。
以下、詳細な検証結果を見ていきます。
テストパターン
難易度の異なる4パターンの質問で検証しました。
| パターン | 質問 |
|---|---|
| シンプル | 一昨日のアクティブユーザー数は? |
| 中程度 | 直近30日間でクリックされている店舗ピンのうち上位10店舗を教えて |
| 複雑 | 直近1週間で、新規ユーザーと既存ユーザーそれぞれの店舗ピンのクリック数を比較して |
| 曖昧 | 経路案内ボタンのクリック数を集計して |
結果の比較表
レスポンス時間
| パターン | 手動版 | AI Agent版 | 勝者 |
|---|---|---|---|
| シンプル | 12.1秒 | 19.4秒 | 手動 |
| 中程度 | 1分26秒 | 33秒 | AI Agent |
| 複雑 | 1分10秒 | 39秒 | AI Agent |
| 曖昧 | 2分24秒 | 45秒 | AI Agent |
Tool Use回数
| パターン | 手動版 | AI Agent版 |
|---|---|---|
| シンプル | 1回 | 1回 |
| 中程度 | 9回 | 3回 |
| 複雑 | 5回 | 3回 |
| 曖昧 | 5回 | 4回 |
トークン消費量
| パターン | 手動版 (Input/Output) | AI Agent版 (Input/Output) |
|---|---|---|
| シンプル | 1,416 / 258 | 2,320 / 1,281 |
| 中程度 | 22,664 / 3,164 | 8,034 / 1,657 |
| 複雑 | 11,034 / 2,625 | 8,992 / 1,716 |
| 曖昧 | 8,948 / 1,631 | 11,070 / 1,734 |
正確性
| パターン | 手動版 | AI Agent版 |
|---|---|---|
| シンプル | ⭕️ | ⭕️ |
| 中程度 | ⭕️ | ⭕️ |
| 複雑 | ⭕️ | ⭕️ |
| 曖昧 | ⭕️ | △ |
考察
1. 複雑な質問ほどAI Agentのほうが速い
手動版では不要なTool Useが発生し、ループ処理のオーバーヘッドが大きくなりました。AI Agentは少ないTool Useで処理が完了したため、その分レスポンス速度が速くなっていました。
2. トークン効率もAI Agentが優秀
中程度の質問で、手動版は22,664トークン、AI Agent版は8,034トークンと、約65%の削減に成功しています。
3. 曖昧な質問では手動版が安定
「経路案内ボタン」のような曖昧な質問では、手動版の方が適切に解釈できました。しかしこれはシステムプロンプトの調整で改善できる可能性があるので、そこまで問題にはならないと考えます。
5. 使い分けガイド
AI Agentが向いているケース
| ケース | 理由 |
|---|---|
| 素早くプロトタイプを作りたい | 実装時間が1/8(30分 vs 4時間) |
| 複雑な質問が多い | 速度・トークン効率が良い |
| 保守性を重視する | ノード数が少なく管理しやすい |
| 複数のToolを使いたい | Tool追加が簡単 |
手動実装が向いているケース
| ケース | 理由 |
|---|---|
| 処理の途中経過をSlackに通知したい | 細かい制御が可能 |
| SQLの検証・ブロックが必要 | 実行前にチェックを挟める |
| 詳細なログを残したい | 各ステップで記録可能 |
| シンプルな質問のみ | トークン消費が少ない |
6. まとめ
AI Agent Nodeは何をやってくれているのか
今回の検証を通じて、AI Agent Nodeが10数ノード分の処理を自動化してくれていることがわかりました。
| 処理 | 手動だと... | AI Agent Nodeなら |
|---|---|---|
| Tool Useのループ | loop_count管理、messages蓄積、.first()/.last()の使い分け |
自動(Max Iterations設定のみ) |
| JSONの構文制御 | クォートの有無を細かく制御 | 意識不要 |
| tool_resultの形式変換 | JSON.stringifyで文字列化 | 自動 |
| エラーハンドリング | Continue On Fail設定、エラー情報の受け渡し | 自動 |
比較結果
| 項目 | 手動版 | AI Agent版 |
|---|---|---|
| ノード数 | 18個 | 5個 |
| 実装時間 | 4〜5時間 | 30分 |
| レスポンス(複雑な質問) | 1分10秒〜2分24秒 | 33秒〜45秒 |
| トークン消費(複雑な質問) | 多い | 最大62%削減 |
最後に
手動で実装を進めた結果「これAI Agent Nodeでよくない?」と気づいて検証してみたら、案の定AI Agent Nodeの方が優秀でした。
最初からAI Agent Nodeを使っていれば4時間も悩まずに済んだと思いますが、手動で実装したからこそ「AI Agent Nodeが裏側で何をやってくれているのか」を理解できました。
n8nでAI連携ワークフローを作ろうとしている方へ。
まずはAI Agent Nodeを試してください。
もしAIがAI Agent Nodeを使わない実装を勧めてきたら「それAI Agent Nodeでよくない?」と聞いてみてください。
手動実装はその後検討することをおすすめします。
参考リンク
株式会社カンリーは「店舗経営を支える、世界的なインフラを創る」をミッションに、店舗アカウントの一括管理・分析SaaS「カンリー店舗集客」の開発・提供、他複数のサービスを提供しております。 技術系以外のnoteはこちらから note.com/canly
Discussion