n8nでAIエージェントを作る:ChatGPT・Claude・Geminiをつなぐ

公開 書いた人 大林 諒

n8nでは、ChatGPTのOpenAI、ClaudeのAnthropic、Google Gemini、手元で動かすOllamaを、同じ画面でワークフローに組み込めます。この記事では「問い合わせ受付」に、種類をLLMで判定してSlackの送り先を変える機能、社内のよくある質問に答えるチャット、社内資料を読ませて答えさせる仕組みの3つを足します。読み終わると、AIノードのどれをどこに使うかを決められ、費用が膨らむ前に止める設定まで入った状態になります。前提は、Webhookで受けた問い合わせをスプレッドシートとSlackに流すところまでできていることです。画面と設定項目は2026年10月時点の安定版2.44.7で確認しています。

この記事の内容
  1. 先に決めること
  2. AIノードの全体像と使い分け
  3. LLMの選び方
  4. 手順1:問い合わせの種類で Slack の送り先を変える
  5. 手順2:社内のよくある質問に答えるチャットを作る
  6. 手順3:社内資料を読ませて答えさせる(RAG)
  7. 応用
  8. 費用と暴走を防ぐ
  9. できないことと、その代わり
  10. よく詰まるところ
  11. 次にやること

先に決めること

AIにやらせるのは「判断」だけにする

問い合わせ受付でAIが要るのは「見積もり依頼か、不具合の報告か」を読み取るところだけです。シートへの書き込みや件数の集計は普通のノードでやります。全部を任せると結果が揺れて、原因を追えません。本番では、AIの出番は1か所に絞るほうが直しやすいです。

流れを固定するか、AIに道を選ばせるか

入力と出口が決まっている処理はチェーン系(Text Classifier など)、質問の中身で調べ先が変わる処理はエージェント系(AI Agent)を使います。エージェントは1回の実行でLLMを何度も呼ぶので、費用も時間もかさみます。

データをどこへ送ってよいか、誰のキーで払うか

クラウドのLLMを使えば、問い合わせ本文は各社のAPIに送られます。外に出せない情報があるなら、送る前に伏せるか、Ollamaで社内のサーバーから出さない構成にします。費用は自前のAPIキーを認証情報(Credentials)に登録して払うのが基本です。n8n Cloud の Starter と Pro では、APIキーなしで「Gateway credits」(n8n経由の前払いクレジット)を使ってOpenAI・Anthropic・Geminiを呼ぶ方法もあります(2.36.0以降。Enterprise Cloud とセルフホストでは使えません)。残高が0になるとそのノードは止まります。

人の確認をどこに挟むか

メール送信や顧客管理の更新のように、外れたら困る出口の手前には人の承認を入れます。社内の通知だけなら、外れても担当者が気づけるので挟みません。

AIノードの全体像と使い分け

n8nのAIノードは、主役になる「ルートノード」に、部品の「サブノード」を下からつなぐ形をしています。たとえば AI Agent ノードの下に、Chat Model(どのLLMを使うか)、Memory(会話の記憶)、Tool(使ってよい道具)をつなぎます。

ルートノードやること会話の記憶ツール問い合わせ受付での使い所
AI Agentツールを選んで使いながら答えを作るつなげるつなげる社内のよくある質問に答えるチャット、資料を調べて答える
Basic LLM Chain1回の指示に1回答えるつなげないつなげない問い合わせの要約、返信文の下書き
Text Classifier決めたカテゴリのどれかに振り分け、カテゴリごとに出口を分けるつなげないつなげない見積もり/不具合/採用/営業売り込みの振り分け
Information Extractor文章から決めた項目を抜き出して構造化するつなげないつなげない会社名・人数・希望時期を抜き出してシートの列に入れる

ほかに Question and Answer Chain(資料検索)、Summarization Chain(要約)、Sentiment Analysis(感情判定)があります。サブノードは次のとおりです。

サブノード役割代表的なノード
Chat Model使うLLMOpenAI Chat Model、Anthropic Chat Model、Google Gemini Chat Model、Ollama Chat Model
Memory会話の履歴を持つSimple Memory、Postgres Chat Memory、Redis Chat Memory
Toolエージェントが使う道具Call n8n Workflow Tool、HTTP Request、Google Sheets、MCP Client Tool
Output Parser出力の形を決めるStructured Output Parser
Embeddings文章をベクトルに変えるEmbeddings OpenAI、Embeddings Ollama
Document Loader と Text Splitter資料を読み込んで細かく切るDefault Data Loader、Recursive Character Text Splitter
AI Agent ノードの下に Chat Model・Memory・Tool の接続口が並んでいるキャンバス
AI Agent ノードの下に Chat Model・Memory・Tool の接続口が並んでいるキャンバス

調べ先を状況で変えたいときだけ AI Agent を使います。全部を任せると費用と揺れが増えます。

LLMの選び方

4社とも専用の Chat Model ノードがあります。AI Agent に使うモデルは、ツール呼び出しに対応したものを選びます。

OpenAIAnthropicGoogle GeminiOllama
ノードOpenAI Chat ModelAnthropic Chat ModelGoogle Gemini Chat ModelOllama Chat Model
認証情報OpenAI(API Key)Anthropic(API Key)Google Gemini(PaLM) Api(API Key)Ollama(Base URL)
キーの取り方の入口OpenAIの管理画面の「API keys」ページで「Create new secret key」Anthropic Console の「Settings > API Keys」で「+ Create Key」Google AI Studio の API Key ページで「Create API Key」キー不要(認証付きプロキシを通すときだけ)
向く場面迷ったらここ長い文章の読み取り無料枠で試したいとき社外に出せないデータ
注意組織が複数あると Organization ID が要るモデルは実画面の一覧から選ぶ無料枠は送った内容が製品改善に使われるマシンの性能が要る

料金はどの社もトークン(文字のかたまり)単位の従量で、入力と出力で単価が分かれ、OpenAIとAnthropicは100万トークンあたりのドル建てです。単価は改定が多いので、各社の公式の料金ページで確かめます。Geminiの料金ページには、無料枠では送った内容が製品改善に使われ、有料枠では使われないとあります。問い合わせ本文を流すなら有料枠にします。

Ollama は無料ですが、動かすのは自分のマシンです。月額1,000〜2,000円台のVPSでn8nと同居させるとメモリが足りないので、別のマシンに置きます。

手順1:問い合わせの種類で Slack の送り先を変える

今の「問い合わせ受付」は、Webhook で受けた内容を Google Sheets の「Append Row」(行を追加)で「問い合わせ一覧」に書き、Slack の #問い合わせ に送っています。ここに Text Classifier を挟み、4種類に振り分けて送り先を変えます。

種類説明(Descriptionに書く文)送り先
見積もり料金・見積もり・導入の相談#問い合わせ-営業
不具合利用中のサービスが動かない・ログインできない#問い合わせ-サポート
採用求人への応募、採用に関する質問#採用
営業売り込み先方が自社の商品やサービスを売り込む連絡送らずシートに残す

認証情報を作る

  1. 「Overview」の「Credentials」タブを開き、「Create credential」を押す。
  2. 使うLLMの認証情報(ここでは OpenAI)を選ぶ。
  3. 取得したAPIキーを「API Key」に貼って保存する。

Text Classifier を置く

  1. Webhook と Google Sheets の間の線にある「+」を押し、「Text Classifier」を追加する。
  2. 「Text to Classify」に次の式を入れる。フォームの項目名は自社のものに合わせる。
件名:{{ $json.body.subject }}
本文:{{ $json.body.message }}
  1. 「Categories」で「Add Category」を押し、上の表の4種類を1つずつ登録する。「Category」に種類名、「Description」に説明を書く。
  2. 「Add Option」から「When No Clear Match」を追加し、「Output on Extra, ‘Other’ Branch」にする。
  3. ノードの下の「Model」の「+」を押し、「OpenAI Chat Model」を追加する。
  4. 「Credential」で手順の最初に作った認証情報を選ぶ。
  5. 「Model」で使うモデルを選び、「Options」の「Sampling Temperature」を0にする。
Text Classifier の Categories に4種類と Description を入れたところ
Text Classifier の Categories に4種類と Description を入れたところ

Description は省略しません。名前だけだと営業売り込みの「御社のサービスを見積もりたい」が見積もりに入ります。誰が何を求めているかで書くと分かれます。

When No Clear Match の既定は「Discard Item」(捨てる)で、どれにも当てはまらない問い合わせが黙って消えます。必ず Other の出口を作り、今までどおり #問い合わせ に送ります。

出口ごとに Slack を分ける

  1. Text Classifier に出口が5つ(4種類と Other)あることを確かめる。
  2. 見積もりの出口に Slack ノードを追加し、「Resource」を Message、「Operation」を Send にして送り先を #問い合わせ-営業 にする。
  3. 不具合・採用・Other も同じように Slack ノードをつなぎ、送り先を表のとおりにする。
  4. 営業売り込みの出口には何もつながない。
  5. 「Execute workflow」(ワークフローを実行)で、4種類の文面をそれぞれ流して出口を確かめる。
Text Classifier から5本の出口が Slack ノードに分かれているキャンバス
Text Classifier から5本の出口が Slack ノードに分かれているキャンバス

種類をシートの列にも残したいとき

Text Classifier は出口を分けるだけで、種類名を項目として返しません。シートに「種類」の列を作って数えたいなら、Information Extractor で種類と要約を決まった形で抜き出し、Switch で分けます。

  1. Webhook の後ろに「Information Extractor」を追加し、「Text」に上と同じ式を入れる。
  2. 「Schema Type」を「Define using JSON Schema」にし、次のスキーマを入れる。
  3. Chat Model をつなぐ(温度0)。
  4. Google Sheets の「種類」列に {{ $json.output.category }}、「要約」列に {{ $json.output.summary }} を入れる。
  5. その後ろに Switch を置き、「Mode」を Rules にして種類ごとに「Routing Rules」を作り、「Options」の「Add option」から「Fallback Output」を足して Extra Output にする。
{
  "type": "object",
  "properties": {
    "category": {
      "type": "string",
      "enum": ["見積もり", "不具合", "採用", "営業売り込み", "その他"]
    },
    "summary": { "type": "string", "description": "60字以内の要約" }
  },
  "required": ["category", "summary"]
}

enum で値を絞ると、「お見積もり」のような表記ゆれで Switch から漏れる事故を防げます。Basic LLM Chain で「Require Specific Output Format」をオンにして Structured Output Parser をつなぐ方法でも同じことができます。$ref を使った JSON Schema は、Structured Output Parser では使えず、Information Extractor でも未対応で型が崩れることがあります。

Information Extractor の Schema Type に JSON Schema を入れたところと、出力の output の下の category と summary
Information Extractor の Schema Type に JSON Schema を入れたところと、出力の output の下の category と summary

手順2:社内のよくある質問に答えるチャットを作る

次は AI Agent で、担当者が「この問い合わせ、どう返せばいい?」と聞くと、よくある質問シートや顧客管理を調べて答えるチャットを作ります。入口は Chat Trigger です。

土台を置く

  1. 新しいワークフローを作り、最初のノードに「Chat Trigger」を置く。
  2. その後ろに「AI Agent」を追加する。「Source for Prompt (User Message)」は「Connected Chat Trigger Node」のままでよい。「Prompt (User Message)」に Chat Trigger の {{ $json.chatInput }} が入る。
  3. AI Agent の「Chat Model」の「+」から Chat Model をつなぐ。
  4. 「Memory」の「+」から「Simple Memory」をつなぎ、「Session ID」を「Connected Chat Trigger Node」にし、「Context Window Length」(直近何往復まで覚えるか。既定は5)を10程度にする。
  5. AI Agent の「Add Option」から「System Message」を追加し、役割と答え方を書く。
役割:example.co.jp の社内向けアシスタント。社員の質問に、ツールで調べた内容だけを根拠に日本語で答える。
- 料金・契約条件・納期は、必ず faq_sheet で確かめてから答える
- 見つからないことは「社内資料に記載がありません」と答え、推測で埋めない
- 回答の最後に、根拠にしたシート名か資料名を1行で書く

見つからないときの答え方も書かないと、それらしい料金をLLMが作ります。

ツールをつなぐ

  1. 「Tool」の「+」から「Google Sheets」を追加する。
  2. ノード名を faq_sheet のように英数字に変える。
  3. 「Operation」を Get Row(s) にし、シート「よくある質問」を選ぶ。
  4. 同じく「Tool」に「HTTP Request Tool」を追加し、ノード名を kintone_customer にして、顧客管理のREST APIで会社名から顧客を探す設定にする。会社名の値は「Value Provided」を「By Model (and is required)」にしてAIに決めさせる。
  5. faq_sheet は「Filters」の「Add Filter」を押し、値の欄の右端の星のボタンを押して、AIに値を決めさせる。式で書く場合は次のようにする。
{{ $fromAI("company_name", "検索する顧客の会社名", "string") }}
  1. 各ツールの説明(Description)に「よくある質問と社内の回答例を調べるときに使う」のように、いつ使う道具かを書く。

$fromAI() の引数は、キー名(英数字・アンダースコア・ハイフンで1〜64文字)、説明、型(string・number・boolean・json)の順です。AI Agent につないだツールでしか使えません。

ツールのノード名に日本語や記号を使うと、Invalid 'tools[0].function.name' のエラーで止まります。ノード名がLLMに関数名として渡るためです。意味は Description に書きます。

faq_sheet の Filters の値の欄に $fromAI の式を入れたところ。右端に星のボタンがある
faq_sheet の Filters の値の欄に $fromAI の式を入れたところ。右端に星のボタンがある

別のワークフローを道具にする

「今日の未対応は何件?」をLLMに数えさせると間違えます。数える処理は別のワークフローに切り出し、「Call n8n Workflow Tool」で呼ばせます。

  1. 新しいワークフロー「未対応件数」を作り、最初に「When Executed by Another Workflow」を置く。
  2. 「Input data mode」を「Define using fields below」にし、date という入力欄を作る。
  3. Google Sheets で問い合わせ一覧を読み、Filter で日付と未対応で絞り、件数を返すノードを置く。
  4. 保存して公開(Publish)する。
  5. チャットのワークフローに戻り、AI Agent の「Tool」に「Call n8n Workflow Tool」を追加する。
  6. 「Source」を Database にして「未対応件数」を選び、「Workflow Inputs」の「Refresh」を押して date を出し、AIに値を決めさせる。

呼ばれる側が公開されていないと、本番のチャットでは失敗します。このエラーはAIに返されるので、画面上は自然な返事に見えます。答えが急に弱くなったら、呼ばれる側の実行一覧を見ます。

試して、社内に公開する

  1. キャンバス下の「Open chat」を押し、テスト用のチャット画面で質問する。
  2. AI Agent のログで、どのツールをどの引数で呼んだかを確かめる。
  3. Chat Trigger の「Make Chat Publicly Available」をオンにする。
  4. 「Mode」を Hosted Chat、「Authentication」を Basic Auth か n8n User Auth にする。
  5. ワークフローを公開し、表示された「Chat URL」を社内に共有する。

Authentication を None にすると、URLを知っている人は誰でも使え、そのたびに費用がかかります。社内向けなら n8n User Auth(n8nにログインしている人だけ)が手軽です。自社サイトに埋め込むなら「Embedded Chat」にし、「Allowed Origins (CORS)」を自社のドメインだけにします。

Simple Memory はキューモード(複数のワーカーで動かす構成)の本番では動かないので、Postgres Chat Memory に替えます。

手順3:社内資料を読ませて答えさせる(RAG)

約款や操作マニュアルについて答えさせるには、RAG(資料の該当部分を探して渡し、それをもとに答えさせる仕組み)を使います。資料を細かく切ってベクトル(意味を数字にしたもの)にしてベクトルストアに入れ、質問が来たら意味の近い部分を探してLLMに渡します。

ベクトルストアを選ぶ

ベクトルストア置き場所向く場面注意
Simple Vector Storen8nのメモリの中試作再起動で消える。全ユーザーから見えるので機密資料は入れない
Qdrant Vector Store自分で立てるかQdrant Cloudセルフホストの本番Dockerで同じサーバーに立てられる
PGVector Vector StorePostgreSQLすでにPostgresを使っている拡張の pgvector が要る
Pinecone・Supabase Vector Store外部のマネージドサービスサーバーを増やしたくない資料が外部サービスに置かれる

Simple Vector Store は公式でも開発用です。セルフホストで手軽なのは Qdrant で、n8nの docker-compose.yml に次を足せば同じネットワークから使えます。ポートは外に出さず、n8n側の Qdrant URL は http://qdrant:6333 にします。

services:
  qdrant:
    image: qdrant/qdrant
    restart: always
    environment:
      - QDRANT__SERVICE__API_KEY=${QDRANT_API_KEY}
    volumes:
      - qdrant_storage:/qdrant/storage

volumes:
  qdrant_storage:

Qdrantは既定で認証なしで起動するので、.env に QDRANT_API_KEY=長いランダムな文字列 を足します。

資料を入れるワークフロー

  1. 新しいワークフロー「資料取り込み」を作り、手動実行のトリガーを置く。
  2. Google Drive ノードで、Resource「File/Folder」の「Search」でフォルダ内のファイルを探し、Resource「File」の「Download」でファイル本体を次に渡す。
  3. 「Qdrant Vector Store」を追加し、「Operation Mode」を Insert Documents、「Qdrant Collection」を company_docs にする。
  4. 下の「Embedding」に「Embeddings OpenAI」をつなぐ。
  5. 「Document」に「Default Data Loader」をつなぎ、「Type of Data」を Binary、「Data Format」を「Automatically Detect by Mime Type」にする。
  6. 「Text Splitting」は Simple のまま実行する(1,000文字ごとに200文字重ねて切る設定)。
Qdrant Vector Store の下に Embeddings OpenAI と Default Data Loader がつながった取り込みワークフロー
Qdrant Vector Store の下に Embeddings OpenAI と Default Data Loader がつながった取り込みワークフロー

「Metadata」に資料名を入れておくと、答えに根拠の資料名を出せます。切る大きさは、約款なら小さめ、手順書なら大きめが合います。

資料を使って答えさせる

  1. 手順2のチャットの AI Agent の「Tool」に「Qdrant Vector Store」を追加する。
  2. 「Operation Mode」を「Retrieve Documents (As Tool for AI Agent)」にする。
  3. 名前を company_docs、説明を「サービス約款・操作マニュアル・料金表を調べるときに使う」にする。
  4. 「Limit」を4程度にする。
  5. 「Embedding」に、取り込みと同じ「Embeddings OpenAI」の同じモデルをつなぐ。

取り込みと検索で埋め込みモデルが違うと、エラーは出ずに的外れな部分が返ります。古い版が残ると新旧が答えに混ざるので、資料を更新するたびにコレクションを作り直します。

応用

外の道具を MCP でつなぐ

「MCP Client Tool」を使うと、MCP(AIに道具を渡す共通の取り決め)に対応した外部サービスをツールにできます。詳しくは「n8nのMCP:ワークフローを外から呼び出す、外のMCPを使う」にあります。

送る前に個人情報を伏せる

「Guardrails」ノードの「Sanitize Text」は、文章の中の個人情報(PII)・秘密情報・URLを見つけて置き換えます。LLMに渡す前に通せば、電話番号やメールアドレスを外に出さずに種類を判定できます。

費用と暴走を防ぐ

LLMの費用は入力と出力の両方にかかり、エージェントやループで回数が増えると跳ねます。

起きること原因防ぐ設定
1回の質問で費用が何倍にもなるAI Agent はツールを呼ぶたびに、会話とツールの結果を全部送り直す「Max Iterations」(既定10)を下げる。ツールを絞る
1回の入力が巨大になるツールがシートの全行やページ全体を返すHTTP Request をツールで使うときは「Optimize Response」で必要な項目だけ返す
会話が長いほど高くなるメモリが過去のやり取りを毎回送る「Context Window Length」を小さくする
一括処理でエラーが連発する各社のレート制限にかかる「Loop Over Items」で小分けにして最後に「Wait」を置く。「Settings」の「Retry On Fail」で「Max. Tries」と「Wait Between Tries (ms)」を決める
月末に請求が膨らむどこかで想定外に回り続けている各社の管理画面で利用上限を設定する(OpenAIはプロジェクトの「Limits」)。APIキーを用途ごとに分ける
公開チャットを外から叩かれるChat Trigger の認証が Nonen8n User Auth か Basic Auth にする

できないことと、その代わり

できないこと代わりの手
AIの判定や回答が正しいと保証する外れて困る出口の前に、Slack の「Send and Wait for Response」か AI Agent の「Tool」の「+」にある「Human review」で人の確認を挟む
計算・集計を正確にさせる普通のノードで組み、Call n8n Workflow Tool で呼ばせる
エージェントの出力を決まった形にそろえるStructured Output Parser が整えるのは最後の出力だけで、エージェントとの組み合わせでは崩れやすい。後ろに Basic LLM Chain を置いて整形させる
サブノードの式で複数件を1件ずつ扱うサブノードの式は常に1件目で評価される。件ごとの値は前段で作る

Human review は、ツールを使う前にワークフローを止め、AIがやろうとしていることを Slack・Gmail などで承認者に送ります。AI Agent の「Tool」の「+」から分類「Human review」を開き、Slack を選ぶと、承認待ちのツールとして加わります(操作は「Send and wait」)。「Message」には既定で {{ $tool.name }}(ツール名)と {{ $tool.parameters }}(引数)が入ります。承認で実行、却下で取り消しです。メール送信や顧客管理の更新には必ず入れます。

AI Agent の Tool の「+」から「Human review」を開いたノード一覧と、Slack を選んだ設定画面
AI Agent の Tool の「+」から「Human review」を開いたノード一覧と、Slack を選んだ設定画面
AI Agent の Tool の「+」から「Human review」を開いたノード一覧と、Slack を選んだ設定画面

よく詰まるところ

症状原因直し方
「A Chat Model sub-node must be connected」Chat Model がつながっていないノード下の「Chat Model +」からつなぐ
「No prompt specified」「Source for Prompt (User Message)」の入力元とデータが合っていない「Define below」にして「Prompt (User Message)」に式で指定する
「400 Invalid value for ‘content’」Prompt の式が空(null)参照先の項目名を確かめる。Webhook なら $json.body の下にあるか見る
テンプレートで「Error in sub-node Simple Memory」古い版の Simple Memory が入っている消して置き直す
「Invalid ‘tools[0].function.name’」ツールのノード名に日本語や記号がある英数字・空白・ハイフン・アンダースコアだけにする
「Workflow is not active and cannot be executed」Call n8n Workflow Tool で呼ばれる側が公開されていない呼ばれる側を公開する
振り分けで一部の問い合わせが消えるWhen No Clear Match が既定の Discard ItemOther の出口を作って通知する
「The service is receiving too many requests from you」OpenAIのレート制限Loop Over Items と Wait で間隔を空ける
「insufficient quota」OpenAIの残高不足か上限超過残高とプロジェクトの上限を確かめる。チャージ直後は反映を待つ
Ollamaに ECONNREFUSED ::1:11434localhost がIPv6に解決されるBase URL を http://127.0.0.1:11434 にする
Docker のn8nから同じマシンのOllamaにつながらないコンテナの中の localhost はコンテナ自身Base URL を http://host.docker.internal:11434 にする。Linux(VPS)では n8n の起動に --add-host host.docker.internal:host-gateway を足し、Ollama は 0.0.0.0 で待ち受けさせる
公開チャットで「workflow could not be started!」Load Previous Session とメモリのつなぎ方が合っていないFrom Memory にし、Chat Trigger と AI Agent に同じ Simple Memory をつなぐ
RAGで的外れな答えしか返らない取り込みと検索で埋め込みモデルが違う同じモデルにそろえて入れ直す

次にやること

あわせて読む