Claude Codeエージェント実践 Day 16|n8nワークフローエージェントを設計する
TL;DR
- Day 15 で設計した4体のエージェントチームのうち、2体目の n8nワークフローエージェント を部下育成モデル Phase 1(設計する)で構築した
- n8n エージェントの役割は 翻訳者 — データ分析エージェントが確定した SQL を、n8n ワークフロー JSON に変換する。SQL の中身には触らせない
- n8n の MCP 連携を有効にし、Claude Code から
/run-workflow/list-workflowsでワークフローを操作できるスキルを設計した
作ったもの
n8nワークフローエージェントの初期構成
n8n-workflow-agent/
├── CLAUDE.md ← 本日設計
├── .claude/
│ └── skills/
│ ├── start-req/SKILL.md ← 汎用(agent-scaffold-factory からコピー)
│ ├── next-phase/SKILL.md ← 汎用(agent-scaffold-factory からコピー)
│ ├── run-workflow/SKILL.md ← n8n 固有スキル(本日設計)
│ └── list-workflows/SKILL.md ← n8n 固有スキル(本日設計)
├── knowledge/
│ ├── business/
│ │ └── 業務ルール.md ← ワークフロー運用ルール(本日設計)
│ ├── technical/
│ │ ├── bigquery.md ← 共通ナレッジ(data-analysis-agent からコピー)
│ │ └── システム構成.md ← n8n 接続情報(本日設計)
│ └── lessons/ ← 空(運用開始後に蓄積)
└── templates/
└── workflow-template.json ← ワークフロー JSON テンプレート(本日設計)
今日のコード量はゼロです。すべて Markdown と JSON の設計ドキュメント。Phase 1 は「設計する」フェーズなので、これで合っているはず。
agent-scaffold-factory(汎用テンプレート)と data-analysis-agent(Week 2 成果物)は引き続き参照用に公開しています。
検証環境
| 項目 | 値 |
|---|---|
| OS | Windows 11 |
| Claude Code | 2.1.x |
| n8n | 2.7.5(npm グローバルインストール) |
| 検証日 | 2026-02-16 |
全体像 — n8nエージェントの位置づけ
まず、Day 15 で設計した4体のエージェントチームの中で、今日構築する n8n エージェントがどこに位置するかを確認します。
ETL の4ステージで見ると、Stage 2(定着)を担当するエージェントです。
| ステージ | 担当エージェント | 状態 |
|---|---|---|
| Stage 1: 探索 | データ分析エージェント | Week 2 で構築済み |
| Stage 2: 定着 | n8nワークフローエージェント | 今日から構築 |
| Stage 3: スケール | Dataflowエージェント | 後日 |
| Stage 4: 可視化 | レポーティングエージェント | 後日 |
Phase 1 の目標を決める
Day 14 で整理した部下育成モデルの Phase 1 は「設計する」でした。
Phase 1: 設計する ← 今日ここ
Phase 2: やらせてみる
Phase 3: 指導する
Phase 4: 任せる
Week 2 のデータ分析エージェントでは、Phase 1 で CLAUDE.md にテーブル定義や SQL ルールを書き込みました。n8n エージェントでも同じアプローチを取りますが、「n8n 固有の何を教えるか」を先に決める必要があります。
n8n エージェントに「何を」教えるか
Day 15 で定義した n8n エージェントの責務を再確認してみます。
| 項目 | 内容 |
|---|---|
| 役割 | 定着したクエリの定期実行 |
| 入力 | 確定済み SQL + 分析結果のサマリー + スケジュール要件 |
| 出力 | n8n ワークフロー定義(JSON) |
ここで重要なのは、n8n エージェントは ゼロから SQL を書くわけではない という点。データ分析エージェントが探索的にクエリを実行し、人間が「これは毎週同じだな」と判断したものを受け取って、n8n フローに「翻訳」します。
実際の利用シーンはこんなイメージです。
人間: 「分析エージェントで地域別売上を見てたんだけど、
クエリが固まったから、これを毎週自動で回したい。
SQLと分析結果はこれ。n8nフローにして!」
つまり n8n エージェントは 翻訳者 なのだと思っています。確定した SQL を、n8n が理解できるワークフロー JSON に変換する。SQL の中身には触らない。この役割定義がうまくいくかは Phase 2 で試してみないと分かりませんが、まずはこの方針で進めてみます。
この役割を踏まえて、教えるべき知識を3つに分解しました。
- n8n のワークフロー JSON 構造(ノード、接続、パラメータ)
- 使用するノードタイプの仕様(Schedule Trigger、BigQuery、Google Sheets、Slack)
- 確定 SQL を忠実に埋め込むためのルールと、人間が設定すべきものの境界
3つ目が一番迷ったところです。エージェントが SQL を「もっと効率的にしよう」と改変したり、クレデンシャルを生成しようとしたりすると、再現性とセキュリティが壊れます。「渡されたものをそのまま使う」「人間が設定すべきものにはプレースホルダーを入れる」という境界を CLAUDE.md に明記することにしました。
n8n のセットアップと MCP 連携
設計の前に、n8n 自体のセットアップから始めます。今回は npm でグローバルインストールしました。
npm で n8n をインストール・起動
npm install -g n8n
n8n start
ブラウザで http://localhost:5678 を開くと、初回セットアップ画面が表示されます。

n8n の初回セットアップ。メールとパスワードを設定する
セットアップが完了すると、ホーム画面に到達します。

「Start from scratch」でワークフロー作成を開始できる
MCP を有効化する
n8n には Instance-level MCP という機能があり、Claude Code などの MCP クライアントからワークフローを検索・実行できるようになります。これが今回のエージェント連携の肝になる部分です。
Settings → Instance-level MCP を開きます。

「Enable MCP access」ボタンで MCP を有効化する。n8n 2.7.5 で確認
「Enable MCP access」をクリックすると、MCP が有効になり、Server URL と Access token が表示されます。

Server URL: http://localhost:5678/mcp-server/http が MCP のエンドポイント
Claude Code から n8n に接続する
MCP の接続情報を .mcp.json に追加します。Access token の「Access token」タブに切り替えると、Configuration JSON がそのまま表示されるので、これをコピーして使えました。

Configuration JSON をコピーして .mcp.json に貼るだけ。ここは想像より簡単だった
{
"mcpServers": {
"n8n-mcp": {
"command": "npx",
"args": [
"-y",
"supergateway",
"--streamableHttp",
"http://localhost:5678/mcp-server/http",
"--header",
"Authorization: Bearer YOUR_ACCESS_TOKEN"
]
}
}
}
注意:
YOUR_ACCESS_TOKENは実際のトークンに置き換えてください。トークンは n8n の Settings → Instance-level MCP → Connection details → Access token タブで確認できます。
これで Claude Code から n8n の MCP ツール(search_workflows、get_workflow_details、execute_workflow)が使えるようになりました。正直なところ、MCP の設定でもっとハマると思っていたのですが、n8n 側が Configuration JSON をそのまま提示してくれるので拍子抜けするほどスムーズでした。
n8n ワークフロー JSON の構造を理解する
エージェントに教える前に、まず自分が理解しなければいけません。n8n のワークフローは JSON 形式で表現されます。構造を最小限に分解すると、4つの要素になります。
実際の JSON はこんな形です。
{
"name": "週次売上レポート",
"nodes": [
{
"id": "trigger-1",
"name": "毎週月曜9時",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [250, 300],
"parameters": {
"rule": {
"interval": [{ "field": "cronExpression", "expression": "0 9 * * 1" }]
}
}
},
{
"id": "bigquery-1",
"name": "売上クエリ実行",
"type": "n8n-nodes-base.googleBigQuery",
"typeVersion": 2,
"position": [450, 300],
"parameters": {
"operation": "executeQuery",
"projectId": "{{ $env.GCP_PROJECT_ID }}",
"sqlQuery": "SELECT region, SUM(amount) ... "
},
"credentials": {
"googleBigQueryOAuth2Api": {
"id": "PLACEHOLDER",
"name": "【要設定】BigQuery クレデンシャル"
}
}
}
],
"connections": {
"毎週月曜9時": {
"main": [[{ "node": "売上クエリ実行", "type": "main", "index": 0 }]]
}
},
"settings": { "executionOrder": "v1" }
}
エージェントが生成するもの / しないもの
ここが境界線になります。試行錯誤した結果、こういう線引きにしてみました。
| 要素 | エージェントが生成 | 人間が設定 |
|---|---|---|
| name(ワークフロー名) | ○ | |
| nodes[].type(ノードタイプ) | ○ | |
| nodes[].parameters(SQL、スケジュール等) | ○ | |
| nodes[].credentials(認証情報) | ○ | |
| connections(ノード間接続) | ○ |
credentials はプレースホルダーにする。ここが一番大事なルールです。
"credentials": {
"googleBigQueryOAuth2Api": {
"id": "PLACEHOLDER",
"name": "【要設定】BigQuery 本番用クレデンシャル"
}
}
エージェントが生成した JSON をそのまま n8n にインポートしても、クレデンシャルが未設定なので動きません。人間が n8n の UI で正しいクレデンシャルを紐付ける。これは意図的な設計にしています。
クレデンシャル情報を CLAUDE.md やナレッジに書くと、セキュリティリスクになる。n8n 公式ドキュメントでも、エクスポートした JSON にクレデンシャルのシークレットは含まれないと明記されていました。
CLAUDE.md の設計
n8n エージェントの CLAUDE.md を設計します。agent-scaffold-factory のテンプレートをベースに、n8n 固有のルールを追記する形です。
CLAUDE.md の要点
全文は長いので、設計上のポイントに絞って紹介します。
Identity / Role セクション
## Identity
あなたは n8n ワークフローの設計・生成を担当するエージェントです。
データ分析エージェントが探索・検証したクエリを、
定期実行可能な n8n ワークフローに変換します。
## 重要な原則
データ分析エージェントが「探索・検証」し、人間が「確定」と判断した SQL を、
忠実に n8n フローに変換するのがこのエージェントの仕事。
SQL の中身を勝手に最適化・改変してはいけない。
「翻訳者」の役割を冒頭で明示しました。Week 2 の経験から、CLAUDE.md の冒頭に書いたルールほど守られやすいという感触があるので、「重要な原則」を上のほうに配置しています。
Scope セクション — 「やらないこと」の明示
## Scope
### やること
- n8n ワークフロー JSON の生成(MCP 経由の操作含む)
- BigQuery クエリの定期実行スケジュール設計
- Google Sheets への出力定義 / Slack 通知の設定
### やらないこと
- クレデンシャル(認証情報)の直接設定
- BigQuery テーブルの新規作成や変更
- アドホックなデータ分析(→ データ分析エージェントの責務)
- 大量データの ETL パイプライン設計(→ Dataflow エージェントの責務)
Day 15 でエージェントを分割した意味がここに出てきます。「やらないこと」を書くのは、Week 2 では時間がかかりましたが、今回は分割済みの設計があったおかげでスッと書けました。
Rules セクション
## Rules
1. **確定済み SQL は改変しない**。データ分析エージェントが検証済みの SQL を
そのまま BigQuery ノードに埋め込む。最適化や書き換えはしない
2. ワークフロー JSON は n8n のインポート形式に準拠すること
3. クレデンシャルは必ずプレースホルダーにすること(id: "PLACEHOLDER")
4. ノード名は日本語で、処理内容が分かる名前にすること
5. SQL クエリ内の日付関数(CURRENT_DATE() 等)は確定 SQL のまま維持する
6. ワークフロー名は「[頻度]_[内容]」形式(例: 週次_地域別売上レポート)
Rules は6項目にしました。最初から完璧を目指すつもりはなく、Phase 2 で実際にワークフローを生成させてみて、問題が出たら追加・修正する方針です。Week 2 で学んだ「完璧な設計を目指すより、早く Phase 2 に入る」を今回も意識しています。
MCP ツール定義セクション
Week 2 のデータ分析エージェントでは bq CLI だけでしたが、n8n エージェントでは n8n MCP ツールも使います。CLAUDE.md に MCP ツールの用途を書いておくことで、エージェントが適切なツールを選べるようにしました。
## MCP ツール一覧
| MCP ツール | 用途 |
|-----------|------|
| `search_workflows` | ワークフロー検索(名前・説明でフィルタ) |
| `get_workflow_details` | ワークフロー詳細取得(ノード構成・トリガー情報) |
| `execute_workflow` | ワークフロー実行(webhook/chat/form 対応) |
SKILL.md の設計 — /run-workflow と /list-workflows
Week 2 のデータ分析エージェントでは /query と /sales-analysis の2スキルでした。n8n エージェントでは、MCP 経由の操作に特化した2つのスキルを設計しました。
なぜ /workflow(生成)ではなく /run-workflow(実行)にしたか
最初は「SQL を受け取ってワークフロー JSON を生成する /workflow スキル」を考えていました。しかし、実際に n8n の MCP を触ってみると、ワークフローの検索と実行が MCP の主要機能 であることが分かりました。
n8n MCP が提供するのは以下の3つです。
-
search_workflows— ワークフロー検索 -
get_workflow_details— ワークフロー詳細取得 -
execute_workflow— ワークフロー実行
つまり、MCP 経由では「既に n8n に登録されているワークフローを操作する」のが主な使い方になります。ワークフロー JSON の 生成 は n8n MCP の守備範囲外で、それはエージェントの通常の対話の中でやればいい。
この発見を踏まえて、スキルの設計を修正しました。
/run-workflow スキル
---
name: run-workflow
description: n8n ワークフローを MCP 経由で実行する
user-invocable: true
disable-model-invocation: true
allowed-tools: mcp__n8n__execute_workflow, mcp__n8n__get_workflow_details, mcp__n8n__search_workflows, Read
argument-hint: [ワークフロー名 or ID]
---
ポイントは allowed-tools です。このスキルが使える MCP ツールを明示的に制限しています。n8n の MCP ツール3つと Read だけ。他のツール(ファイル書き込みなど)は使えない。
実行手順はこう定義しました。
- 引数がワークフロー名なら
search_workflowsで ID を特定 -
get_workflow_detailsでトリガータイプを確認 - トリガータイプに応じて
execute_workflowで実行 - 結果を報告(実行サマリー + 出力データ + 実行ログ)
Week 2 の /query スキルと同じく、disable-model-invocation: true にしています。Phase 1-3 では人間が明示的にトリガーする設計。Phase 4 で false に切り替えて自律実行を許可する想定ですが、そこに到達するのはまだ先の話になりそうです。
/list-workflows スキル
---
name: list-workflows
description: n8n で利用可能なワークフロー一覧を MCP 経由で取得・表示する
user-invocable: true
disable-model-invocation: true
allowed-tools: mcp__n8n__search_workflows, mcp__n8n__get_workflow_details, Read
argument-hint: [検索キーワード(省略可)]
---
こちらは execute_workflow を allowed-tools に含めていません。一覧表示のスキルで誤ってワークフローを実行してしまうリスクを排除するためです。小さなことですが、allowed-tools でスキルごとの権限を絞れるのは Claude Code Skills の良い設計だと感じました。
出力はテーブル形式にしました。
| ID | 名前 | 状態 | ノード構成 | 最終更新 |
|----|------|------|-----------|---------|
| 1 | 週次_地域別売上 | active | Schedule → BQ → Sheets → Slack | 2026-02-16 |
knowledge/technical/ のナレッジ設計
エージェントが参照する n8n のテクニカルナレッジです。
書いた内容と、書かなかった内容
n8n には数百のノードタイプがありますが、今回使うのは Schedule Trigger、BigQuery、Google Sheets、Slack、Set、IF の6種類だけ。それ以外のノードタイプ(Webhook、HTTP Request、Code ノード等)は、必要になったタイミングで追加します。
Week 2 で学んだ教訓として、CLAUDE.md やナレッジが大きいほどノイズが増えるという実感がありました。使わない情報は入れない方針にしています。
ナレッジに書いた主要ノードタイプ仕様(クリックで展開)
Schedule Trigger(n8n-nodes-base.scheduleTrigger)
定期実行のトリガー。cron 式で柔軟にスケジュール指定可能。
{
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"parameters": {
"rule": {
"interval": [{ "field": "cronExpression", "expression": "0 9 * * 1" }]
}
}
}
よく使う cron 式:
-
0 9 * * 1: 毎週月曜 09:00 -
0 9 1 * *: 毎月1日 09:00 -
0 9 * * 1-5: 平日毎日 09:00
Google BigQuery(n8n-nodes-base.googleBigQuery)
{
"type": "n8n-nodes-base.googleBigQuery",
"typeVersion": 2,
"parameters": {
"operation": "executeQuery",
"projectId": "{{ $env.GCP_PROJECT_ID }}",
"sqlQuery": "SELECT ... WHERE date >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)"
},
"credentials": {
"googleBigQueryOAuth2Api": { "id": "PLACEHOLDER", "name": "【要設定】BigQuery クレデンシャル" }
}
}
注意事項:
- projectId は環境変数で参照する(ハードコードしない)
- sqlQuery 内の日付は CURRENT_DATE() を使う
- LIMIT は明示的に指定する(無制限クエリの防止)
Google Sheets(n8n-nodes-base.googleSheets)
{
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"parameters": {
"operation": "appendOrUpdate",
"documentId": "PLACEHOLDER_SHEET_ID",
"sheetName": "売上レポート",
"columns": { "mappingMode": "autoMapInputData" }
},
"credentials": {
"googleSheetsOAuth2Api": { "id": "PLACEHOLDER", "name": "【要設定】Google Sheets クレデンシャル" }
}
}
Slack(n8n-nodes-base.slack)
{
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"parameters": {
"operation": "post",
"channel": "PLACEHOLDER_CHANNEL",
"text": "📊 週次売上レポートが更新されました",
"otherOptions": { "includeLinkToWorkflow": true }
},
"credentials": {
"slackOAuth2Api": { "id": "PLACEHOLDER", "name": "【要設定】Slack クレデンシャル" }
}
}
ノード配置ルールと命名規則
ナレッジには JSON 仕様だけでなく、配置や命名のルールも書きました。
| ルール | 内容 |
|---|---|
| ノード配置 | 左→右に配置(x 座標を 200 ずつ増やす、y 基準 300) |
| ノード名 | 日本語で処理内容を示す(例: 売上クエリ実行) |
| ワークフロー名 |
[頻度]_[内容](例: 週次_地域別売上レポート) |
| 出力ファイル名 |
workflow-[kebab-case].json(例: workflow-weekly-sales.json) |
ワークフロー運用ポリシーの設計
knowledge/business/ には、ワークフロー化の判断基準を書きました。これは技術仕様ではなく「いつワークフロー化すべきか」という業務ルールです。
自動化の判断基準
以下のすべてを満たす場合に、ワークフロー化を検討する方針にしてみました。
- 同じクエリを 3回以上 手動実行した実績がある
- クエリの内容が 安定している(毎回パラメータだけ変わる)
- 出力先が 明確 である(誰が、何の目的で見るか)
「3回以上」という閾値は仮のもので、運用してみて調整するつもりです。少なすぎると不安定なクエリまでワークフロー化してしまうし、多すぎると自動化が進まない。良いバランスがあれば教えてほしいところです。
スケジュール設定ルール
| ルール | 内容 |
|---|---|
| 実行時刻 | 業務時間前(デフォルト: 09:00 JST) |
| 週次レポート | 月曜日 |
| 月次レポート | 翌月1営業日 |
| タイムゾーン | Asia/Tokyo |
エージェントとの引き継ぎフォーマット
ここは実は一番悩んだ部分です。「データ分析エージェントの出力を、どういう形式で n8n エージェントに渡すか」という引き継ぎの問題。
最終的に、こういう形式に落ち着きました。
必須入力:
- 確定済み SQL(データ分析エージェントが検証済み。改変しない)
- スケジュール(実行頻度とタイミング。例: 毎週月曜 09:00)
任意入力(あれば精度が上がる):
- 分析結果のサマリー(ワークフロー名や Slack 通知文の生成に使う)
- 出力先の指定(Google Sheets のシート名、Slack チャンネル名)
部下に「このまま清書して」と頼むときに、原稿だけ渡すか、「こういう意図で書いた」まで伝えるかで、清書の品質が変わる。エージェント間の引き継ぎも同じだろうと考えています。
ワークフローテンプレートの設計
エージェントがワークフロー生成の起点として使うテンプレートも用意しました。
基本パターン: BQ → Sheets → Slack
このパターンをテンプレート JSON にしました。
workflow-template.json(クリックで展開)
{
"name": "[頻度]_[内容]",
"nodes": [
{
"id": "trigger-1",
"name": "【要編集】スケジュール",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [250, 300],
"parameters": {
"rule": {
"interval": [{ "field": "cronExpression", "expression": "0 9 * * 1" }]
}
}
},
{
"id": "bigquery-1",
"name": "【要編集】クエリ実行",
"type": "n8n-nodes-base.googleBigQuery",
"typeVersion": 2,
"position": [450, 300],
"parameters": {
"operation": "executeQuery",
"projectId": "{{ $env.GCP_PROJECT_ID }}",
"sqlQuery": "/* 【要編集】ここにクエリを記述 */"
},
"credentials": {
"googleBigQueryOAuth2Api": { "id": "PLACEHOLDER", "name": "【要設定】BigQuery クレデンシャル" }
}
},
{
"id": "set-1",
"name": "データ整形",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [650, 300],
"parameters": {
"mode": "manual",
"duplicateItem": false,
"assignments": {
"assignments": [
{ "id": "report-date", "name": "レポート日", "value": "={{ $now.format('yyyy-MM-dd') }}", "type": "string" }
]
}
}
},
{
"id": "sheets-1",
"name": "【要編集】Sheets書き出し",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [850, 300],
"parameters": {
"operation": "appendOrUpdate",
"documentId": "PLACEHOLDER_SHEET_ID",
"sheetName": "【要編集】シート名",
"columns": { "mappingMode": "autoMapInputData" }
},
"credentials": {
"googleSheetsOAuth2Api": { "id": "PLACEHOLDER", "name": "【要設定】Google Sheets クレデンシャル" }
}
},
{
"id": "slack-ok",
"name": "完了通知",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [1050, 200],
"parameters": {
"operation": "post",
"channel": "PLACEHOLDER_CHANNEL",
"text": "✅ [ワークフロー名] が正常に完了しました({{ $now.format('yyyy-MM-dd HH:mm') }})",
"otherOptions": { "includeLinkToWorkflow": true }
},
"credentials": {
"slackOAuth2Api": { "id": "PLACEHOLDER", "name": "【要設定】Slack クレデンシャル" }
}
},
{
"id": "slack-error",
"name": "エラー通知",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [1050, 400],
"parameters": {
"operation": "post",
"channel": "#alert-workflow",
"text": "❌ [ワークフロー名] でエラーが発生しました\nエラー: {{ $json.error.message }}",
"otherOptions": { "includeLinkToWorkflow": true }
},
"credentials": {
"slackOAuth2Api": { "id": "PLACEHOLDER", "name": "【要設定】Slack クレデンシャル" }
}
}
],
"connections": {
"【要編集】スケジュール": {
"main": [[{ "node": "【要編集】クエリ実行", "type": "main", "index": 0 }]]
},
"【要編集】クエリ実行": {
"main": [[{ "node": "データ整形", "type": "main", "index": 0 }]]
},
"データ整形": {
"main": [[{ "node": "【要編集】Sheets書き出し", "type": "main", "index": 0 }]]
},
"【要編集】Sheets書き出し": {
"main": [[{ "node": "完了通知", "type": "main", "index": 0 }]]
}
},
"settings": { "executionOrder": "v1" }
}
テンプレートの設計思想
「【要編集】」プレフィックスでエージェントの作業箇所を明示した。テンプレートをそのまま使うのではなく、エージェントが要件に応じてカスタマイズする前提です。【要編集】が残っていたら、まだ作業が完了していないことが一目でわかる。
「【要設定】」プレフィックスで人間の作業箇所を明示した。クレデンシャルやシート ID など、人間が n8n の UI で設定すべき箇所。エージェントの出力物を受け取った人間が、何をすればいいか迷わないようにしたかった。
エラーハンドリングをテンプレートに含めた。正常系だけでなく、異常時の Slack 通知もデフォルトで入れています。私の経験上、エラーハンドリングは「あとで追加しよう」と思っていると永遠に追加されないので...。
共通スキルのコピー配置
Day 15 で設計した「共通スキル × 固有スキル」のコンポジションを実際に行いました。
コピー元 → コピー先
data-analysis-agent/ n8n-workflow-agent/
├── .claude/skills/ ├── .claude/skills/
│ ├── start-req/SKILL.md ──コピー──→ │ ├── start-req/SKILL.md
│ └── next-phase/SKILL.md ──コピー──→ │ ├── next-phase/SKILL.md
│ │ ├── run-workflow/SKILL.md ← 新規
│ │ └── list-workflows/SKILL.md ← 新規
├── knowledge/technical/ ├── knowledge/technical/
│ └── bigquery.md ──コピー──→ │ └── bigquery.md
コピー時に気をつけたこと
bigquery.md をコピーした際、データ分析エージェント固有のルール(「考察を入れない」「3点セットで出力する」等)が混入していないか確認しました。n8n エージェントに持ち込むべきなのは「テーブル定義」「SQL 方言の注意事項」「カラム名のリスト」だけです。
データ分析エージェントの業務ルールが混入すると、n8n エージェントの動作に影響してしまう。Day 15 で「分ける理由」として挙げた「失敗の影響範囲を限定する」は、こういうコピー作業の段階から意識が必要だと感じました。
ハマったところ
問題1: ノードの typeVersion が分からない
症状: n8n のノードには typeVersion があるが、最新バージョンが何番なのか、公式ドキュメントに明記されていなかった。
原因: n8n はバージョンアップ時にノードの typeVersion を更新するが、API リファレンスにはバージョン一覧がない。
解決: 自分の n8n インスタンス(2.7.5)で新規ワークフローを作成し、各ノードを追加してエクスポートした JSON を確認。実環境のバージョンを基準にテンプレートの typeVersion を設定しました。
# 実環境で確認した typeVersion(n8n 2.7.5)
scheduleTrigger: 1.2
googleBigQuery: 2
googleSheets: 4.5
slack: 2.2
set: 3.4
if: 2.2
これは環境依存の情報なので、他のバージョンでは異なる可能性があります。もっとスマートな確認方法があれば教えてほしいです。
問題2: connections のキーがノード名(name)であること
症状: 最初、connections のキーを id で書いてしまい、n8n にインポートしたら接続が切れていた。
原因: n8n の connections はノードの name フィールドをキーに使う。id ではない。
解決: ナレッジに「接続定義のキーはノード名(name)であり、id ではない」と明記。テンプレートのノード名と connections のキーが一致していることを確認するチェック項目も追加しました。
これは Phase 2 で「エージェントがやりがちなミス」として出てくる可能性が高い気がしています。先にナレッジに書いておいたのは、Week 2 で「ハマってから直す」を繰り返した反省から。予見できる問題は先に潰しておく方針にしてみました。
問題3: MCP のスキル設計を途中で変更した
症状: 最初は「SQL を受け取ってワークフロー JSON を生成する /workflow スキル」を設計していたが、n8n MCP を実際に触ってみたら方針が変わった。
原因: MCP が提供するのは search_workflows / get_workflow_details / execute_workflow の3つ。「ワークフロー JSON を生成して n8n に登録する」API はなかった。
解決: スキルの責務を「ワークフロー JSON 生成」から「既存ワークフローの操作」に変更し、/run-workflow と /list-workflows の2スキルに分割。ワークフロー JSON の生成はスキル外の通常対話で行う設計にした。
ここで30分くらい迷いました。「設計を変えると Day 15 の記事と矛盾しないか」と。ただ、Day 15 で書いたのは全体の方針であって、スキルの名前まで確定していたわけではない。設計は実装段階で変わるものだし、その変遷を正直に書くほうがリアルな実践記録になるだろうと判断しました。
なぜこう作ったか — Week 2 との比較
Week 2(データ分析エージェント)の Phase 1 と今日を比較すると、3つの違いがありました。
| 観点 | Week 2(データ分析) | Week 3(n8n) |
|---|---|---|
| テンプレートの有無 | ゼロから設計 | agent-scaffold-factory ベース |
| 「やらないこと」の明確さ | 考えるのに時間がかかった | Day 15 の分割設計でスッと書けた |
| ナレッジの分量 | あれもこれも書いた | 6種類のノードタイプに絞った |
テンプレートがあるので設計が速かった。共通部分(Identity、Role の書き方、Output Format のパターン)はテンプレートを埋めるだけ。固有部分(n8n のルール)に集中できました。
ナレッジの分量を抑えられた。Week 2 では bigquery.md にあれもこれも書いてしまいましたが、今回は「このエージェントが使う範囲だけ」を意識して書きました。6種類のノードタイプに絞ったことで、読みやすいドキュメントになったと思います。ただ、Phase 2 で足りない情報が出てくる可能性は高いので、そのときに追記する前提です。
まとめ
- n8n エージェントは翻訳者 — データ分析エージェントが確定した SQL を受け取り、n8n ワークフロー JSON に変換する。SQL の中身には触らない
- n8n の MCP 連携 を有効にし、Claude Code から
/run-workflow/list-workflowsでワークフローを操作するスキルを設計した - Phase 1(設計する) として、CLAUDE.md、SKILL.md、ナレッジを設計。最初から完璧を目指さず、Phase 2 で修正する前提
- 【要編集】と【要設定】 のプレフィックス規約で、エージェントの作業と人間の作業の境界を可視化した
- MCP を触ってスキル設計を途中で変更した。設計は実装段階で変わるもの。変遷を記録するのも実践記事の価値だと感じている
明日の Day 17 では、この設計に基づいて Phase 2(やらせてみる) に進みます。n8n にサンプルワークフローを登録し、/run-workflow で実行してみるところまでが目標です。
Step 1: n8n にサンプルワークフロー(週次_地域別売上レポート)を登録
Step 2: /list-workflows で一覧取得を確認
Step 3: /run-workflow で実行 → 結果を確認
Step 4: 問題があれば SKILL.md やナレッジにフィードバック
Phase 2 でどんな問題が出てくるか、正直まだ読めていません。Week 2 の経験からすると「思ってもみなかったところでハマる」のがお約束なので、そこも含めて共有していきます。
シリーズを追いかける
Discussion