Análisis de préstamos de suscripción
Este es unDocument Extraction, AI Summarizationflujo de automatización del dominio deautomatización que contiene 17 nodos.Utiliza principalmente nodos como Code, MistralAi, ManualTrigger, SplitInBatches, Agent. Análisis automatizado de documentos de préstamo para decisiones de suscripción con Mistral OCR y GPT
- •Clave de API de OpenAI
Nodos utilizados (17)
{
"id": "rVKBWXqaa79EfTVA",
"meta": {
"instanceId": "db1715da5f21adba44ce4ea3b08abb06cd1771e876f5ad2751fcafd78c5eb9dc",
"templateCredsSetupCompleted": true
},
"name": "UnderwritingLoanAnalysis",
"tags": [],
"nodes": [
{
"id": "0d40759f-812a-4972-ba74-e42c8d5aa258",
"name": "Buscar una carpeta",
"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": "Obtener elementos en una carpeta",
"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": "Descargar un archivo",
"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": "Extraer texto",
"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": "Clasificar el archivo",
"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": "Combinar los datos",
"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": "Agentee de IA",
"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": "Modelo de Chat 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": "Al hacer clic en 'Ejecutar flujo de trabajo'",
"type": "n8n-nodes-base.manualTrigger",
"position": [
432,
0
],
"parameters": {},
"typeVersion": 1
},
{
"id": "30b481ed-670c-4303-a0da-7362e94fa2d4",
"name": "Nota adhesiva",
"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": "Nota adhesiva1",
"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": "Nota adhesiva2",
"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": "Iterar sobre elementos",
"type": "n8n-nodes-base.splitInBatches",
"disabled": true,
"position": [
1040,
0
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "40f0d23a-aae0-4450-959e-3b98032659c2",
"name": "Nota adhesiva3",
"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": "Nota adhesiva4",
"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": "Nota adhesiva5",
"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": "Nota adhesiva6",
"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": "Agente de IA",
"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": "Agente de IA",
"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
}
]
]
}
}
}¿Cómo usar este flujo de trabajo?
Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.
¿En qué escenarios es adecuado este flujo de trabajo?
Avanzado - Extracción de documentos, Resumen de IA
¿Es de pago?
Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.
Flujos de trabajo relacionados recomendados
Vinay Gangidi
@vgangidiCompartir este flujo de trabajo