n8n-ai-nodes-official について
n8n ワークフローで LLM タスクを組み立てる開発者向けの、AI ノード選択・設定ガイドです。Agent ノード、軽量なチェーン、専用ノードの使い分けに加え、ツール、メモリ、構造化出力、人間による確認を解説します。
主な機能
- 01Agent とチェーンノードの比較
- 02モデル、メモリ、ツール接続の指針
- 03ツール選択パターンの解説
- 04構造化出力と自動修正の指針
- 05重要な操作に対する人間の確認
活用シーン
- 01LLM ワークフローの処理に使うノード選択
- 02Agent へのツールとメモリの接続
- 03入力を分類してワークフロー分岐へ振り分け
- 04副作用の前に承認ステップを追加
MCP 対応
ツールが MCP 対応ワークフローから利用できる場合の MCP ツールの使い方を説明し、ワークフロー間で Agent の機能を共有する MCP 拡張を案内します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ n8n-io/ skills --skill n8n-ai-nodes-officialインストール後、Claude Code で/n8n-ai-nodes-officialを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/CHAT_SURFACE_PATTERNS.mdHUMAN_REVIEW.mdMEMORY.mdRAG.mdSTRUCTURED_OUTPUT.mdSUBWORKFLOW_AS_TOOL.mdSYSTEM_PROMPT.mdTOOLS.mdreferences/examples/agent-core.jsonnotion-ideas-subagent.jsonslack-router.json詳細
n8n AI ノード
AI Agent ノード(@n8n/n8n-nodes-langchain.agent)は、モデル、メモリ、ツール、および任意の出力パーサー用のサブノードを備えた、複数ターンに対応する LLM ドライバーです。ワークフロー内で動作し、トリガー、制御フロー、ライフサイクルはワークフローが管理します。
AI Agent ノードと n8n のファーストクラス Agent のどちらを使うべきですか?
デフォルトで「エージェントを構築して」という場合は、n8n のファーストクラス Agent(n8n-agents-official)を指します。ワークフローが制御フローを管理し、AI が範囲の限られた 1 つのステップである場合、またはファーストクラス Agent の制限に達した場合は、ノードを使用してください。
| 必要なこと | 現時点でノードが適している理由 |
|---|---|
| トリガーまたは上流データをツールのパラメーターに正確にマッピングする | Agent ツールの式から参照できるのは、モデル自身の引数だけです。ノードのツールでは $('Webhook').item.json... を使用できます |
| チャットチャネルと他のワークフローで共有する 1 つの会話 | Agent のチャネルセッションとワークフローセッションは連携しません |
MCP ツールリストに create_agent がない | このインスタンスでは Agent が有効になっていません |
Agent ノードと生のチャット補完のどちらを使うべきですか?
判断基準:
- ツール呼び出し、複数ターンの推論、またはメモリが必要ですか? Agent を使います。特に考えずに済む妥当なデフォルトでもあります。ワークフロー全体で Agent に統一するのは合理的で、アップグレードへの移行も簡単になります。
- できるだけ軽量な、単発のテキスト出力呼び出しが必要ですか? チャットモデルのサブノード(
OpenRouter Chat Model、OpenAI Chat Model、Anthropic Chat Modelなど)を備えた Basic LLM Chain(@n8n/n8n-nodes-langchain.chainLlm)を使います。Agent のループ、ツール/メモリ/パーサー用のスロットがなく、デバッグも簡単です。注:チャットモデルノードはサブノードであり、単独では実行できません。チェーンまたは Agent に接続します。統一したい場合は、ここでも Agent を使えます。 - 自然言語入力に基づき、N 個の出力分岐の 1 つへルーティングしますか(AI が分岐を選ぶ役割ですか)? Text Classifier ノード(
@n8n/n8n-nodes-langchain.textClassifier)を使います。カテゴリごとに 1 つずつ、N 個の出力ハンドルがあり、下流のパスをそれぞれに直接接続できます。各カテゴリには名前と説明の両方が必要です(モデルは説明に基づいて選択するため、名前だけでは不十分です)。入力の境界ケースに対する堅牢性を高めるには、options.enableAutoFixing: trueを設定します。チャットモデルのサブノード(OpenRouter Chat Model、OpenAI Chat Modelなど)と組み合わせます。この用途に Agent と Switch を使う必要はありません。Text Classifier は単一のノードで、この目的に特化しています。 - ツールは不要ですが、構造化出力が必要ですか? 今後の拡張も考えるなら、Agent がより使いやすいデフォルトです。Basic LLM Chain も
outputParserStructuredサブノードを受け付けるため、より軽量なノードを使いたい場合に適しています。 - 画像/音声/動画を生成しますか? そのプロバイダーを直接呼び出す場合は、プロバイダーのネイティブな単発呼び出しノード(OpenAI Image、Gemini Image、ElevenLabs など)を使います。アグリゲーター(OpenRouter、Together など)を経由する場合は HTTP Request を使います。ネイティブなアグリゲーターノードが存在せず、メディア操作ではネイティブノードのベース URL がプロバイダーのものに固定されているためです。メディア生成を Agent でラップしないでください。「バイナリデータと Agent の境界」を参照してください。
特定の用途に向けた、ほかの LangChain の「チェーン」/ユーティリティノードもあります。テキストから構造化フィールドを抽出する Information Extractor、3 方向に分岐する Sentiment Analysis、Summarization Chain、Basic LLM Chain などです。
ほとんどの LLM ステップでは、Agent が妥当なデフォルトです。ツール、メモリ、反復処理を使わない単発のテキスト呼び出しに、より軽量なノードを使いたい場合は Basic LLM Chain を選んでください。タスクに特化した Information Extractor/Sentiment Analysis/Summarization Chain/Text Classifier がぴったり合う場合は、そちらを選んでください。
必須事項
- ツール名と説明はプロンプトの一部です。 モデルはツール名と説明をもとにツールを選びます。
doStuffのような曖昧なツールノード名や、「データに対して処理を行う」といった不十分な説明は、気づかれないまま失敗を引き起こします。モデルがツールを使わなかったり、誤ったツールを選んだり、パラメーターを幻覚したりします。どちらも API 設計の一部として扱ってください。references/TOOLS.mdを参照してください。 - 構造化出力:パースと自動修正の両方を行います。
autoFix: trueを設定したoutputParserStructuredと、コーディングに対応した修正用モデル(例:Claude Sonnet 4.6)を組み合わせるのが、本番環境向けのパターンです。
推奨されるデフォルト設定
- ツールの説明はモジュール式のプロンプト断片です。 このツールの呼び出し方に固有の内容は、システムプロンプトではなくツールの説明に記述します。これによりシステムプロンプトを簡潔に保ち、ツールを複数のエージェントで再利用できます。
references/SYSTEM_PROMPT.mdを参照してください。 - 複数ステップの処理にはサブワークフローツール(
toolWorkflow)を使います。 どのようなワークフローも、型付きのfromAi()入力を持つツールにでき、分岐、エラー処理、サブワークフローを組み合わせられます。references/SUBWORKFLOW_AS_TOOL.mdを参照してください。 - ユーザーに見える副作用を伴うツールには、人によるレビューを組み込みます。 メッセージの送信、支払い、返金、アカウントの変更などが該当します。Slack/Chat/Discord/Telegram の承認ノードを通して実行を制御し、ツールの実行前に人が承認するようにしてください。
references/HUMAN_REVIEW.mdを参照してください。
サブノードのパターン
Agent ノードには、メイン入力(プロンプトまたはユーザーメッセージ)とサブノード入力があります。
const aiAgent = node({
type: '@n8n/n8n-nodes-langchain.agent',
config: {
name: 'Customer Support Agent',
parameters: {
promptType: 'define',
text: '={{ $json.userMessage }}',
options: {
systemMessage: '...',
passthroughBinaryImages: true, // for vision / multimodal
},
},
subnodes: {
model: openRouterModel,
memory: simpleMemory,
tools: [generateImage, editImage, searchKnowledgeBase],
outputParser: structuredParser, // optional
},
},
})
4 つのサブノードスロット:
model(必須):言語モデルです。OpenAI、Anthropic、OpenRouter などを使用します。Completion ではなく、Chat モデルのバリアントを使ってください。memory(任意):会話のメモリです。これがない場合、呼び出しはすべてステートレスになります。references/MEMORY.mdを参照してください。tools(任意ですが、エージェントを使う主な目的です):エージェントが呼び出せるツールです。references/TOOLS.mdを参照してください。outputParser(任意):構造化された JSON 出力を強制します。references/STRUCTURED_OUTPUT.mdを参照してください。
トリガー
トリガーによって入力の形式は異なります。
- **Chat Trigger(
@n8n/n8n-nodes-langchain.chatTrigger)**でavailableInChat: trueを設定すると、キャンバスのチャットテスターからエージェントを試せます。入力は{ chatInput, sessionId, files[] }です。メモリのキーにはsessionIdが使われるため、会話の継続性が必要な場所には渡してください。ファイルはfiles[]経由で渡されます。詳細は下記のバイナリーのセクションを参照してください。これは本番環境向けの窓口ではありません。本番環境では Slack/Discord/Teams/Telegram/Webhook を使用してください。 - Webhook:入力形式は任意で、デフォルトではセッションがありません。リクエスト本文でセッション ID/会話 ID を渡し、メモリノードに転送して継続性を管理します。
- 外部チャットの窓口(Slack、Discord、Teams、Telegram):返信を投稿するチャットトリガー付きワークフローではすべて、ボット自身のユーザー ID を除外する必要があります。除外しないとループが延々と続き、n8n がクラッシュする可能性があります。対応している場合は、トリガーレベルでのフィルタリングを推奨します(Slack の
options.userIdsは除外リストです)。それ以外の場合は、トリガー直後の最初のノードでフィルタリングしてください。仕様は窓口ごとに異なります。references/CHAT_SURFACE_PATTERNS.mdを参照してください。n8n のファーストクラス Agent は、ワークフローなしで Slack、Telegram、Discord、Linear にネイティブ接続できます。詳細はn8n-agents-officialを参照してください。ループ防止フィルター以外は、シンプルなボット(トリガー → エージェント → 返信)を 1 つのワークフローにまとめて問題ありません。ローディング表示、サブエージェント、複数の窓口での再利用、堅牢なエラー処理が必要になったら、「シェル」ワークフローとエージェントコアのサブワークフローに分割してください。 - 手動/スケジュール:任意のタイミングで呼び出します。前回の実行から明示的に継続するのでない限り、メモリが役立つことはほとんどありません。
- Execute Workflow Trigger(サブワークフロー):エージェント自体が別のエージェントのツールである場合に使用します。トリガーで宣言された入力を契約として扱ってください。
バイナリとエージェントの境界
モデルは passthroughBinaryImages: true によって、アップロードされたファイルを認識できます(ビジョン)。しかし、ツールはバイナリを受け取れず、fromAi() のパラメーターは JSON のみです。Base64 も、非 AI バインディング経由を含め、ツールでは受け付けられません。
回避策:エージェントの実行前にアップロードをストレージへ事前配置し、ストレージキーをシステムプロンプトに挿入します。ツールはキーを文字列パラメーターとして受け取り、内部で再取得します。全体のパターンについては、n8n-binary-and-data-official の references/AGENT_TOOL_BINARY.md を参照してください。
出力側について:エージェントの出力フォーマッターはテキスト形式です(outputParser が接続されている場合は構造化テキスト形式です)。モデルがバイナリ(画像データ、音声データ、動画)を返しても、エージェントはそれを一切出力しません。後続で取り出す方法はなく、エージェントの後に Code ノードや Set ノードを使って復元しようとしても機能しません。一度だけ実行するメディア生成には、@n8n/n8n-nodes-langchain.googleGemini や @n8n/n8n-nodes-langchain.openAi など、プロバイダーのネイティブな単一呼び出しノードを直接使用してください。
例外として、メディア処理が本当にエージェントに含まれるべき場合(会話のコンテキストに応じて複数のツールから選択されるツールのひとつである場合や、以前に生成した画像を編集する場合)は、回避策として、結果をストレージにアップロードし、キーまたは URL を返すツールサブワークフローを使います。パターンについては、n8n-binary-and-data-official の references/AGENT_TOOL_BINARY.md を参照してください。これをデフォルトの方法にしないでください。アップロード、キーの受け渡し、再取得という手順には、不要なノードとストレージへの依存が加わります。エージェントによるツール選択が実際に必要な場合にのみ使用してください。
システムプロンプトとツールの説明に記述する内容
| システムプロンプトに記述する内容 | ツールの説明に記述する内容 |
|---|---|
| ペルソナ、役割、話し方 | この特定のツールの機能 |
| 出力形式のルール(「マークダウンで回答する」など) | 他のツールではなく、このツールを使う状況 |
| 拒否や安全性に関する動作 | 各パラメーターの意味と期待される形式 |
表示プロトコル(「画像は ![]() マークダウンで表示する」など) | 適切な呼び出しと不適切な呼び出しの例 |
| 全般的なコンテキスト(現在の日付、ユーザーの役割) | ツール固有の注意点(レート制限、エッジケース) |
| ツール間のフロー(「生成後は必ず表示プロトコルを使って表示する」など) | ツール固有の入力変換 |
利点:ツールを再利用しやすくなります。説明が十分なツールは、どのエージェントにも組み込んで利用できます。システムプロンプトは役割と共通の動作に集中できます。
詳しいガイダンスと実例については、references/SYSTEM_PROMPT.md と references/TOOLS.md を参照してください。
ツール選択:4 つのタイプ
目的を満たす、最も軽量な選択肢を選んでください。
- ネイティブの n8n ツールノードがある場合(例:
slackTool、gmailTool、`calculatorTool)、それを使用してください。設定の手間が最小です。- ネイティブノードに必要な操作がない、またはカスタムパラメーターが必要な場合(例:ノードが公開していない Notion エンドポイント、標準外のヘッダー、異なるページネーション形式)、サービスの「Predefined Credential Type」を指定した HTTP Request Tool を使用してください。既存の OAuth/API キー認証情報を再利用でき、カスタム認証コードなしで API にフルアクセスできます。
- 複数ステップのロジックがある場合、またはプロジェクト内のサブワークフローを再利用する場合:サブワークフローをツールとして使用します(
toolWorkflow)。ワークフローとして構築できるものはすべて、型付きのfromAi()入力を持つツールにできます。n8n で最も強力な選択肢なので、迷った場合はこちらをデフォルトにしてください。references/SUBWORKFLOW_AS_TOOL.mdを参照してください。 - エージェントが直接オーケストレーションすべき外部 HTTP API を呼び出す場合:HTTP Request Tool を使用します。ロングポーリングコールバックを使う、時間のかかる非同期処理にも適しています。
- 公開済みで、MCP からアクセス可能なワークフローとしてツールがすでに存在する場合:MCP ツールを使用します。ワークフローをまたいだエージェント機能に便利です。
n8n-extending-mcp-officialを参照してください。
各選択肢の詳しいガイダンスと fromAi() パラメーターの接続方法については、references/TOOLS.md を参照してください。
人によるレビュー
ツールに人によるレビューを追加するか省略するかを決める前に、ユーザーに確認してください。承認が必要かどうかは、影響範囲、監査要件、モデルへの信頼度などに基づく製品/ポリシー上の判断であり、あなたよりもユーザーのほうが適切に判断できます。質問を提示し、以下の基準に基づいて推奨したうえで、ユーザーに決定してもらってください。
ツールの実行前に人の承認が必要な場合(送信、支払い、返金、アカウント変更、顧客向けの操作など)は、レビュー用ツールノードでラップします。例:slackHitlTool、discordHitlTool、telegramHitlTool、gmailHitlTool など。(n8n のノード名では human-in-the-loop パターンに Hitl を使い、UI では「人によるレビュー」と呼ばれます。)レビュー用ノードは、ai_tool 接続上でラップ対象のツールとエージェントの間に配置します。ラップ対象のツールの ai_tool 出力をレビュー用ノードに接続し、レビュー用ノードの ai_tool 出力をエージェントに接続します。エージェントが呼び出しを行うと、レビュー用ノードが承認まで一時停止し、承認されるとラップ対象のツールが実行されます。
次の場合は、人によるレビューをデフォルトで適用するか、推奨してください。
- ツールが送信、支払い、返金を行う場合、またはユーザーに見える状態を変更する場合。
- 承認者が会話相手と異なる場合(マネージャーが顧客向けの操作を承認する、サポートチームが顧客起点の返金を承認するなど)。
- トリガーが非対話型(注文、フォーム、スケジュール)で、ツールの実行に人の承認が必要な場合。
承認メッセージには、モデルが言い換えたテキストではなく、ラップ対象のツールが実際に受け取る実際のパラメーターを表示してください。$tool.parameters.<name> を直接使うか、$tool.parameters を反復処理してすべてのパラメーターを一覧表示します。承認テキストの生成に fromAi() を使わないでください。承認するのは、実際の呼び出しではなく言い換えです。ボタンのラベルは、実際の値を使ってカスタマイズします。例:Approve {{ $tool.parameters.amount }} refund。
完全な設定パターン、プラットフォームごとのセットアップ、複数チャンネルの承認者パターンについては、references/HUMAN_REVIEW.md を参照してください。
出力の解析:いつ、どのように行うか
後続処理で自由形式のテキストではなく構造化データが必要な場合は、outputParser サブノードを追加してください。
const parser = outputParser({
type: '@n8n/n8n-nodes-langchain.outputParserStructured',
config: {
parameters: {
schemaType: 'manual',
inputSchema: JSON.stringify({
type: 'object',
properties: {
score: { type: 'integer', minimum: 1, maximum: 5 },
category: { type: 'string', enum: ['bug', 'feature', 'question'] },
reason: { type: 'string' },
tags: { type: 'array', items: { type: 'string' } },
},
required: ['score', 'category', 'reason'],
}),
autoFix: true,
customizeRetryPrompt: true,
prompt: '...retry instructions...', // generally leave as default
},
subnodes: {
languageModel: fixerModel, // coding-capable model, e.g. Claude Sonnet 4.6
},
},
})
jsonSchemaExampleではなく、実際の JSON スキーマを使ってschemaType: 'manual'を指定してください。 例だけでは、任意フィールド、列挙型、値の範囲、配列の制約を表現できないため、データ構造が少し複雑になっただけで対応できなくなります。スキーマを使えば、必須フィールドと任意フィールドを指定し、列挙型を定義し、数値や文字列の形式を制約できるほか、モデルが従うべきルールも明確になります。制約が増えることはないと確信できる一度限りのデータ構造に限り、例とともにschemaType: 'fromJson'を使ってください。autoFix: trueを指定すると、解析に失敗した場合に再試行します。 修正用サブノードとして、コーディングに対応できるモデル(例:Claude Sonnet 4.6 など)を接続してください。スキーマに照らして不正な JSON を修正するのは、構造化出力/コーディングのタスクです。性能の低いモデルや汎用モデルでは、再試行後も不正な出力になりやすく、目的を果たせないことがあります。
カスタムの再試行プロンプトを含む完全なパターンについては、references/STRUCTURED_OUTPUT.md を参照してください。
メモリ:簡単な考え方
- メモリなし: ステートレスです。単発のタスク(分類、要約)に適しています。
memoryBufferWindow: メモリキーごとに直近 N 件のメッセージを保持し、n8n の内部ストアを介して実行をまたいで永続化します。キーにはsessionKeyに割り当てた任意の式を使います。チャットトリガーではsessionIdが自動的に設定されますが、任意の値をキーにできます(Slack のthread_ts、Webhook の会話 ID、複数テナントの複合キーなど)。チャットメモリのデフォルトです。「ウィンドウ」は、コンテキストに保持されるメッセージ数のスライディング上限であり、永続化の範囲ではありません。memoryPostgres/memoryRedis/類似のもの: エージェントの外部からメモリをクエリしたり読み取ったりする必要がある場合に使います。たとえば、独自の UI で会話履歴を表示する場合、過去のチャットを分析する場合、別のシステムとメモリを共有する場合などです。それ以外の場合は、memoryBufferWindowで十分です。
トリガーからメモリまで一貫して安定したキーを渡してください。そうしないと、会話が混線します。references/MEMORY.md を参照してください。
RAG(検索拡張生成)
n8n には LangChain の RAG プリミティブが用意されています。ドキュメントローダー、テキストスプリッター、埋め込み、ベクトルストア、リトリーバー、リランカーなどです。各要素は機能しますが、「どのベクトルストアを使うか、どのようにチャンク分割するか、いつリランクするか」といった、意見を反映したエンドツーエンドのレシピは、データの形状や規模に大きく左右されます。
このスキルでは、意図的に RAG に関する見解を最小限にしています。RAG の詳細については references/RAG.md を参照してください。
リファレンスファイル
| ファイル | 参照するタイミング |
|---|---|
references/TOOLS.md | エージェントにツールを追加する場合、4 種類のツールから選択する場合、ツール名と説明を作成する場合 |
references/SUBWORKFLOW_AS_TOOL.md | toolWorkflow を使用してサブワークフローをエージェントツールとして接続する場合、fromAi のオーバーライドをマッピングする場合 |
references/SYSTEM_PROMPT.md | システムプロンプトを作成またはリファクタリングする場合、システムプロンプトとツールの説明のどちらに記述するかを判断する場合 |
references/STRUCTURED_OUTPUT.md | JSON 出力を強制する場合、autoFix の再試行を設定する場合、後続の処理で検証する場合 |
references/MEMORY.md | メモリの種類を選択する場合、永続化と sessionId の処理を行う場合 |
references/RAG.md | 検索拡張エージェントを構築する場合。意図的にスタブです |
references/HUMAN_REVIEW.md | ツールに人間の承認を追加する場合、承認メッセージを設定する場合、複数チャネルの承認者パターンを実装する場合 |
references/CHAT_SURFACE_PATTERNS.md | Slack、Discord、Teams、Telegram、または任意のカスタムチャット画面上でチャットボットのワークフローを構築する場合。シェル+コア+サブエージェントの構成や、Message an Agent を介してコアとして第一級の Agent を使う構成を含みます |
アンチパターン
| アンチパターン | 問題点 | 対策 |
|---|---|---|
汎用的なツール名(doStuff、runQuery) | モデルがどのツールを選べばよいか判断できず、選択をスキップしたり、パラメーターを幻覚したりします | 動詞から始まる具体的な名前にします:Search customer database、Generate image with Veo |
| 空欄、または1行だけのツールの説明 | モデルはいつ呼び出せばよいかわからず、選択を誤ります | 実際の説明を書きます:ツールの機能、使用するタイミング、パラメーターの意味 |
| システムプロンプトにすべてを詰め込む | プロンプトが肥大化し、再利用できず、ツールごとのガイダンスが埋もれます | ツール固有の指示はツールの説明に移し、システムプロンプトはペルソナとグローバルルールに絞ります |
| サブワークフローで対応できる場面でコードノードのツールを使う | 再利用できず、個別にテストできず、分岐との組み合わせもできません | 適切なサブワークフローと toolWorkflow を使います |
| バイナリを直接ツールに渡す | 動作しません。バイナリはツールの境界を越えられません | あらかじめストレージに保存し、fromAi 経由でキーを渡して、ツール内部で取得します。n8n-binary-and-data-official を参照してください |
autoFix なしで outputParserStructured を使う | モデルの出力に問題が1つでもあると、ワークフローが失敗します | 安価な修正モデルとともに autoFix: true を設定します |
sessionId をハードコードする、または指定しない | 会話が混ざったり、メモリが一致しなかったりします | トリガーから sessionId を渡し、メモリとツールで一貫して使用します |
| 分岐を使う代わりに、ほぼ同一のツールを2つ作る | モデルが混乱し、選択が非決定的になります | パラメーターに基づく内部分岐を備えた1つのツールにします |
| 複数のワークフローで再利用する、または頻繁に反復するシステムプロンプトをハードコードする | 編集のたびに再公開が必要となり、ワークフロー間で共有できず、調整の変更がノードのJSONに蓄積します | Data Table に保存し、実行時に読み込みます |
| 画像/音声/動画の生成を Agent でラップする | バイナリがツールや出力フォーマッターを通って流れず、Agent を追加しても利点がありません | プロバイダーのネイティブな単一呼び出しノード(OpenAI Image、Gemini Image、ElevenLabs)を直接使います。アグリゲーターを経由する場合に限り、HTTP Request を使います |
| 自然言語入力のルーティングに Agent + Switch を使う | Text Classifier なら1つのノードで N 個の組み込み出力ブランチを使えるところに、2つのノードとプロンプトの定型文が必要になります | Text Classifier(@n8n/n8n-nodes-langchain.textClassifier)を使います。各カテゴリには専用の出力ハンドルが割り当てられるため、後続の経路に直接つなげられます |
| ユーザーに見える状態を変更するツール(送信、支払い、返金)を、人間の確認なしで実行する | 誤った推論に基づいて、エージェントが取り消せない操作を実行します | チャネルに適した確認用ツールノード(Slack/Chat/Discord/Telegram)でラップし、実際のパラメーターを $tool.parameters で表示します |
fromAi() で確認メッセージを埋める | モデルが言い換えるため、値ではなく文面を承認することになります | $tool.parameters.<name> を直接使い、実際の呼び出し内容を確認できるようにします |
| ボット自身のユーザー ID を除外せず、チャットトリガーのワークフローが返信を投稿する | ボット自身のメッセージでワークフローが再トリガーされ、レート制限または n8n の同時実行数の上限に達するまで、実行とトークンを消費する無限ループになります | 利用可能な場合はトリガーレベルでのフィルタリングを優先します(Slack Trigger の options.userIds は除外リストなので、ここにボット ID を設定します)。それ以外の場合は、トリガー直後の最初のノードで $json.user !== '<BOT_USER_ID>'(または各サービスに応じた同等の条件)を使ってフィルタリングします。複雑さに関係なく、返信を送るすべてのチャットトリガー型ワークフロー(Slack、Discord、Teams、Telegram)で必須です。サービスごとの仕様については references/CHAT_SURFACE_PATTERNS.md を参照してください |
エージェントが Block Kit を返すときに、Slack ノードの blocksUi に blocks 配列をそのまま渡す | Slack ノードは入力を黙って受け入れ、リッチコンテンツなしでメッセージを投稿します。エラーも警告も表示されません | 実際の配列を値として { "blocks": [...] } でラップします。文字列化した配列は使いません。式:={{ { "blocks": $('Agent').item.json.output.blocks } }}。n8n-node-configuration-official の references/COMMS_NODES.md「Block Kit messages」を参照してください |