{
  "id": "4sTIIfK40TvKs0O8",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "AI-Powered Student Answer Sheet Evaluation Agent",
  "tags": [],
  "nodes": [
    {
      "id": "7e734b0a-96c8-4c30-b7a0-7dbb3bce0771",
      "name": "Answer Sheet Uploader",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -672,
        -224
      ],
      "parameters": {
        "options": {},
        "formTitle": "Examiner",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Examiner Name",
              "placeholder": "Examiner Name",
              "requiredField": true
            },
            {
              "fieldType": "file",
              "fieldLabel": "Upload Answer Sheet",
              "acceptFileTypes": ".png,.jpg"
            }
          ]
        },
        "formDescription": "Examiner AI Agent"
      },
      "typeVersion": 2.3
    },
    {
      "id": "328e9f3e-a81e-405f-b2af-3707c71121dd",
      "name": "Analyze an image",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        -448,
        -224
      ],
      "parameters": {
        "text": "=The image is an answer paper of a student, you need to analyze and pick each and every answer along with section name, question number and student name.",
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-2.5-flash",
          "cachedResultName": "models/gemini-2.5-flash"
        },
        "options": {},
        "resource": "image",
        "inputType": "binary",
        "operation": "analyze",
        "binaryPropertyName": "Upload_Answer_Sheet"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ba55ae1e-0c3a-4050-ad8f-91f9aa5887f5",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -96,
        -224
      ],
      "parameters": {
        "text": "=Marks of the student:\n{{ $json.content.parts[0].text }}\nExaminer Name:{{ $('Answer Sheet Uploader').item.json['Examiner Name'] }}\n\n",
        "options": {
          "systemMessage": "=You are an intelligent Answer Evaluation Agent designed to assess student answer sheets accurately.\n\nYour task is to cross-check each student\u2019s answers from the uploaded Student Answer Sheet (user input) with the provided Question Paper (tool: \u201cQuestion Paper 5Th Class\u201d) and the Correct Answer Paper (tool: \u201cAnswer Paper 5th Class\u201d), and then calculate the marks accordingly.\n\nSteps 1:\nEvaluation Process \nRead the Question Paper (Question Paper 5Th Class)\nExtract all questions and question numbers.\nMaintain the order and numbering as given.\nRead the Correct Answer Paper (Answer Paper 5th Class)\nExtract correct answers corresponding to each question number.\nEnsure mapping between question number and correct answer is accurate.\n\nStep 2:\nRead the Student Answer Sheet (user input)\nIdentify the student\u2019s answers for each question number.\nMaintain consistent numbering for comparison.\n\nStep 3:\nCompare Answers\nMatch each student answer with the correct answer from the Answer Paper.\nIf the answer matches exactly (or within acceptable variation for text answers), mark as Correct; otherwise mark as Incorrect. ignore punctuation marks like .,;:'\"\"' \n\n\u20b9 is equal Rs. or Rs or rs. or rs or ruppees\n\nStep 4:\nCalculate Marks\nuse append row tool to append the below information.\nAssign marks for each correct answer (e.g., 2 mark each).\n\nAppend the Evaluation Summary using append row tool\nStudent Name\nExaminer Name\nCorrect Answer - no of correct answers\nIncorrect Answers - no of incorrect answers\nTotal Marks - Total marks \nTotal Marks Obtain - Marks obtain by student\n\n\nStep 5:\nCretae a JSON as final output in the below format for all the questions.\n\n{\n  \"Student Name\": \"value\",\n  \"Teacher Name\": \"value\",\n  \"Total Correct Answers\": 8,\n  \"Total Incorrect Answers\": 2,\n  \"Total Marks\": 10,\n  \"Marks Obtained\": 8,\n  \"Data\": [\n    {\n      \"Question\": \"value\",\n      \"Correct Answer\": \"value\",\n      \"Student Answer\": \"value\",\n      \"Status\": \"value\"\n    },\n    {\n      \"Question\": \"value\",\n      \"Correct Answer\": \"value\",\n      \"Student Answer\": \"value\",\n      \"Status\": \"value\"\n    },\n    {\n      \"Question\": \"value\",\n      \"Correct Answer\": \"value\",\n      \"Student Answer\": \"value\",\n      \"Status\": \"value\"\n    }\n  ]\n}\n"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "9eb8d9c8-0bc9-4637-a57b-c4120b7cfd7c",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -224,
        0
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-2.5-pro"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "62e3fcd5-e0d5-482d-b123-c4712d11d753",
      "name": "Question Paper 5Th Class",
      "type": "n8n-nodes-base.googleDocsTool",
      "position": [
        -96,
        0
      ],
      "parameters": {
        "operation": "get",
        "documentURL": "=https://docs.google.com/document/d/1-B5C4_RjUpNbtw3ByEQXTh8r3_0IPTwwEx7EKqFqmG0/edit?usp=drive_link"
      },
      "credentials": {
        "googleDocsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "844d4fe0-49da-421d-9bd4-29297118e858",
      "name": "Answer Paper 5th Class",
      "type": "n8n-nodes-base.googleDocsTool",
      "position": [
        32,
        0
      ],
      "parameters": {
        "operation": "get",
        "documentURL": "https://docs.google.com/document/d/1DPWpi4wLbLumV6FaKk2G0GfNY63l5GCLfBqMeAUs5UY/edit?usp=drive_link"
      },
      "credentials": {
        "googleDocsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "252ace90-c1c6-403e-bfdc-297808ed2abf",
      "name": "Structured Output Parser1",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        160,
        0
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"Student Name\": \"John Doe\",\n  \"Examiner Name\": \"Mrs. Smith\",\n  \"Total Correct Answers\": 8,\n  \"Total Incorrect Answers\": 2,\n  \"Total Marks\": 10,\n  \"Marks Obtained\": 8,\n  \"Data\": [\n    {\n      \"Question\": \"Q1\",\n      \"Correct Answer\": \"B\",\n      \"Student Answer\": \"B\",\n      \"Status\": \"Correct\"\n    },\n    {\n      \"Question\": \"Q2\",\n      \"Correct Answer\": \"A\",\n      \"Student Answer\": \"C\",\n      \"Status\": \"Incorrect\"\n    },\n    {\n      \"Question\": \"Q3\",\n      \"Correct Answer\": \"D\",\n      \"Student Answer\": \"D\",\n      \"Status\": \"Correct\"\n    }\n  ]\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "5875281b-95c5-45b0-b97a-4f24fdb54f82",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -768,
        -320
      ],
      "parameters": {
        "height": 256,
        "content": "Form Trigger \u2013 Collects Teacher Name and uploads the Student\u2019s scanned Answer Sheet."
      },
      "typeVersion": 1
    },
    {
      "id": "6a43448e-837e-44da-b813-23697f57e9c5",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -512,
        -320
      ],
      "parameters": {
        "color": 2,
        "height": 256,
        "content": "Gemini image Analysis Node \u2013 Extracts the student\u2019s answers from the scanned image."
      },
      "typeVersion": 1
    },
    {
      "id": "bf8fa4b1-ae80-4073-8351-76480d754d05",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -240,
        -320
      ],
      "parameters": {
        "color": 3,
        "width": 496,
        "height": 464,
        "content": "AI Evaluation Agent Node \u2013 Uses attached Google Docs (Question Paper and Correct Answer Sheet) to compare answers and generate a structured JSON result with correct/incorrect count and marks obtained."
      },
      "typeVersion": 1
    },
    {
      "id": "cd8c33f8-c4be-4924-8c36-f3746f67ca63",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        304,
        -496
      ],
      "parameters": {
        "color": 4,
        "width": 272,
        "height": 304,
        "content": "Google Sheets (Summary Update) \u2013 Appends an entry with Student Name, Teacher Name, Total Questions, Correct Count, Incorrect Count, Total Marks, and Marks Obtained"
      },
      "typeVersion": 1
    },
    {
      "id": "5ba0dd51-dbd4-4144-ab72-0ce450ba924b",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        592,
        -240
      ],
      "parameters": {
        "color": 4,
        "width": 352,
        "height": 272,
        "content": "Google Sheets (Detailed Report Update) \u2013 Appends question-wise details with Question, Correct Answer, Student Answer, and Evaluation Status."
      },
      "typeVersion": 1
    },
    {
      "id": "6d16f5b7-f914-4330-a76a-5dcdd820ba30",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        304,
        -176
      ],
      "parameters": {
        "color": 6,
        "width": 272,
        "height": 352,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nThis code merger all the questions into one json to append into google sheet\n"
      },
      "typeVersion": 1
    },
    {
      "id": "882afe39-f035-4f2a-afea-9cd15848f5b6",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1392,
        -496
      ],
      "parameters": {
        "width": 512,
        "height": 736,
        "content": "## AI-Powered Student Answer Sheet Evaluation Agent\n\nThis flow helps teachers automatically evaluate student exam papers using AI.\n\n## Business Problem\n\nIn schools, manually checking and marking answer sheets is a time-consuming and repetitive task for teachers. This AI-powered agent simplifies the process by evaluating scanned student answer sheets intelligently and accurately.\n\n## Solution Overview\n\nTeachers only need to upload a scanned copy of the student\u2019s answer sheet through the form. The AI agent\u2014connected to the Question Paper and Correct Answer Sheet tools\u2014automatically compares each answer, calculates marks, and generates results in JSON format.\n\nThe evaluated data is then saved into Google Sheets, but it can also be integrated with any school database for seamless record management.\n\n## Future Enhancements\n\nThis flow can be further enhanced to handle multi-page answer sheets and generate customized evaluation reports based on the school\u2019s format or grading standards."
      },
      "typeVersion": 1
    },
    {
      "id": "ba0cf804-f83f-41f9-9775-d39e41df83e7",
      "name": "Append Summary",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        384,
        -336
      ],
      "parameters": {
        "columns": {
          "value": {
            "Total Marks": "={{ $json.output['Total Marks'] }}",
            "Student Name": "={{ $json.output['Student Name'] }}",
            "Examiner Name": "={{ $json.output['Examiner Name'] }}",
            "Correct Answer": "={{ $json.output['Total Correct Answers'] }}",
            "Incorrect Answers": "={{ $json.output['Total Incorrect Answers'] }}",
            "Total Marks Obtain": "={{ $json.output['Marks Obtained'] }}"
          },
          "schema": [
            {
              "id": "Student Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Student Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Examiner Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Examiner Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Correct Answer",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Correct Answer",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Incorrect Answers",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Incorrect Answers",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Total Marks",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Total Marks",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Total Marks Obtain",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Total Marks Obtain",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1BVy9jadiWBx-N8DSYGoBbc2XBb9Z2bC8Gi7fA5N4kKE/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1BVy9jadiWBx-N8DSYGoBbc2XBb9Z2bC8Gi7fA5N4kKE",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1BVy9jadiWBx-N8DSYGoBbc2XBb9Z2bC8Gi7fA5N4kKE/edit?usp=drivesdk",
          "cachedResultName": "Score Card"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "786aa89b-d2aa-4546-95ca-acfeb74baa4c",
      "name": "Append Scorecard",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        688,
        -128
      ],
      "parameters": {
        "columns": {
          "value": {
            "Status": "={{ $json.Status }}",
            "Student Name": "={{ $json['Student Name'] }}",
            "Actual Answer": "={{ $json['Correct Answer'] }}",
            "Student Answer": "={{ $json['Student Answer'] }}",
            "Question Number": "={{ $json.Question }}"
          },
          "schema": [
            {
              "id": "Student Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Student Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Question Number",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Question Number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Actual Answer",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Actual Answer",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Student Answer",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Student Answer",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 760946435,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1BVy9jadiWBx-N8DSYGoBbc2XBb9Z2bC8Gi7fA5N4kKE/edit#gid=760946435",
          "cachedResultName": "Scorecard"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1BVy9jadiWBx-N8DSYGoBbc2XBb9Z2bC8Gi7fA5N4kKE",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1BVy9jadiWBx-N8DSYGoBbc2XBb9Z2bC8Gi7fA5N4kKE/edit?usp=drivesdk",
          "cachedResultName": "Score Card"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "f6bc7583-39ee-4769-b099-9b4a915a3d1a",
      "name": "Code to merge multiple items into one JSON",
      "type": "n8n-nodes-base.code",
      "position": [
        384,
        -112
      ],
      "parameters": {
        "jsCode": "// Get AI output JSON safely (works even if wrapped in array)\nconst raw = $json[\"output\"] || ($json[0] && $json[0].output);\nif (!raw) {\n  throw new Error(\"No valid output data found in input\");\n}\n\nconst studentName = raw[\"Student Name\"];\nconst examinerName = raw[\"Examiner Name\"];\nconst totalCorrect = raw[\"Total Correct Answers\"];\nconst totalIncorrect = raw[\"Total Incorrect Answers\"];\nconst totalMarks = raw[\"Total Marks\"];\nconst marksObtained = raw[\"Marks Obtained\"];\n\nconst questions = raw[\"Data\"] || [];\n\nconst result = questions.map(q => ({\n  json: {\n    \"Student Name\": studentName,\n    \"Examiner Name\": examinerName,\n    \"Question\": q[\"Question\"],\n    \"Correct Answer\": q[\"Correct Answer\"],\n    \"Student Answer\": q[\"Student Answer\"],\n    \"Status\": q[\"Status\"],\n    \"Total Correct Answers\": totalCorrect,\n    \"Total Incorrect Answers\": totalIncorrect,\n    \"Total Marks\": totalMarks,\n    \"Marks Obtained\": marksObtained\n  }\n}));\n\nreturn result;\n"
      },
      "typeVersion": 2
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "c792c0f5-bb22-4b80-afe0-d7abc878346f",
  "connections": {
    "AI Agent": {
      "main": [
        [
          {
            "node": "Append Summary",
            "type": "main",
            "index": 0
          },
          {
            "node": "Code to merge multiple items into one JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze an image": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append Scorecard": {
      "main": [
        []
      ]
    },
    "Answer Sheet Uploader": {
      "main": [
        [
          {
            "node": "Analyze an image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Answer Paper 5th Class": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Question Paper 5Th Class": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser1": {
      "ai_outputParser": [
        [
          {
            "node": "AI Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Code to merge multiple items into one JSON": {
      "main": [
        [
          {
            "node": "Append Scorecard",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}