估计很多家庭都有小朋友上小学前“父慈母笑”,上学后“鸡飞狗跳”这一情况,而这大部分都和辅导小孩的作业有关。从我自身作为一名父亲来说,在辅导小孩作业时基本都是“头晕脑胀”,恨不得自己直接替娃把作业都写完。如果有家长在辅导小孩作业上“如鱼得水”,那么应该是“别人家的孩子”!
当然,我们可以借助作业辅导软件,比如就有自动批改作业的软件,能够自动帮忙找出作业中答案错误的部分。但这些软件目前都有两个弊端:
正好最近看到了智谱免费开放了GLM-4-Flash语言大模型后,又又又免费开放了他们的 GLM-4V-Flash 多模态大模型 : 一款专注于高效的单一图像理解,适用于快速图像解析的场景,例如实时图像分析或批量图像处理的模型。
GLM-4V-Flash模型是智谱推出一款免费的多模态模型,在图像处理方面实现了精确度的显著提升。该模型具备图像描述生成、图像分类、视觉推理、视觉问答(VQA)以及图像情感分析等高级图像处理功能,并且支持包括中文、英语、日语、韩语、德语在内的26种语言。这使得GLM-4V-Flash能够针对特定垂直行业提供精准的场景解决方案,以低成本助力开发者迅速融入大模型时代,无需顾虑大模型图像处理的高昂成本!
多模态都直接免费开放使用,这个手笔也没谁了!
然后,我就突发奇想,不行就基于GLM-4V-Flash自己DIY个作业批改神器吧,拍照就能分析的那种,基于错误的题目,还能带AI答案解析!
01 实现思路 要实现一个基于GLM模型的作业错误检测功能,我们需要开发一个前端页面来允许用户上传作业图片,通过后端服务调用GLM-4V-Flash模型进行图片内容提取,最后调用GLM-4-Flash模型进行作业检查,并且给出检查结果。
具体包含以下几个步骤:
前端页面设计 :
后端服务开发:
接收前端发送的图片和文本数据。
对图片进行Base64处理,调用GLM-4V-Flash模型提取图片中的答题信息。
将提取到的答题信息,调用GLM-4-Flash模型进行计算和检查,并给出错误点和合理的学习建议。
处理API返回的结果,并将其转换为前端可以展示的格式方便阅读。
结果展示 :
02 接口 调用说明 GLM-4V-Flash提供了API和SDK两种使用方式,可以按照实际需求进行选择!在使用前我们需要智谱AI开放平台中获取API KEY:
传输方式
https
请求地址
https://open.bigmodel.cn/api/paas/v4/chat/completions
调用方式
同步调用,等待模型执行完成并返回最终结果或 SSE 调用
字符编码
UTF-8
接口请求格式
JSON
响应格式
JSON 或标准 Stream Event
接口请求类型
POST
开发语言
任意可发起 http 请求的开发语言
请求参数 参数名称
类型
是否必填
参数说明
model
String
是
所要调用的模型编码。
messages
List
是
调用语言模型时,将当前对话信息列表作为提示输入给模型, 按照
"url" : "https://xxx/xx.jpg"
的json 数组形式进行传参;可能的消息类型包括 System message、User message、Assistant message 。见下方 message 消息字段说明 图片说明:上传格式仅支持图片url ,图片大小支持5M以下图片。支持的图片类型 jpg、png、jpeg
request_id
String
否
由用户端传参,需保证唯一性;用于区分每次请求的唯一标识,用户端不传时平台会默认生成。
do_sample
Boolean
否
do_sample 为 true 时启用采样策略,do_sample 为 false 时采样策略 temperature、top_p 将不生效
stream
Boolean
否
使用同步调用时,此参数应当设置为 Fasle 或者省略。表示模型生成完所有内容后一次性返回所有内容。
如果设置为 True,模型将通过标准 Event Stream ,逐块返回模型生成内容。Event Stream 结束时会返回一条data: [DONE]
消息。
temperature
Float
否
采样温度,控制输出的随机性,必须为正数取值范围是:(0.0,1.0]
,不能等于 0,默认值为 0.95值越大,会使输出更随机,更具创造性;值越小,输出会更加稳定或确定建议您根据应用场景调整 top_p
或 temperature
参数,但不要同时调整两个参数
top_p
Float
否
用温度取样的另一种方法,称为核取样取值范围是:(0.0, 1.0)
开区间,不能等于 0 或 1,默认值为 0.7模型考虑具有 top_p
概率质量 tokens 的结果例如:0.1 意味着模型解码器只考虑从前 10% 的概率的候选集中取 tokens建议您根据应用场景调整 top_p
或 temperature
参数,但不要同时调整两个参数
max_tokens
Integer
否
模型最大输出 tokens ,默认1024
示例DEMO 本文主要以SDK方式使用为主。使用SDK调用方式,需要先安装智谱Python库
比如我们上传一个URL图片,调用下:
from zhipuai import ZhipuAI
client = ZhipuAI(api_key="b975b35xxxxxxxxxxxxxxx6q3y" )
response = client.chat.completions.create(
model="glm-4v-flash" ,
messages=[
{
"role" : "user" ,
"content" : [
{
"type" : "text" ,
"text" : "请详细描述下这个图片的内容"
},
{
"type" : "image_url" ,
"image_url" : {
"url" : "https://img0.baidu.com/it/u=774674552,567460925&fm=253&fmt=auto&app=138&f=JPEG?w=414&h=500"
}
}
]
}
]
)
print(response.choices[0].message)
调试结果返回如下:
这个是原图:
只能说,厉害!
03 应用实现 —
按照上述的实现思路实现批改作业神器的应用核心点分为两部分,后端部分调用 GLM-4V-Flash实现拍照作业的数内容提取,前端采用简洁的拍照和作业描述菜单功能(本应用作为DEMO应用,非投产应用,主要用于思路参考)。具体涉及到的一些技术和详细代码如下:
前端技术和代码 HTML :用于构建网页的基本结构,包括表单、输入字段、按钮等。
CSS :用于设计和布局,使网页在不同设备上都能有良好的视觉表现,实现响应式设计。
JavaScript :用于实现网页的动态交互功能,如表单提交、数据显示、模态框控制等。
FormData :用于构建表单数据,方便地发送文件和其他数据。
正则表达式 :用于处理和格式化从后端接收到的文本数据。
移动端适配 :确保应用在手机等移动设备上也能正常工作,可能涉及到视口设置、触摸事件处理等。
代码参考如下:
<html lang ="zh-CN" >
<head >
<meta charset ="UTF-8" >
<meta name ="viewport" content ="width=device-width, initial-scale=1.0" >
<title > 作业批改title >
<style >
body {
font-family : Arial, sans-serif;
margin : 0 ;
padding : 0 ;
display : flex;
flex-direction : column;
align-items : center;
justify-content : center;
height : 100vh ;
background-color : #f7f7f7 ;
}
form {
width : 90% ;
max-width : 400px ;
margin : 20px 0 ;
padding : 20px ;
border : 1px solid #ccc ;
border-radius : 5px ;
background-color : #fff ;
}
input [type="file"] , textarea {
width : 100% ;
padding : 10px ;
margin-bottom : 10px ;
border : 1px solid #ccc ;
border-radius : 5px ;
}
button {
width : 100% ;
padding : 10px ;
background-color : #007bff ;
color : white;
border : none;
border-radius : 5px ;
cursor : pointer;
}
button :hover {
background-color : #0056b3 ;
}
.result {
width : 90% ;
max-width : 400px ;
padding : 10px ;
border : 1px solid #ccc ;
border-radius : 5px ;
background-color : #fff ;
white-space : pre-wrap;
word-wrap : break-word;
}
.modal {
display : none;
position : fixed;
z-index : 1 ;
left : 0 ;
top : 0 ;
width : 100% ;
height : 100% ;
overflow : auto;
background-color : rgba (0,0,0,0.4);
}
.modal-content {
background-color : #fefefe ;
margin : 15% auto;
padding : 20px ;
border : 1px solid #888 ;
width : 80% ;
max-width : 300px ;
text-align : center;
}
.close {
color : #aaa ;
float : right;
font-size : 28px ;
font-weight : bold;
}
.close :hover ,
.close :focus {
color : black;
text-decoration : none;
cursor : pointer;
}
style >
head >
<body >
<h1 > 作业批改神器h1 >
<div id ="myModal" class ="modal" >
<div class ="modal-content" >
<span class ="close" > ×span >
<p > 正在检查...p >
div >
div >
<form id ="uploadForm" enctype ="multipart/form-data" >
<input type ="file" id ="image" accept ="image/*" capture ="camera" required >
<textarea id ="text" placeholder ="输入你需要了解的内容,比上传的图片中答案错误的有哪些" required > textarea >
<button type ="submit" > 确认检查button >
form >
<pre id ="result" class ="result" > pre >
<script >
var modal = document .getElementById("myModal" );
var span = document .getElementsByClassName("close" )[0 ];
var form = document .getElementById("uploadForm" );
span.onclick = function ( ) {
modal.style.display = "none" ;
}
window .onclick = function (event ) {
if (event.target == modal) {
modal.style.display = "none" ;
}
}
form.onsubmit = function (event ) {
event.preventDefault();
var image = document .getElementById('image' ).files[0 ];
var text = document .getElementById('text' ).value;
if (!image) {
alert('请选择一张图片' );
return ;
}
var formData = new FormData();
formData.append('image' , image);
formData.append('text' , text);
modal.style.display = 'block' ;
fetch('http://xxx.xxx.xxx.xxx:5000/analyze' , {
method: 'POST' ,
body : formData
})
.then(response => {
if (!response.ok) {
throw new Error ('网络响应不正常' );
}
return response.json();
})
.then(data => {
modal.style.display = 'none' ;
document .getElementById('result' ).innerHTML = data.message.replace(/\n/g , ' ' );
})
.catch(error => {
modal.style.display = 'none' ;
document .getElementById('result' ).textContent = '错误: ' + error.message;
})
.finally(() => {
document .getElementById('image' ).value = '' ;
});
}
script >
body >
html >
后端技术和代码
Python: 作为后端开发的主要编程语言。
Flask: 一个轻量级的Web应用框架,用于快速开发后端服务。
ZhipuAI SDK: 用于调用ZhipuAI的API,处理图片和文本数据。
Base64编码: 可能用于在将图片数据发送到后端之前,将其转换为字符串格式。
JSON: 用于在前后端之间传输数据的格式。
CORS: 跨源资源共享,确保前端能够从不同的源访问后端服务。
错误处理: 在后端进行错误捕获和处理。
代码参考如下:
from flask import Flask, request, jsonify
from zhipuai import ZhipuAI
import base64
from io import BytesIO
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
API_KEY = "b975xxxxxxxxxxxxxxxxxq3y"
client = ZhipuAI(api_key=API_KEY)
@app.route('/analyze', methods=['POST']) # 定义路由和接受的方法
def analyze () :
if 'image' not in request.files:
return jsonify({"error" : "未找到图片" }), 400
image_file = request.files['image' ]
if image_file:
img_base64 = base64.b64encode(image_file.read()).decode('utf-8' )
text = request.form.get('text' )
if not text:
return jsonify({"error" : "缺少文本描述" }), 400
response_vflash = client.chat.completions.create(
model="glm-4v-flash" ,
messages=[
{
"role" : "user" ,
"content" : [
{
"type" : "image_url" ,
"image_url" : {
"url" : "data:image/jpeg;base64," + img_base64
}
},
{
"type" : "text" ,
"text" : "这是一份学生家庭作业,请提取图片中的内容包含,手写的答案"
}
]
}
]
)
try :
vflash_message_content = response_vflash.choices[0 ].message.content
except Exception as e:
return jsonify({"error" : str(e)}), 500
response_flash = client.chat.completions.create(
model="glm-4-plus" ,
messages=[
{"role" : "system" , "content" : "你是一个老师,精通语文、数学、英文。能够发现学生作业中的错误点,并且能够提供学习建议" },
{"role" : "user" , "content" : vflash_message_content + text}
],
)
try :
flash_message_content = response_flash.choices[0 ].message.content
except Exception as e:
return jsonify({"error" : str(e)}), 500
return jsonify({"message" :flash_message_content})
if __name__ == '__main__' :
app.run(host='0.0.0.0' , debug=True )
运行后端服务
#运行后端服务
python3 app.py
#显示已下信息则启动成功
* Serving Flask app 'app'
* Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0 .0 .0 )
* Running on http:
* Running on http:
Press CTRL+C to quit
* Restarting with stat
* Debugger is active!
* Debugger PIN: 736-862-000
运行前端服务
python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
xxx.xxx.xxx.xxx - - [10 /Dec/2024 15 :59 :20 ] "GET / HTTP/1.1" 200 -
如果是公网服务器,手机端或者用浏览器调整为手机模式,访问 http://HOSTIP:8000/,可以看到以下页面:
04 效果展示 —
数学作业识别效果:
语文作业识别效果:
英语作业识别效果:
05 最后 —
由此可见,GLM-4V-Flash虽然免费开放使用,但是无论在性能、功能、使用上都没有进行任何的限制,真免费! 并且提供了简单易用的API接口和SDK,使得在信息提取、内容创作、图片识别等多个领域中,开发者可以以较低的成本快速地实现和验证他们的想法。
当然,本文的只是提供了一种简单的思路示例,还有很多待优化的地方比如,页面的兼容、后端并发处理的多线程等等!如果你也感兴趣的话,赶紧试试吧!
点击 【 阅读原文】 体验更多可能 ⬇️⬇️⬇️