ローン引受分析
上級
これはDocument Extraction, AI Summarization分野の自動化ワークフローで、17個のノードを含みます。主にCode, MistralAi, ManualTrigger, SplitInBatches, Agentなどのノードを使用。 ローン文書分析のオートメーション化(貸出判断用)をMistral OCRとGPTで実行
前提条件
- •OpenAI API Key
ワークフロープレビュー
ノード接続関係を可視化、ズームとパンをサポート
ワークフローをエクスポート
以下のJSON設定をn8nにインポートして、このワークフローを使用できます
{
"id": "rVKBWXqaa79EfTVA",
"meta": {
"instanceId": "db1715da5f21adba44ce4ea3b08abb06cd1771e876f5ad2751fcafd78c5eb9dc",
"templateCredsSetupCompleted": true
},
"name": "UnderwritingLoanAnalysis",
"tags": [],
"nodes": [
{
"id": "0d40759f-812a-4972-ba74-e42c8d5aa258",
"name": "フォルダを検索",
"type": "n8n-nodes-base.microsoftOneDrive",
"position": [
624,
0
],
"parameters": {
"query": "<Your Folder Name>",
"resource": "folder",
"operation": "search"
},
"credentials": {
"microsoftOneDriveOAuth2Api": {
"id": "<Your One Drive API Key>",
"name": "Microsoft Drive account"
}
},
"typeVersion": 1
},
{
"id": "65de0a29-5e09-41ae-b14c-e83a10eb1be5",
"name": "フォルダ内のアイテムを取得",
"type": "n8n-nodes-base.microsoftOneDrive",
"position": [
832,
0
],
"parameters": {
"folderId": "={{ $json.id }}",
"resource": "folder"
},
"credentials": {
"microsoftOneDriveOAuth2Api": {
"id": "<Your One Drive API Key>",
"name": "Microsoft Drive account"
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "bdfdb814-df76-42ff-8b07-926c7e7d48c2",
"name": "ファイルをダウンロード",
"type": "n8n-nodes-base.microsoftOneDrive",
"position": [
1216,
80
],
"parameters": {
"fileId": "={{ $('Get items in a folder').item.json.id }}",
"operation": "download"
},
"credentials": {
"microsoftOneDriveOAuth2Api": {
"id": "<Your One Drive API Key>",
"name": "Microsoft Drive account"
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "bcd0718c-df22-41e1-9754-a2298877ae43",
"name": "テキストを抽出",
"type": "n8n-nodes-base.mistralAi",
"position": [
1376,
80
],
"parameters": {
"options": {}
},
"credentials": {
"mistralCloudApi": {
"id": "<Your OCR API Key>",
"name": "Mistral Cloud account"
}
},
"typeVersion": 1
},
{
"id": "6eaee806-a5e6-4c5d-b89a-500bd70cc03d",
"name": "ファイルを分類",
"type": "n8n-nodes-base.code",
"position": [
1584,
80
],
"parameters": {
"jsCode": "// get filename from Download node\nconst fileName = ($('Download a file').first().json.name || '').toLowerCase();\n\n// get extracted text from OCR node\nconst text = ($input.first().json.extractedText || '').toLowerCase();\n\nlet type = \"Unknown\";\n\n// --- Rule-based classification ---\n\n// Priority 1: File name clues\nif (fileName.includes(\"passport\")) type = \"Passport\";\nelse if (fileName.includes(\"license\") || fileName.includes(\"dl\")) type = \"Driving License\";\nelse if (fileName.includes(\"mortgage\")) type = \"Mortgage Application\";\nelse if (fileName.includes(\"proof\") && fileName.includes(\"fund\")) type = \"Proof of Funds Letter\";\nelse if (fileName.includes(\"pay\") || fileName.includes(\"paystub\")) type = \"Employee Pay Statement\";\nelse if (fileName.includes(\"t4\")) type = \"T4 Statement\";\nelse if (fileName.includes(\"electric\") || fileName.includes(\"hydro\")) type = \"Electricity Bill\";\nelse if (fileName.includes(\"internet\") || fileName.includes(\"shaw\")) type = \"Internet Bill\";\nelse if (fileName.includes(\"statement\") && fileName.includes(\"account\")) type = \"Account Statement\";\nelse if (fileName.includes(\"bank\")) type = \"Bank Statement\";\n\n// Priority 2: Text-based fallback\nelse if (text.includes(\"gross pay\") || text.includes(\"net pay\")) type = \"Employee Pay Statement\";\nelse if (text.includes(\"bank of montreal\") || text.includes(\"scotiabank\") || text.includes(\"royal bank\")) type = \"Bank Statement\";\nelse if (text.includes(\"proof of funds\")) type = \"Proof of Funds Letter\";\nelse if (text.includes(\"mortgage application\")) type = \"Mortgage Application\";\nelse if (text.includes(\"driver\") && text.includes(\"licence\")) type = \"Driving License\";\nelse if (text.includes(\"internet\") && text.includes(\"usage\")) type = \"Internet Bill\";\nelse if (text.includes(\"hydro\") || text.includes(\"electricity\")) type = \"Electricity Bill\";\nelse if (text.includes(\"t4\") && text.includes(\"income\")) type = \"T4 Statement\";\n\nreturn [{\n json: {\n FileName: $('Download a file').first().json.name,\n DocumentType: type,\n ExtractedText: $input.first().json.extractedText\n }\n}];\n"
},
"typeVersion": 2,
"alwaysOutputData": true
},
{
"id": "15d653cd-af01-43a1-ac1d-1497774745dd",
"name": "データを結合",
"type": "n8n-nodes-base.code",
"position": [
1248,
-256
],
"parameters": {
"jsCode": "// Gather all items coming from the \"Done\" output of the Loop Over Items node\nconst docs = $input.all().map(item => ({\n FileName: item.json.FileName || null,\n DocumentType: item.json.DocumentType || \"Unknown\",\n ExtractedText: item.json.ExtractedText || \"\"\n}));\n\nreturn [{\n json: {\n BorrowerName: \"Kenneth Smith\", // replace with dynamic value if available\n Documents: docs\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "fa0b2bc5-2038-4b94-8650-5908298c64dc",
"name": "AIエージェント",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1392,
-256
],
"parameters": {
"text": "=You will receive an array of documents belonging to a single mortgage applicant.\n\nEach document object includes:\n- FileName \n- DocumentType \n- ExtractedText (the OCR text from the original file)\n\nAnalyze the full dataset, identify document types, extract key financial information, and produce an underwriting summary and decision as described in the system prompt.\n\nBorrower Documents:\n{{ JSON.stringify($json.Documents, null, 2) }}\n",
"options": {
"systemMessage": "=You are a senior mortgage underwriter at a Canadian financial institution.\n\nYou will analyze a borrower’s full document set to determine mortgage eligibility, loan feasibility, and documentation completeness.\n\nYour analysis must include:\n\n### 1. Identity Verification\nConfirm borrower identity, address, and citizenship using ID documents (Passport, Driver’s License, Utility Bills).\n\n### 2. Employment & Income Verification\nValidate employment details, employer name, job title, tenure, and consistency of pay across pay statements, T4s, and tax filings.\n\n### 3. Asset & Liability Review\nSummarize checking, savings, and investment balances. \nIdentify recurring debts or monthly obligations (utilities, rent, phone, insurance, etc.). \nCalculate Debt-to-Income (DTI) ratio.\n\n### 4. Property & Loan Analysis\nIf a mortgage application or loan-related document is present, extract:\n- Lender name and officer\n- Loan amount and term\n- Interest rate type (fixed / variable)\n- Loan purpose (purchase / refinance)\n- Down payment and percentage\n- Property value and address\n- Property type and use (primary, investment, secondary)\n- Amortization structure\n- Derived Loan-to-Value (LTV = loan amount ÷ property value)\nThen evaluate:\n- Whether the borrower’s verified assets can support the required down payment.\n- Whether DTI and LTV fall within standard underwriting thresholds.\n- Any property or loan risks (e.g., old property, low down payment, non-owner-occupied use).\n\n### 5. Document Consistency\nIdentify missing, inconsistent, or outdated documents (expired IDs, missing pay stubs, missing credit report).\n\n### 6. Decision\nProvide a professional underwriter-style decision with justification:\n- **Decision:** Approve / Approve with conditions / Decline / Escalate\n- **Rationale:** Clear bullet points explaining the reasoning.\n- **Next Steps:** Requested documents or verifications before final approval.\n\n### Output Format\nReturn your analysis as Markdown:\n\n#### Step 1: Identity Verification\n#### Step 2: Employment & Income\n#### Step 3: Assets & Liabilities\n#### Step 4: Property & Loan Analysis\n#### Step 5: Document Consistency\n#### Step 6: Final Decision\n#### Decision Summary (bullet points)\n"
},
"promptType": "define"
},
"typeVersion": 2.2
},
{
"id": "1be14652-9fa5-473b-afc8-901a0ec4ed07",
"name": "OpenAIチャットモデル",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
1392,
-112
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "<Your LLM Model Name>"
},
"options": {}
},
"credentials": {
"openAiApi": {
"id": "<Your LLM Model API Key>",
"name": "OpenAi account 2"
}
},
"typeVersion": 1.2
},
{
"id": "e5fe5cff-e538-4032-8df5-1246099618d1",
"name": "ワークフローを実行時",
"type": "n8n-nodes-base.manualTrigger",
"position": [
432,
0
],
"parameters": {},
"typeVersion": 1
},
{
"id": "30b481ed-670c-4303-a0da-7362e94fa2d4",
"name": "付箋",
"type": "n8n-nodes-base.stickyNote",
"position": [
-480,
176
],
"parameters": {
"color": 4,
"width": 816,
"content": "**Solution: \n\ntrigger the run, grab files from a known OneDrive folder, loop in batches, OCR each file, classify it with simple filename+text rules, aggregate into a borrower payload, then have the LLM return JSON first and a brief Markdown decision. Add filters/retries, bucket unknown/unreadable docs, log counts/costs, and keep PII out of logs.**"
},
"typeVersion": 1
},
{
"id": "9ea5459a-21f6-4e75-830b-b4b38400f089",
"name": "付箋1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-480,
-224
],
"parameters": {
"color": 4,
"width": 816,
"content": "**Problem Statement**\n\nUnderwriters receive borrower documents in mixed formats and naming conventions (IDs, paystubs, bank statements, utility bills, tax forms). Manually opening, reading, and sorting these files is slow and error-prone. Two big pain points: 1) reliably extracting text from scans, and 2) consistently identifying document types to assemble a complete borrower picture. This leads to missed docs, inconsistent decisions, weak audit trails, and high turnaround time—especially when multiple borrowers are involved."
},
"typeVersion": 1
},
{
"id": "4d426895-0b7f-4ea1-a38f-5188801f586a",
"name": "付箋2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-480,
-32
],
"parameters": {
"color": 4,
"width": 816,
"height": 176,
"content": "***Constraints***\n\nFiles live in OneDrive folders with variable naming.\nQuality of scans varies; OCR can fail or return partial text.\nDocument classification needs to be understandable and easily adjustable.\nPII must not leak through logs or exports.\nCosts (OCR + LLM tokens) rise with folder size and page counts.\nYou need a deterministic path when AI isn’t confident (fallbacks, flags)."
},
"typeVersion": 1
},
{
"id": "844083c1-ce99-4ab3-98b7-7a6523d88109",
"name": "アイテムをループ処理",
"type": "n8n-nodes-base.splitInBatches",
"disabled": true,
"position": [
1040,
0
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "40f0d23a-aae0-4450-959e-3b98032659c2",
"name": "付箋3",
"type": "n8n-nodes-base.stickyNote",
"position": [
368,
-144
],
"parameters": {
"width": 208,
"height": 112,
"content": "Entry trigger used for local testing and manual runs; it simply starts the pipeline and hands off to the OneDrive folder search."
},
"typeVersion": 1
},
{
"id": "781728d1-9f06-4e95-adfc-ae2095771027",
"name": "付箋4",
"type": "n8n-nodes-base.stickyNote",
"position": [
624,
-144
],
"parameters": {
"width": 320,
"height": 112,
"content": "Finds the target borrower documents container in OneDrive and outputs the folder id that downstream nodes use, Takes the found folder id and lists the files inside so the loop can process each item"
},
"typeVersion": 1
},
{
"id": "8425b303-96cc-4ff9-ba20-a386a300519d",
"name": "付箋5",
"type": "n8n-nodes-base.stickyNote",
"position": [
992,
288
],
"parameters": {
"width": 768,
"height": 256,
"content": "**Loop Over** : Drives per-file processing: for each listed file it routes to download/OCR/classify, and when the last item is done it forwards the collected results to the combiner. \n\n**Download a file (OneDrive)**: Fetches the actual file binary (plus metadata) for the current item so OCR can read its contents.\n\n**Extract text (Mistral AI)**: Runs OCR on the downloaded file and emits the extracted text that classification and later analysis depend on.\n\n**Classify the File (Code)**: Uses filename clues and OCR text to assign a document type (e.g., Passport, Paystub, Bank Statement, Utility Bill, T4, Proof of Funds, Mortgage Application, or Unknown) and forwards a compact record per file."
},
"typeVersion": 1
},
{
"id": "f55f83eb-f7b7-4982-99c1-ec21f573793c",
"name": "付箋6",
"type": "n8n-nodes-base.stickyNote",
"position": [
1200,
-432
],
"parameters": {
"width": 560,
"content": "**Combine the Data (Code)**: Aggregates all per-file records into a single borrower payload with BorrowerName and a Documents[] array ready for underwriting analysis. \n**AI Agent (@n8n/n8n-nodes-langchain.agent)**: Consumes the consolidated Documents[], applies an underwriting-oriented system prompt, and produces the decision-focused analysis for the borrower. Provides the language model (gpt-4.1-mini) that the AI Agent uses to generate the underwriting summary and decision.\n"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "b3d81169-9b6f-4530-b765-1ab386b90e4a",
"connections": {
"bcd0718c-df22-41e1-9754-a2298877ae43": {
"main": [
[
{
"node": "6eaee806-a5e6-4c5d-b89a-500bd70cc03d",
"type": "main",
"index": 0
}
]
]
},
"bdfdb814-df76-42ff-8b07-926c7e7d48c2": {
"main": [
[
{
"node": "bcd0718c-df22-41e1-9754-a2298877ae43",
"type": "main",
"index": 0
}
]
]
},
"844083c1-ce99-4ab3-98b7-7a6523d88109": {
"main": [
[
{
"node": "15d653cd-af01-43a1-ac1d-1497774745dd",
"type": "main",
"index": 0
}
],
[
{
"node": "bdfdb814-df76-42ff-8b07-926c7e7d48c2",
"type": "main",
"index": 0
}
]
]
},
"0d40759f-812a-4972-ba74-e42c8d5aa258": {
"main": [
[
{
"node": "65de0a29-5e09-41ae-b14c-e83a10eb1be5",
"type": "main",
"index": 0
}
]
]
},
"15d653cd-af01-43a1-ac1d-1497774745dd": {
"main": [
[
{
"node": "fa0b2bc5-2038-4b94-8650-5908298c64dc",
"type": "main",
"index": 0
}
]
]
},
"6eaee806-a5e6-4c5d-b89a-500bd70cc03d": {
"main": [
[
{
"node": "844083c1-ce99-4ab3-98b7-7a6523d88109",
"type": "main",
"index": 0
}
]
]
},
"1be14652-9fa5-473b-afc8-901a0ec4ed07": {
"ai_languageModel": [
[
{
"node": "fa0b2bc5-2038-4b94-8650-5908298c64dc",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"65de0a29-5e09-41ae-b14c-e83a10eb1be5": {
"main": [
[
{
"node": "844083c1-ce99-4ab3-98b7-7a6523d88109",
"type": "main",
"index": 0
}
]
]
},
"e5fe5cff-e538-4032-8df5-1246099618d1": {
"main": [
[
{
"node": "0d40759f-812a-4972-ba74-e42c8d5aa258",
"type": "main",
"index": 0
}
]
]
}
}
}よくある質問
このワークフローの使い方は?
上記のJSON設定コードをコピーし、n8nインスタンスで新しいワークフローを作成して「JSONからインポート」を選択、設定を貼り付けて認証情報を必要に応じて変更してください。
このワークフローはどんな場面に適していますか?
上級 - 文書抽出, AI要約
有料ですか?
このワークフローは完全無料です。ただし、ワークフローで使用するサードパーティサービス(OpenAI APIなど)は別途料金が発生する場合があります。
関連ワークフロー
キャッシュの照合
Mistral AI および OpenAI GPT-4 を用いた請求書と銀行通帳照合の自動化
Code
Mistral Ai
Manual Trigger
+
Code
Mistral Ai
Manual Trigger
15 ノードVinay Gangidi
コンテンツ作成
自動化学術論文メタデータおよび変数抽出(GeminiからGoogle Sheetsへ)
論文のメタデータおよび変数抽出の自動化:GeminiからGoogle Sheetsへ
Set
Code
Wait
+
Set
Code
Wait
39 ノードOwenLee
文書抽出
AI および Gmail を使って YNAB 内の Amazon 取引の備考を自動更新
AIとGmailを使ってYNABのAmazon取引コメントを自動更新
If
Set
Wait
+
If
Set
Wait
30 ノードAngel Menendez
文書抽出
初学者データ分析:GPT-4oを使ってGoogleシートで結合・フィルタリング・サマリー
初心者のデータ分析:GPT-4o を使用して Google スプレッドシートで結合、フィルタリング、集計
If
Set
Code
+
If
Set
Code
21 ノードRobert Breen
文書抽出
Facebookページコメント管理ボット:返信、削除、利用制限、通知
AI駆動のFacebookコメント管理:自動返信、削除、利用制限、通知
If
Set
Code
+
If
Set
Code
59 ノードSpaGreen Creative
ソーシャルメディア
SlackとAsanaを使用した仮想Scラムマスター
OpenAI、Slack、Asanaを統合したAIベースのScラムマスターアシスタント
Set
Code
Html
+
Set
Code
Html
35 ノードŁukasz
プロジェクト管理