株式会社明正 様|AI業務内製化 1DAY合宿 例題1 手順書
上から順に読んで、そのとおりに進めてください。貼るもの・押すボタンは、すべてこのページに入っています。 画面の見た目がこのページと違っていたら、探し回らずに手を挙げてください。すぐに伺います。
やることは1つだけです。Outlook に届いている輸出依頼のメールをコピーして、n8n に貼り付けます。 すると、そのメールに書かれている内容が自動で読み取られて、Google スプレッドシートの案件台帳に1行追加されます。
当日は、お預かりしている5案件のうち MASS360008(輸出案件・当社にて本船手配) のスレッドを使います。 このスレッドは何往復もしていますが、使うのは いちばん下にある、最初の依頼メール です。
図1 スレッドのいちばん下(=いちばん古い6/8のメール)が、新しい案件の依頼メールです。ここに案件の条件が全部書かれています。
これが今日貼り付けるメールです。実物を開いて、同じものが表示されているか確かめてください。
図2 貼り付けるメールの全体。署名部分(会社の住所・電話)は貼り付けても構いません。AIが読み飛ばします。
ここがこの例題の心臓部です。同じメールに色を付けました。 この色の付いた部分が、そのままスプレッドシートの列に入っていきます。先にこの対応を目で見ておいてください。
図3 色の付いた18か所が、スプレッドシートの18列に入ります。件名の中にも情報が入っている点に注目してください(搬入日・依頼種別・建値・参照番号・荷受人)。
このメールを1回貼り付けると、台帳はこうなります。これがゴールです。
| 受信日時 | 依頼元 | 担当者 | 依頼種別 | 荷主参照番号 | 荷受人 | 建値 | 積地(POL) | 揚地(POD) | |
|---|---|---|---|---|---|---|---|---|---|
| 2 | 2026-06-08 14:29 | M商事株式会社 | 相澤様 | 通関・輸出依頼 | MTS-226399 | 〇〇 MOTOR (VIETNAM) CORPORATION | CIF | YOKOHAMA, JAPAN | HOCHIMINH, VIETNAM |
| 品名 | 数量・重量 | 梱包 | コンテナ | 搬入日 | 納入先 | 依頼されていること | 要返信 | 期限 | |
|---|---|---|---|---|---|---|---|---|---|
| 2 | リフロー炉(SOLSYS-8031) | 1台 L3,650×D855×H1,410mm / 1t | 木枠梱包済み | 20ft FCL ×1 | 2026-06-19 | ㈱明正 出田町営業所 | ターゲットスケジュールの連絡 | 要 | 記載なし |
図4 列が18あるので、上下2段に分けて表示しています。実際は横に1行で並びます。
ここから実際の作業です。全部で6ステップ、40分ほどを見込んでいます。
Google スプレッドシートを新規作成します。ブラウザのアドレス欄に sheets.new と入力して Enter を押すと、新しいシートがすぐ開きます。
① 新しいスプレッドシートを開く
② 左上のいちばん端のセル(A1)をクリックする
③ 下のブロックをコピーして、そのまま貼り付ける
受信日時 依頼元 担当者 依頼種別 荷主参照番号 荷受人 建値 積地(POL) 揚地(POD) 品名 数量・重量 梱包 コンテナ 搬入日 納入先 依頼されていること 要返信 期限
最後に、画面上部の「無題のスプレッドシート」をクリックして、案件台帳 という名前に変えておきます。
n8n を開いて、右上の Create Workflow から新しいワークフローを作ります。 何も置かれていない広い画面(キャンバス)が出てきます。
① 下のブロックの「コピー」を押す
② n8n の何もない画面の上でクリックしてから、⌘+V(Windows は Ctrl+V)を押す
③ 4つの四角(ノード)が並べば成功です
{
"name": "案件メール → 案件台帳",
"nodes": [
{
"parameters": {
"formTitle": "案件メールを貼り付ける",
"formDescription": "Outlook のメールをコピーして、下の欄に貼り付けてください。",
"formFields": {
"values": [
{ "fieldLabel": "件名", "requiredField": true },
{ "fieldLabel": "本文", "fieldType": "textarea", "requiredField": true }
]
},
"options": {}
},
"id": "n1",
"name": "メールを貼り付ける",
"type": "n8n-nodes-base.formTrigger",
"typeVersion": 2.2,
"position": [0, 0]
},
{
"parameters": {
"promptType": "define",
"text": "=あなたは国際物流の営業事務担当です。次の依頼メールを読み、案件台帳に載せる項目を抜き出してください。\n\n必ず次の JSON だけを返してください。前後に説明文を書かないでください。\n読み取れない項目は空文字にしてください。推測で埋めないでください。\n\n{\n \"依頼元\": \"差出人の会社名\",\n \"担当者\": \"差出人の氏名(敬称付き)\",\n \"依頼種別\": \"通関・輸出依頼 / 通関・輸入依頼 / 見積依頼 / 連絡 のいずれか\",\n \"荷主参照番号\": \"件名や本文にある取引先側の管理番号\",\n \"荷受人\": \"CONSIGNEE の正式名称\",\n \"建値\": \"CIF / FOB / EXW など\",\n \"積地\": \"POL。都市名と国名\",\n \"揚地\": \"POD。都市名と国名\",\n \"品名\": \"貨物の名称と型式\",\n \"数量重量\": \"個数・寸法・重量をまとめて\",\n \"梱包\": \"木枠 / パレット / 裸 など\",\n \"コンテナ\": \"20ft FCL / 40HQ / LCL など。本数も\",\n \"搬入日\": \"YYYY-MM-DD 形式。年がなければ受信年を補う\",\n \"納入先\": \"搬入先の営業所名や倉庫名\",\n \"依頼されていること\": \"先方が求めているアクションを1文で\",\n \"要返信\": \"要 または 不要\",\n \"期限\": \"返信や対応の期限。書かれていなければ 記載なし\"\n}\n\n--- 件名 ---\n{{ $json['件名'] }}\n\n--- 本文 ---\n{{ $json['本文'] }}",
"options": {}
},
"id": "n2",
"name": "Claudeに読ませる",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"typeVersion": 1.5,
"position": [240, 0]
},
{
"parameters": { "options": {} },
"id": "n3",
"name": "Claude",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"typeVersion": 1.3,
"position": [280, 200]
},
{
"parameters": {
"jsCode": "const t = $input.first().json.text || $input.first().json.output || '';\nconst m = t.match(/\\{[\\s\\S]*\\}/);\nconst d = m ? JSON.parse(m[0]) : {};\nconst pad = (n) => String(n).padStart(2, '0');\nconst now = new Date();\nreturn [{ json: {\n '受信日時': `${now.getFullYear()}-${pad(now.getMonth()+1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}`,\n '依頼元': d['依頼元'] || '',\n '担当者': d['担当者'] || '',\n '依頼種別': d['依頼種別'] || '',\n '荷主参照番号': d['荷主参照番号'] || '',\n '荷受人': d['荷受人'] || '',\n '建値': d['建値'] || '',\n '積地(POL)': d['積地'] || '',\n '揚地(POD)': d['揚地'] || '',\n '品名': d['品名'] || '',\n '数量・重量': d['数量重量'] || '',\n '梱包': d['梱包'] || '',\n 'コンテナ': d['コンテナ'] || '',\n '搬入日': d['搬入日'] || '',\n '納入先': d['納入先'] || '',\n '依頼されていること': d['依頼されていること'] || '',\n '要返信': d['要返信'] || '',\n '期限': d['期限'] || ''\n} }];"
},
"id": "n4",
"name": "列に整える",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [480, 0]
},
{
"parameters": {
"operation": "append",
"documentId": { "__rl": true, "value": "", "mode": "list" },
"sheetName": { "__rl": true, "value": "", "mode": "list" },
"columns": {
"mappingMode": "autoMapInputData",
"value": {},
"matchingColumns": []
},
"options": {}
},
"id": "n5",
"name": "台帳に1行追加",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [720, 0]
}
],
"connections": {
"メールを貼り付ける": { "main": [[{ "node": "Claudeに読ませる", "type": "main", "index": 0 }]] },
"Claudeに読ませる": { "main": [[{ "node": "列に整える", "type": "main", "index": 0 }]] },
"Claude": { "ai_languageModel": [[{ "node": "Claudeに読ませる", "type": "ai_languageModel", "index": 0 }]] },
"列に整える": { "main": [[{ "node": "台帳に1行追加", "type": "main", "index": 0 }]] }
},
"pinData": {}
}
貼り付けると、画面はこうなります。
図5 4つのノードが左から右に一列に並びます。下にぶら下がっている小さい「Claude」は、どのAIを使うかを指定する部品です。
貼り付けたばかりのノードには、赤い三角の警告マークが付いています。「どのアカウントを使うか」がまだ決まっていないためです。2か所だけ設定します。
下にぶら下がっている Claude のノードをダブルクリック → Credential to connect with の欄を開き、講師が用意したものを選びます。一覧に出てくるので、新規作成は不要です。
台帳に1行追加 のノードをダブルクリックして、上から順に選びます。
・Credential … 講師が用意したものを選ぶ
・Document … From list のまま、Step 1 で作った 案件台帳 を選ぶ
・Sheet … シート1 を選ぶ
・Mapping Column Mode … Map Automatically を選ぶ
Outlook に戻ります。Step 0 で確認した 6/8 の依頼メール を開いてください。
① 件名をドラッグして選択 → ⌘+C でコピー
② n8n のフォーム(次のStepで開きます)の「件名」欄に貼る
③ 本文に戻り、「株式会社明正 石田様」から「以上、何卒宜しくお願い申し上げます。」までを選択してコピー
④ フォームの「本文」欄に貼る
n8n の画面に戻り、下の方にある Execute workflow を押します。 すると 「メールを貼り付ける」 の画面(フォーム)が別のタブで開きます。
図6 この画面に貼り付けて Submit を押します。ここが「メールを n8n に入れる」ところです。
Submit を押すと、n8n の画面に戻って処理が走ります。4つのノードすべてに緑のチェックが付けば成功です。
図7 緑のチェックが4つ。どこかで赤くなったら、そのノードをダブルクリックすると理由が書いてあります。読めなければ手を挙げてください。
Step 1 で作った 案件台帳 を開いてください。2行目に、いま貼り付けたメールの内容が入っています。
図3の色分けを思い出しながら、メールのどの文字が、どの列に入ったかを1つずつ目で追ってください。 「件名の中の 6/19 が、搬入日の列に入っている」——これが分かれば、この例題の目的は達成です。
6ステップが終わった方は、こちらに進んでください。ここからが本当の練習です。
同じ手順で、他の4案件の依頼メールも貼り付けてください。CBC340018・CBC350011・OCEN360005・OWEL36J003 です。 それぞれスレッドのいちばん下のメールを使います。
| 依頼元 | 依頼種別 | 荷主参照番号 | 建値 | 積地(POL) | 揚地(POD) | コンテナ | 要返信 | |
|---|---|---|---|---|---|---|---|---|
| 2 | M商事株式会社 | 通関・輸出依頼 | MTS-226399 | CIF | YOKOHAMA, JAPAN | HOCHIMINH, VIETNAM | 20ft FCL ×1 | 要 |
| 3 | C社 | 通関・輸出依頼 | P7406-01 | — | — | — | — | 要 |
| 4 | C社 | 通関・輸出依頼 | — | CIF | — | — | — | 要 |
| 5 | O社 | 通関・輸入依頼 | — | FOB | — | — | — | 要 |
| 6 | W社 | 通関・輸出依頼 | — | CIF | — | — | — | 要 |
図8 5件入れると、「—」(空欄)がどこに多く出るかが見えてきます。空欄が多い項目ほど、メールの書き方がばらついている項目です。
Claudeに読ませる のノードをダブルクリックすると、長い日本語の文章が入っています。これが「AIへの指示(プロンプト)」です。 間違っていた箇所を、ここに書き足して直します。
・日付が「6/19」のように年がない場合は、メールの受信年を補って YYYY-MM-DD にしてください。
・コンテナは本数まで書いてください。本数の記載がなければ「×1」としてください。
・依頼種別は、件名の【 】の中に書かれている言葉を優先してください。
・荷受人は CONSIGNEE の正式名称をそのまま書き、日本語訳はしないでください。
・弊社の営業所名(出田町営業所など)は「納入先」に入れ、「荷受人」には入れないでください。
書き足したら、もう一度 Execute workflow から同じメールを入れ直して、直ったかどうかを確かめます。 直っていなければ、書き方を変えてもう一度。この繰り返しが「AIに仕事を教える」という作業の実体です。
株式会社明正 様|AI業務内製化 1DAY合宿 例題2 手順書
例題1の続きです。新しく覚えるのは「2つの入力を扱う」と「条件で枝を分ける」の2つだけ。 ノードの置き方・つなぎ方は例題1と同じですので、操作を覚え直す必要はありません。
社内指示書(SI)と、インボイス・パッキングリスト(IV/PL)を貼り付けます。 すると、同じ項目が左右に並び、一致・不一致・片方にしかないに仕分けられて、 不一致が1件でもあれば「要確認リスト」が出てきます。
当日は CBC350011(輸出・インドヨウ素) の通関用書類2点を使います。 こちらで先に突き合わせてみたところ、反応の異なる食い違いが一通り含まれていました。1案件で論点がすべてカバーできます。
図1 赤が本当の食い違い、黄が「AIは不一致と言うが、運用上は正しいかもしれない」もの。黄をどう扱うかが、この例題の本題です。
全部で5ステップ、45分ほどを見込んでいます。例題1のワークフローは残したまま、新しく1本作ります。
配布したPDFを開いて、文字を選択してコピーします。PDFのまま貼ることもできますが、まずはテキストで確実に動かします。
① CBC350011 MASTER SI のPDFを開き、⌘+A → ⌘+C で全体をコピー → メモ帳などに貼って置いておく
② CBC350011 IV PL のPDFも同じようにコピーして、別のところに貼っておく
n8n で新しいワークフローを作り、何もない画面の上で ⌘+V します。例題1と同じやり方です。
{
"name": "書類の突き合わせ",
"nodes": [
{
"parameters": {
"formTitle": "書類を2つ貼り付ける",
"formDescription": "社内指示書と、インボイス・パッキングリストの中身を貼り付けてください。",
"formFields": {
"values": [
{ "fieldLabel": "社内指示書", "fieldType": "textarea", "requiredField": true },
{ "fieldLabel": "インボイスとパッキングリスト", "fieldType": "textarea", "requiredField": true }
]
},
"options": {}
},
"id": "m1",
"name": "書類を貼り付ける",
"type": "n8n-nodes-base.formTrigger",
"typeVersion": 2.2,
"position": [0, 0]
},
{
"parameters": {
"promptType": "define",
"text": "=あなたは国際物流の通関担当です。2つの書類を突き合わせ、同じ項目を並べて一致しているかを判定してください。\n\n【大事なルール】\n- どちらが正しいかは判断しないでください。事実として「違っている」ことだけを報告してください。\n- 片方にしか書かれていない項目は status を only にしてください。\n- 書類ごとに呼び名が違っても、同じ意味の項目は同じ item にまとめてください。\n 例: 数量/Quantity、総重量/Gross Weight/KGS、容積/Measurement/M3、本船/Vessel、積地/Port of Loading\n\n次の項目を必ず確認してください。\nインボイス番号 / 荷受人 / 通知先 / 本船名と航海番号 / 積地 / 揚地 / 品名 / 数量 / 総重量 / 容積 / 個数と荷姿 / 出港日 / 金額 / L/C番号 / HSコード / 荷印\n\n必ず次の JSON だけを返してください。前後に説明文を書かないでください。\n{\n \"rows\": [\n { \"item\": \"項目名\", \"si\": \"社内指示書の値\", \"iv\": \"インボイス側の値\", \"status\": \"match\" または \"diff\" または \"only\" }\n ]\n}\n\n--- 社内指示書 ---\n{{ $json['社内指示書'] }}\n\n--- インボイスとパッキングリスト ---\n{{ $json['インボイスとパッキングリスト'] }}",
"options": {}
},
"id": "m2",
"name": "Claudeに突き合わせさせる",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"typeVersion": 1.5,
"position": [240, 0]
},
{
"parameters": { "options": {} },
"id": "m3",
"name": "Claude",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"typeVersion": 1.3,
"position": [280, 200]
},
{
"parameters": {
"jsCode": "const t = $input.first().json.text || $input.first().json.output || '';\nconst m = t.match(/\\{[\\s\\S]*\\}/);\nconst d = m ? JSON.parse(m[0]) : { rows: [] };\nconst rows = d.rows || [];\nconst ng = rows.filter(r => r.status !== 'match');\nreturn [{ json: {\n '確認が必要な件数': ng.length,\n '要確認リスト': ng,\n '一致した項目': rows.filter(r => r.status === 'match').map(r => r.item),\n '全体': rows\n} }];"
},
"id": "m4",
"name": "食い違いを数える",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [480, 0]
},
{
"parameters": {
"conditions": {
"options": { "caseSensitive": true, "leftValue": "", "typeValidation": "loose", "version": 2 },
"conditions": [
{
"id": "c1",
"leftValue": "={{ $json['確認が必要な件数'] }}",
"rightValue": 0,
"operator": { "type": "number", "operation": "gt" }
}
],
"combinator": "and"
},
"options": {}
},
"id": "m5",
"name": "食い違いがあるか",
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [700, 0]
},
{
"parameters": {
"assignments": {
"assignments": [
{ "id": "a1", "name": "結果", "value": "要確認", "type": "string" },
{ "id": "a2", "name": "件数", "value": "={{ $json['確認が必要な件数'] }}", "type": "string" },
{ "id": "a3", "name": "中身", "value": "={{ JSON.stringify($json['要確認リスト'], null, 2) }}", "type": "string" }
]
},
"options": {}
},
"id": "m6",
"name": "要確認リストを作る",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [920, -100]
},
{
"parameters": {
"assignments": {
"assignments": [
{ "id": "b1", "name": "結果", "value": "確認不要(すべて一致)", "type": "string" }
]
},
"options": {}
},
"id": "m7",
"name": "確認不要",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [920, 100]
}
],
"connections": {
"書類を貼り付ける": { "main": [[{ "node": "Claudeに突き合わせさせる", "type": "main", "index": 0 }]] },
"Claudeに突き合わせさせる": { "main": [[{ "node": "食い違いを数える", "type": "main", "index": 0 }]] },
"Claude": { "ai_languageModel": [[{ "node": "Claudeに突き合わせさせる", "type": "ai_languageModel", "index": 0 }]] },
"食い違いを数える": { "main": [[{ "node": "食い違いがあるか", "type": "main", "index": 0 }]] },
"食い違いがあるか": { "main": [[{ "node": "要確認リストを作る", "type": "main", "index": 0 }], [{ "node": "確認不要", "type": "main", "index": 0 }]] }
},
"pinData": {}
}
図2 右から2つ目が今回はじめて出てくる「分岐」です。件数が1件以上なら上、0件なら下に流れます。
① 下にぶら下がっている Claude のノードをダブルクリックし、例題1と同じクレデンシャルを選ぶ
② Execute workflow を押す
③ 開いたフォームに、Step 1 でコピーした2つの書類をそれぞれ貼り付けて Submit
今回はスプレッドシートに書き出しません。n8nの画面で結果を見ます。いちばん右のノードをクリックすると、右側に結果が出ます。
ここが本題です。AIが出した要確認リストと、図1の表を見比べてください。次の3つに分けます。
③ 見つけられなかったものがあれば、それも書き出してください。AIが苦手な形が分かります。
Claudeに突き合わせさせる のノードを開き、指示文に「これは不一致として報告しなくてよい」というルールを書き足します。
・荷受人が「TO THE ORDER OF ○○銀行」の場合は、L/C取引のため正常です。
この場合は、指示書の NOTIFY 欄とインボイス側の荷受人を比べてください。
・数量は、正味重量と総重量を区別してください。別の項目として扱い、
正味どうし・総重量どうしで比べてください。混ぜて比べないでください。
・社内指示書の金額が 0.00 の場合は、未記入とみなし、不一致として報告しないでください。
・日付は表記の違い(2025.12.16 と DEC. 16, 2025)を同じものとして扱ってください。
書き足したら、もう一度 Execute workflow から同じ書類を入れ直して、要確認リストが2件前後まで減るかを確かめます。
CBC350011 向けに調整したものを、そのまま別の案件に当ててみます。