专栏名称: Python开发者
人生苦短,我用 Python。伯乐在线旗下账号「Python开发者」分享 Python 相关的技术文章、工具资源、精选课程、热点资讯等。
目录
相关文章推荐
Python爱好者社区  ·  炸了!《大模型基础》开源 ·  昨天  
Python爱好者社区  ·  “我,在阿里月薪6万,离职后突然惊醒:人越努 ... ·  2 天前  
Python开发者  ·  突发!GitLab不再为中国大陆、香港、澳门 ... ·  2 天前  
Python开发者  ·  Ilya向全世界宣布:预训练结束了!全球AI ... ·  昨天  
51好读  ›  专栏  ›  Python开发者

我用免费大模型DIY了个作业批改助手,手机端可用!

Python开发者  · 公众号  · Python  · 2024-12-23 11:50

正文


估计很多家庭都有小朋友上小学前“父慈母笑”,上学后“鸡飞狗跳”这一情况,而这大部分都和辅导小孩的作业有关。从我自身作为一名父亲来说,在辅导小孩作业时基本都是“头晕脑胀”,恨不得自己直接替娃把作业都写完。如果有家长在辅导小孩作业上“如鱼得水”,那么应该是“别人家的孩子”!



当然,我们可以借助作业辅导软件,比如就有自动批改作业的软件,能够自动帮忙找出作业中答案错误的部分。但这些软件目前都有两个弊端:


  • 收费,或者功能有限制:必须要充值会员才能使用完整功能,还必须是每年都需要充值会员,费用还不低。

  • 友好性不够:现在很多批改作业的软件都是基于OCR模型,底层逻辑是答案比对,无法同时给出详细的、个性化的答案详解,简单来说就是无法”拟人化“。


正好最近看到了智谱免费开放了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返回的结果,并将其转换为前端可以展示的格式方便阅读。


      结果展示

        • 将API返回的错误信息和正确答案整合,按照设计的布局展示在前端页面上。

        • 确保结果的展示与用户上传的图片和文本输入相对应。


        02 接口调用说明

        GLM-4V-Flash提供了API和SDK两种使用方式,可以按照实际需求进行选择!在使用前我们需要智谱AI开放平台中获取API KEY:

        #智谱AI开放平台地址https://bigmodel.cn/usercenter

        • 接口说明:

        传输方式

        https

        请求地址

        https://open.bigmodel.cn/api/paas/v4/chat/completions

        调用方式

        同步调用,等待模型执行完成并返回最终结果或 SSE 调用

        字符编码

        UTF-8

        接口请求格式

        JSON

        响应格式

        JSON 或标准 Stream Event

        接口请求类型

        POST

        开发语言

        任意可发起 http 请求的开发语言


        请求参数

        参数名称

        类型

        是否必填

        参数说明

        model

        String

        所要调用的模型编码。

        messages

        List

        调用语言模型时,将当前对话信息列表作为提示输入给模型, 按照


        {"role": "user", 
         "content": [
                  {
                    "type": "text",
                    "text": "解释一下图中的现象"
                  },
                  {
                    "type": "image_url",
                    "image_url": {
                        "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_ptemperature 参数,但不要同时调整两个参数

        top_p

        Float

        用温度取样的另一种方法,称为核取样取值范围是:(0.0, 1.0) 开区间,不能等于 0 或 1,默认值为 0.7模型考虑具有 top_p 概率质量 tokens 的结果例如:0.1 意味着模型解码器只考虑从前 10% 的概率的候选集中取 tokens建议您根据应用场景调整 top_ptemperature 参数,但不要同时调整两个参数

        max_tokens

        Integer

        模型最大输出 tokens ,默认1024


        示例DEMO

        本文主要以SDK方式使用为主。使用SDK调用方式,需要先安装智谱Python库

        #安装SDK库pip install zhipuai


        比如我们上传一个URL图片,调用下:

        from zhipuai import ZhipuAIclient = ZhipuAI(api_key="b975b35xxxxxxxxxxxxxxx6q3y") # 填写您自己的APIKeyresponse = client.chat.completions.create(    model="glm-4v-flash",  # 填写 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';
        // 发送请求到后端API fetch('http://xxx.xxx.xxx.xxx:5000/analyze', { // 注意:这里的URL应该根据实际后端服务地址修改 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, '
        '
        ); // 将换行符转换为HTML换行
        }) .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  # 导入Flask框架和相关功能from zhipuai import ZhipuAI  # 导入ZhipuAI SDKimport base64  # 导入base64库,用于编码from io import BytesIO  # 导入BytesIO,用于操作字节流from flask_cors import CORS  # 导入CORS,用于跨域资源共享
        app = Flask(__name__) # 创建Flask应用实例CORS(app) # 允许跨域请求
        # 填写您自己的APIKeyAPI_KEY = "b975xxxxxxxxxxxxxxxxxq3y" #替换为自己的API Keyclient = ZhipuAI(api_key=API_KEY) # 初始化ZhipuAI客户端
        @app.route('/analyze', methods=['POST']) # 定义路由和接受的方法def analyze(): if 'image' not in request.files: # 检查是否有图片文件上传 return jsonify({"error": "未找到图片"}), 400 # 如果没有,返回错误信息和400状态码
        image_file = request.files['image'] # 获取上传的图片文件 if image_file: # 将图片转换为base64编码 img_base64 = base64.b64encode(image_file.read()).decode('utf-8')
        text = request.form.get('text') # 从表单中获取文本描述
        if not text: # 检查是否有文本描述 return jsonify({"error": "缺少文本描述"}), 400 # 如果没有,返回错误信息和400状态码
        # 使用ZhipuAI客户端调用模型 response_vflash = client.chat.completions.create( model="glm-4v-flash", # 指定使用glm-4v-flash模型 messages=[ # 定义消息列表 { "role": "user", # 定义消息的角色 "content": [ # 定义消息内容 { "type": "image_url", # 消息类型为图片URL "image_url": { # 图片URL内容 "url": "data:image/jpeg;base64," + img_base64 # 编码后的图片数据 } }, { "type": "text", # 消息类型为文本 "text": "这是一份学生家庭作业,请提取图片中的内容包含,手写的答案" # 文本内容 } ] } ] )
        try: vflash_message_content = response_vflash.choices[0].message.content # 提取模型返回的message信息 except Exception as e: return jsonify({"error": str(e)}), 500 # 如果发生异常,返回错误信息和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: onWARNING: 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://127.0.0.1:5000 * Running on http://xxx.xxx.xxx.xxx:5000Press 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,使得在信息提取、内容创作、图片识别等多个领域中,开发者可以以较低的成本快速地实现和验证他们的想法。

        当然,本文的只是提供了一种简单的思路示例,还有很多待优化的地方比如,页面的兼容、后端并发处理的多线程等等!如果你也感兴趣的话,赶紧试试吧!


        点击阅读原文】体验更多可能
        ⬇️⬇️⬇️