{
  "name": "Extract meeting details with GPT-4.1-mini and evaluate accuracy in Google Sheets",
  "nodes": [
    {
      "id": "6a5ff5a1-b75f-4cf2-a952-ff20bf29c054",
      "name": "trigger",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        -112,
        -16
      ]
    },
    {
      "id": "fe99e9c0-9104-4b2b-add6-ef68b331491f",
      "name": "normalize_trigger_input",
      "type": "n8n-nodes-base.set",
      "position": [
        192,
        -16
      ]
    },
    {
      "id": "cc5675cc-44b6-4a68-befd-b46062440ae4",
      "name": "load_eval_data",
      "type": "n8n-nodes-base.evaluationTrigger",
      "position": [
        -96,
        336
      ]
    },
    {
      "id": "fcd81c55-e173-4cd2-b870-8b5af138e4dd",
      "name": "merged_inputs",
      "type": "n8n-nodes-base.noOp",
      "position": [
        480,
        -16
      ]
    },
    {
      "id": "91fca1e3-7d83-4798-8b59-b135eb7deac4",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        960,
        224
      ]
    },
    {
      "id": "06c934d2-e0dc-449f-8a87-945043c84bf0",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        736,
        224
      ]
    },
    {
      "id": "a37b5bfa-5671-4854-a18e-1ab5b0e25e7d",
      "name": "output_fixer",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        944,
        448
      ]
    },
    {
      "id": "4725d4f7-1e51-4042-b6fe-f3d98630be9d",
      "name": "OpenAI Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2560,
        464
      ]
    },
    {
      "id": "4b62e05b-86b8-4699-9c25-33b93b771912",
      "name": "not_evaluating",
      "type": "n8n-nodes-base.if",
      "position": [
        2048,
        -48
      ]
    },
    {
      "id": "d142e14e-2764-4524-97ff-d5fe200f293c",
      "name": "handle_error",
      "type": "n8n-nodes-base.stopAndError",
      "position": [
        1552,
        288
      ]
    },
    {
      "id": "78818b79-e7b4-4510-84b1-536dd8f5f993",
      "name": "normalize_eval_data",
      "type": "n8n-nodes-base.set",
      "position": [
        208,
        336
      ]
    },
    {
      "id": "23c9765a-cc3f-4335-9b47-93034435c48c",
      "name": "record_eval_output",
      "type": "n8n-nodes-base.evaluation",
      "position": [
        2768,
        224
      ]
    },
    {
      "id": "d819daba-640c-4539-bdd1-afddfac010ce",
      "name": "evaluate_match",
      "type": "n8n-nodes-base.evaluation",
      "position": [
        2416,
        224
      ]
    },
    {
      "id": "aeded02e-86ef-4243-a06f-03a71ad56951",
      "name": "extract_meeting_details",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        784,
        -32
      ]
    },
    {
      "id": "ee15e729-f594-4692-949e-78e7845d6c27",
      "name": "validate_output",
      "type": "n8n-nodes-base.if",
      "position": [
        1520,
        -32
      ]
    },
    {
      "id": "381c017a-5248-47ea-a723-ad8dcf379a67",
      "name": "normalize_agent_output",
      "type": "n8n-nodes-base.set",
      "position": [
        1776,
        -48
      ]
    },
    {
      "id": "974f63f9-4151-4ed2-a05b-3217d164dfd4",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -800,
        -736
      ],
      "parameters": {
        "width": 496,
        "height": 1744,
        "content": "# AI Meeting Extractor with Evaluation Framework\n\nProduction-ready AI agent subworkflow that extracts structured meeting details from natural language messages. Demonstrates best practices for validat"
      }
    },
    {
      "id": "fada81c5-4293-419f-80a1-6a184fb00e8b",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        496
      ],
      "parameters": {
        "width": 624,
        "height": 448,
        "content": "## Load Evaluation Data\n\nGets test cases from Google Sheet and normalizes them to match the format from the trigger node.\n\n**load_eval_data**: Change the spreadsheet ID here to point to your copy of t"
      }
    },
    {
      "id": "55d30f15-6fe4-4c11-a25f-e4b9a4fd173f",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        624,
        -592
      ],
      "parameters": {
        "width": 688,
        "height": 1184,
        "content": "## AI Agent - Core Extraction Logic\n\nThis is the heart of the workflow: an AI agent that extracts meeting details from natural language text.\n\n**What it does**:\n- Takes message text, reference datetim"
      }
    },
    {
      "id": "2a960655-689d-4d66-9229-7613b5dc9d70",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1456,
        -976
      ],
      "parameters": {
        "width": null,
        "height": 1440,
        "content": "## Output Validation & Error Handling\n\n**validate_output**: Checks that the AI agent actually returned data.\n\n⚠️ **Why this is needed**: The AI Agent node with \"Continue on Error Output\" sometimes tak"
      }
    },
    {
      "id": "7b5cdd55-b731-4d13-95ab-6b4cdfb81253",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1984,
        -896
      ],
      "parameters": {
        "width": null,
        "height": 1056,
        "content": "## Evaluation Mode Router\n\n**not_evaluating**: Routes the workflow based on execution mode.\n\n- **False path (evaluation mode)**: Continues to evaluation nodes\n- **True path (normal mode)**: Ends workf"
      }
    },
    {
      "id": "967293ff-bcc4-4cdc-984e-286026662f95",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2384,
        -464
      ],
      "parameters": {
        "width": 560,
        "height": 1104,
        "content": "## Evaluation: Compare Actual vs Expected\n\n**evaluate_match**: Compares AI output against ground truth from test data.\n\nUses GPT-5-mini to perform semantic matching:\n- **Exact match**: date, time, mee"
      }
    }
  ],
  "connections": {
    "trigger": {
      "main": [
        [
          {
            "node": "normalize_trigger_input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "output_fixer": {
      "ai_languageModel": [
        [
          {
            "node": "Structured Output Parser",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "merged_inputs": {
      "main": [
        [
          {
            "node": "extract_meeting_details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "evaluate_match": {
      "main": [
        [
          {
            "node": "record_eval_output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "load_eval_data": {
      "main": [
        [
          {
            "node": "normalize_eval_data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "not_evaluating": {
      "main": [
        [],
        [
          {
            "node": "evaluate_match",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "validate_output": {
      "main": [
        [
          {
            "node": "normalize_agent_output",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "handle_error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "extract_meeting_details",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "evaluate_match",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "normalize_eval_data": {
      "main": [
        [
          {
            "node": "merged_inputs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "normalize_agent_output": {
      "main": [
        [
          {
            "node": "not_evaluating",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "extract_meeting_details": {
      "main": [
        [
          {
            "node": "validate_output",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "handle_error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "normalize_trigger_input": {
      "main": [
        [
          {
            "node": "merged_inputs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "extract_meeting_details",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    }
  }
}