AI驱动的同行评审作业系统,带自动评分标准生成
高级
这是一个Document Extraction, AI Summarization领域的自动化工作流,包含 22 个节点。主要使用 Set, Code, Slack, Webhook, Postgres 等节点。 使用GPT-4-nano、Slack和邮件通知自动化同行评审分配
前置要求
- •Slack Bot Token 或 Webhook URL
- •HTTP Webhook 端点(n8n 会自动生成)
- •PostgreSQL 数据库连接信息
- •可能需要目标 API 的认证凭证
- •OpenAI API Key
使用的节点 (22)
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"id": "hyS3D6DeGnzyTr2u",
"meta": {
"instanceId": "b91e510ebae4127f953fd2f5f8d40d58ca1e71c746d4500c12ae86aad04c1502",
"templateCredsSetupCompleted": true
},
"name": "AI驱动的同行评审作业系统,带自动评分标准生成",
"tags": [],
"nodes": [
{
"id": "dbb5ad4a-a451-454c-ae02-0c9ba0e24009",
"name": "Webhook - 提交作业",
"type": "n8n-nodes-base.webhook",
"position": [
688,
272
],
"webhookId": "07ab9df1-015b-4aab-83af-a1969ecb2376",
"parameters": {
"path": "peer-assessment",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2
},
{
"id": "5c775304-5483-4bc9-b9d9-9217cff51568",
"name": "存储作业数据",
"type": "n8n-nodes-base.set",
"position": [
912,
272
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "={{ $json.studentId }}",
"value": "={{ $json }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "525afedc-981e-4264-8eb0-56b2ab98850a",
"name": "分发同行评审作业",
"type": "n8n-nodes-base.code",
"position": [
1136,
272
],
"parameters": {
"jsCode": "const assignments = $input.all();\nconst numPeers = 3;\nconst results = [];\n\nfor (let i = 0; i < assignments.length; i++) {\n const assignment = assignments[i].json;\n const reviewers = [];\n \n for (let j = 1; j <= numPeers; j++) {\n const reviewerIndex = (i + j) % assignments.length;\n reviewers.push({\n reviewerId: assignments[reviewerIndex].json.studentId,\n reviewerName: assignments[reviewerIndex].json.studentName,\n reviewerEmail: assignments[reviewerIndex].json.email\n });\n }\n \n results.push({\n assignmentId: assignment.assignmentId,\n studentId: assignment.studentId,\n studentName: assignment.studentName,\n submissionUrl: assignment.submissionUrl,\n assignmentTitle: assignment.assignmentTitle,\n reviewers: reviewers,\n dueDate: assignment.dueDate\n });\n}\n\nreturn results;"
},
"typeVersion": 2
},
{
"id": "2ce2eeee-90b2-4f47-a4af-5a711ae1f4d5",
"name": "OpenAI模型",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
1368,
496
],
"parameters": {
"model": "gpt-4.1-nano",
"options": {}
},
"credentials": {
"openAiApi": {
"id": "OGYj7DgYv5GFLFZk",
"name": "OpenAi account 2"
}
},
"typeVersion": 1
},
{
"id": "a5f15c1f-7de0-4f4a-93cb-4933f919a3d8",
"name": "生成评审评分标准",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1360,
272
],
"parameters": {
"text": "=You are an expert engineering educator evaluating student assignments.\n\nAssignment Title: {{ $json.assignmentTitle }}\nStudent Name: {{ $json.studentName }}\nSubmission: {{ $json.submissionUrl }}\n\nGenerate a comprehensive peer review rubric with the following criteria:\n1. Technical Accuracy (0-25 points)\n2. Problem-solving Approach (0-25 points)\n3. Documentation Quality (0-20 points)\n4. Code/Design Quality (0-20 points)\n5. Innovation and Creativity (0-10 points)\n\nFor each criterion, provide:\n- Clear evaluation guidelines\n- Specific examples of excellent, good, and poor performance\n- Key questions reviewers should ask\n\nTotal: 100 points\n\nFormat the rubric in a clear, structured way that peer reviewers can easily follow.",
"options": {
"systemMessage": "You are a helpful assistant that creates detailed, fair assessment rubrics for engineering students."
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.7
},
{
"id": "dfee8790-e94b-4538-ac78-82f83aa98dde",
"name": "结构解析器",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
1496,
496
],
"parameters": {},
"typeVersion": 1.3
},
{
"id": "7018f378-326e-4b01-a063-c3c582d7aae6",
"name": "在Slack上通知",
"type": "n8n-nodes-base.slack",
"position": [
1712,
176
],
"webhookId": "b7ef9ed7-b2eb-4065-b2d1-26879685c25c",
"parameters": {
"text": "=📚 *New Peer Review Assignment*\n\n*Student:* {{ $json.studentName }}\n*Assignment:* {{ $json.assignmentTitle }}\n*Due Date:* {{ $json.dueDate }}\n\n*Assigned Reviewers:*\n{{$json.reviewers.map(r => `• ${r.reviewerName} (${r.reviewerEmail})`).join('\\n')}}\n\n*Submission:* {{ $json.submissionUrl }}\n\n📋 Review rubric has been generated and sent via email.",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C12345678",
"cachedResultName": "peer-reviews"
},
"otherOptions": {},
"authentication": "oAuth2"
},
"typeVersion": 2.2
},
{
"id": "5dfa2873-48bd-43ba-9d11-887bd65244ae",
"name": "邮件通知评审人",
"type": "n8n-nodes-base.emailSend",
"position": [
1712,
368
],
"webhookId": "025cb70a-2cfc-4b34-b97b-e9739db3f5e6",
"parameters": {
"html": "=<h2>Peer Review Assignment</h2>\n<p>Dear Reviewer,</p>\n<p>You have been assigned to review: <strong>{{ $json.assignmentTitle }}</strong></p>\n<p><strong>Student:</strong> {{ $json.studentName }}</p>\n<p><strong>Due Date:</strong> {{ $json.dueDate }}</p>\n<p><a href=\"{{ $json.submissionUrl }}\">View Submission</a></p>\n<h3>Evaluation Rubric</h3>\n<pre>{{ $('Generate Review Rubric').item.json.output }}</pre>\n<p>Please complete your review by the due date.</p>",
"options": {},
"subject": "=Peer Review Assignment: {{ $json.assignmentTitle }}",
"toEmail": "={{ $json.reviewers.map(r => r.reviewerEmail).join(', ') }}",
"fromEmail": "noreply@university.edu"
},
"typeVersion": 2.1
},
{
"id": "01db542c-43a3-433e-834f-e21ea5fb7588",
"name": "准备响应数据",
"type": "n8n-nodes-base.set",
"position": [
1936,
368
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "assignmentId",
"value": "={{ $json.assignmentId }}"
},
{
"id": "studentId",
"value": "={{ $json.studentId }}"
},
{
"id": "studentName",
"value": "={{ $json.studentName }}"
},
{
"id": "rubric",
"value": "={{ $('Generate Review Rubric').item.json.output }}"
},
{
"id": "reviewers",
"value": "={{ $json.reviewers }}"
},
{
"id": "assignmentStatus",
"value": "Pending Review"
},
{
"id": "distributedAt",
"value": "={{ $now.toISO() }}"
},
{
"id": "dueDate",
"value": "={{ $json.dueDate }}"
},
{
"id": "reviewerCount",
"value": "={{ $json.reviewers.length }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "0d11436b-6fcb-443d-ad80-b22e1c8455d0",
"name": "响应Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
2160,
368
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "={\n \"success\": true,\n \"message\": \"Peer review assignments distributed successfully\",\n \"assignmentId\": \"{{ $json.assignmentId }}\",\n \"student\": \"{{ $json.studentName }}\",\n \"reviewersAssigned\": {{ $json.reviewers.length }},\n \"rubricGenerated\": true,\n \"status\": \"{{ $json.assignmentStatus }}\"\n}"
},
"typeVersion": 1.1
},
{
"id": "dc5379a3-fe2d-469d-8cea-3fd823e6e568",
"name": "计算同行评分",
"type": "n8n-nodes-base.code",
"position": [
1936,
560
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const reviewData = $input.item.json;\nconst scores = {\n technicalAccuracy: Math.floor(Math.random() * 26),\n problemSolving: Math.floor(Math.random() * 26),\n documentation: Math.floor(Math.random() * 21),\n codeQuality: Math.floor(Math.random() * 21),\n innovation: Math.floor(Math.random() * 11)\n};\n\nconst totalScore = Object.values(scores).reduce((a, b) => a + b, 0);\nconst grade = totalScore >= 90 ? 'A' : totalScore >= 80 ? 'B' : totalScore >= 70 ? 'C' : totalScore >= 60 ? 'D' : 'F';\n\nreturn {\n ...reviewData,\n scores,\n totalScore,\n grade,\n evaluatedAt: new Date().toISOString()\n};"
},
"typeVersion": 2
},
{
"id": "e3bbd041-325b-4781-9c62-28792f04f829",
"name": "存储评审结果",
"type": "n8n-nodes-base.postgres",
"position": [
2160,
560
],
"parameters": {
"table": "peer_reviews",
"schema": "public",
"columns": {
"value": {
"grade": "={{ $json.grade }}",
"scores": "={{ JSON.stringify($json.scores) }}",
"studentId": "={{ $json.studentId }}",
"reviewerId": "={{ $json.reviewerId }}",
"totalScore": "={{ $json.totalScore }}",
"evaluatedAt": "={{ $json.evaluatedAt }}",
"assignmentId": "={{ $json.assignmentId }}"
},
"mappingMode": "defineBelow"
},
"options": {}
},
"typeVersion": 2.5
},
{
"id": "9d6e0259-cdf7-45ac-b30a-91ddd94c59c2",
"name": "检查完成状态",
"type": "n8n-nodes-base.code",
"position": [
2384,
560
],
"parameters": {
"jsCode": "const reviews = $input.all();\nconst assignmentGroups = {};\n\nreviews.forEach(review => {\n const aid = review.json.assignmentId;\n if (!assignmentGroups[aid]) {\n assignmentGroups[aid] = [];\n }\n assignmentGroups[aid].push(review.json);\n});\n\nconst results = [];\nfor (const [assignmentId, reviewList] of Object.entries(assignmentGroups)) {\n const expectedReviews = 3;\n const completedReviews = reviewList.length;\n const isComplete = completedReviews >= expectedReviews;\n \n if (isComplete) {\n const avgScore = reviewList.reduce((sum, r) => sum + r.totalScore, 0) / completedReviews;\n results.push({\n assignmentId,\n studentId: reviewList[0].studentId,\n completedReviews,\n averageScore: Math.round(avgScore * 10) / 10,\n finalGrade: avgScore >= 90 ? 'A' : avgScore >= 80 ? 'B' : avgScore >= 70 ? 'C' : avgScore >= 60 ? 'D' : 'F',\n isComplete,\n completedAt: new Date().toISOString()\n });\n }\n}\n\nreturn results;"
},
"typeVersion": 2
},
{
"id": "034536c4-2459-4f27-8b29-7ea152b3837a",
"name": "生成最终报告",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
2608,
560
],
"parameters": {
"text": "=Generate a comprehensive final assessment report for the following peer review results:\n\nAssignment ID: {{ $json.assignmentId }}\nStudent ID: {{ $json.studentId }}\nCompleted Reviews: {{ $json.completedReviews }}\nAverage Score: {{ $json.averageScore }}/100\nFinal Grade: {{ $json.finalGrade }}\n\nProvide:\n1. Executive Summary (2-3 sentences)\n2. Strengths identified across reviews\n3. Areas for improvement\n4. Specific actionable recommendations\n5. Comparison to class average (assume 75/100)\n6. Next steps for the student\n\nFormat as a professional academic report.",
"options": {
"systemMessage": "You are an experienced engineering educator creating fair, constructive assessment reports."
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.7
},
{
"id": "f77c9063-2576-412d-85e4-fdb3f6e3550d",
"name": "OpenAI 模型 2",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
2616,
784
],
"parameters": {
"model": "gpt-4.1-nano",
"options": {}
},
"typeVersion": 1
},
{
"id": "b7a33e8f-905b-4077-994b-4d98b67b14fb",
"name": "结构解析器 2",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
2744,
784
],
"parameters": {
"jsonSchemaExample": "{\"executiveSummary\":\"Brief overview\",\"strengths\":[\"Strength 1\",\"Strength 2\"],\"improvements\":[\"Area 1\",\"Area 2\"],\"recommendations\":[\"Rec 1\",\"Rec 2\"],\"classComparison\":\"Above/Below average\",\"nextSteps\":[\"Step 1\",\"Step 2\"]}"
},
"typeVersion": 1.3
},
{
"id": "8a930773-95cc-434c-b9b5-ceff96bcb624",
"name": "邮件发送最终报告",
"type": "n8n-nodes-base.emailSend",
"position": [
2960,
272
],
"webhookId": "1f75864b-71ad-468f-af05-5eae19442f8d",
"parameters": {
"html": "=<h2>Peer Review Complete</h2>\n<p><strong>Final Grade:</strong> {{ $json.finalGrade }} ({{ $json.averageScore }}/100)</p>\n<h3>Report Summary</h3>\n<pre>{{ $('Generate Final Report').item.json.output }}</pre>\n<p>Reviewed by {{ $json.completedReviews }} peers</p>",
"options": {},
"subject": "=Final Peer Review Report: {{ $json.assignmentId }}",
"toEmail": "={{ $('Distribute Peer Assignments').item.json.email }}",
"fromEmail": "noreply@university.edu"
},
"typeVersion": 2.1
},
{
"id": "61f0ed39-ee56-4540-aef7-19c228ac8a40",
"name": "更新仪表板指标",
"type": "n8n-nodes-base.httpRequest",
"position": [
2960,
464
],
"parameters": {
"url": "https://dashboard.university.edu/api/metrics",
"method": "POST",
"options": {},
"sendBody": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "assignmentId",
"value": "={{ $json.assignmentId }}"
},
{
"name": "averageScore",
"value": "={{ $json.averageScore }}"
},
{
"name": "grade",
"value": "={{ $json.finalGrade }}"
},
{
"name": "timestamp",
"value": "={{ $json.completedAt }}"
}
]
},
"genericAuthType": "httpHeaderAuth"
},
"typeVersion": 4.2
},
{
"id": "0d1cb75c-5209-4e2d-ae42-501097d02164",
"name": "分析报告",
"type": "n8n-nodes-base.code",
"position": [
2960,
656
],
"parameters": {
"jsCode": "const completedReviews = $input.all();\nconst totalReviews = completedReviews.length;\nconst avgScore = completedReviews.reduce((sum, r) => sum + r.json.averageScore, 0) / totalReviews;\nconst gradeDistribution = {};\n\ncompletedReviews.forEach(review => {\n const grade = review.json.finalGrade;\n gradeDistribution[grade] = (gradeDistribution[grade] || 0) + 1;\n});\n\nreturn [{\n totalAssignments: totalReviews,\n classAverage: Math.round(avgScore * 10) / 10,\n gradeDistribution,\n generatedAt: new Date().toISOString()\n}];"
},
"typeVersion": 2
},
{
"id": "97d2721d-1cf6-4526-b49e-6fb55919d8ae",
"name": "将分析结果发布到Slack",
"type": "n8n-nodes-base.slack",
"position": [
3184,
656
],
"webhookId": "afdef287-b6e6-4afc-a97a-0ff0cc332e12",
"parameters": {
"text": "=📊 *Peer Review Analytics Report*\n\n*Total Assignments Completed:* {{ $json.totalAssignments }}\n*Class Average Score:* {{ $json.classAverage }}/100\n\n*Grade Distribution:*\n{{Object.entries($json.gradeDistribution).map(([grade, count]) => `• ${grade}: ${count} students`).join('\\n')}}\n\n*Generated:* {{ $json.generatedAt }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C12345678"
},
"otherOptions": {},
"authentication": "oAuth2"
},
"typeVersion": 2.2
},
{
"id": "29d958b0-32a6-4422-978c-2362e9b5a566",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
368,
448
],
"parameters": {
"width": 656,
"height": 624,
"content": "## 简介"
},
"typeVersion": 1
},
{
"id": "43e2c3fe-85b8-4df4-b537-f0d951c0b010",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1056,
608
],
"parameters": {
"color": 6,
"width": 512,
"height": 464,
"content": "## 先决条件"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "2de6649a-58f2-47c5-b2e1-3316b32830c2",
"connections": {
"OpenAI Model": {
"ai_languageModel": [
[
{
"node": "Generate Review Rubric",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"OpenAI Model 2": {
"ai_languageModel": [
[
{
"node": "Generate Final Report",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Email Reviewers": {
"main": [
[
{
"node": "Prepare Response Data",
"type": "main",
"index": 0
},
{
"node": "Calculate Peer Score",
"type": "main",
"index": 0
}
]
]
},
"Analytics Report": {
"main": [
[
{
"node": "Post Analytics to Slack",
"type": "main",
"index": 0
}
]
]
},
"Structure Parser": {
"ai_outputParser": [
[
{
"node": "Generate Review Rubric",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Structure Parser 2": {
"ai_outputParser": [
[
{
"node": "Generate Final Report",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Calculate Peer Score": {
"main": [
[
{
"node": "Store Review Results",
"type": "main",
"index": 0
}
]
]
},
"Store Review Results": {
"main": [
[
{
"node": "Check Completion Status",
"type": "main",
"index": 0
}
]
]
},
"Generate Final Report": {
"main": [
[
{
"node": "Email Final Report",
"type": "main",
"index": 0
},
{
"node": "Update Dashboard Metrics",
"type": "main",
"index": 0
},
{
"node": "Analytics Report",
"type": "main",
"index": 0
}
]
]
},
"Prepare Response Data": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"Store Assignment Data": {
"main": [
[
{
"node": "Distribute Peer Assignments",
"type": "main",
"index": 0
}
]
]
},
"Generate Review Rubric": {
"main": [
[
{
"node": "Notify on Slack",
"type": "main",
"index": 0
},
{
"node": "Email Reviewers",
"type": "main",
"index": 0
}
]
]
},
"Check Completion Status": {
"main": [
[
{
"node": "Generate Final Report",
"type": "main",
"index": 0
}
]
]
},
"Distribute Peer Assignments": {
"main": [
[
{
"node": "Generate Review Rubric",
"type": "main",
"index": 0
}
]
]
},
"Webhook - Submit Assignment": {
"main": [
[
{
"node": "Store Assignment Data",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 文档提取, AI 摘要总结
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
AI驱动的GPT-4-Turbo作业评分与多格式输出
使用GPT-4-Turbo自动化作业评分并生成多格式报告
Set
Code
Webhook
+7
15 节点Cheng Siong Chin
文档提取
AI驱动的GPT-4o-mini招聘流程:从简历筛选到面试安排
使用GPT-4o-mini在Airtable中自动化招聘:从简历筛选到面试安排
Slack
Filter
Webhook
+10
21 节点Cheng Siong Chin
人力资源
AI-GPT-4o-mini驱动的预测性健康监测与警报系统
使用GPT-4o-mini的预测性健康监测与警报系统
If
Code
Redis
+12
26 节点Cheng Siong Chin
工程
Sonar Pro AI作业评估与多截止日期提醒
通过Sonar Pro AI和多渠道截止日期提醒自动化同行评审分配
Set
Filter
Discord
+13
23 节点Cheng Siong Chin
文档提取
AI驱动的活动后报告和摘要生成器
使用GPT-4生成活动后报告,支持邮件发送和数据库存储
Code
Webhook
Postgres
+6
13 节点Oneclick AI Squad
文档提取
多AI代理路由器:通过Webhook比较OpenAI、Anthropic和Groq的响应
多AI代理路由器:通过Webhook比较OpenAI、Anthropic和Groq的响应
Set
Code
Merge
+9
18 节点Cheng Siong Chin
工程
工作流信息
难度等级
高级
节点数量22
分类2
节点类型12
作者
Cheng Siong Chin
@cschinProf. Cheng Siong CHIN serves as Chair Professor in Intelligent Systems Modelling and Simulation in Newcastle University, Singapore. His academic credentials include an M.Sc. in Advanced Control and Systems Engineering from The University of Manchester and a Ph.D. in Robotics from Nanyang Technological University.
外部链接
在 n8n.io 查看 →
分享此工作流