尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

AI or Not Quiz:一个用于人机文本判别训练的轻量级Web应用

AI or Not Quiz:一个用于人机文本判别训练的轻量级Web应用 这次我们来看一个很有意思的开源小项目Wikipedia: AI or Not Quiz。它的玩法一句话就能说清楚——给你看一段文字你判断这段文字究竟是 AI 写的还是真人写的。听起来简单但真上手会发现这其实是一个非常实用的 AI 文本鉴别试验场。它把“人能否识别 AI 生成内容”这件事变成了一个可重复、可评分、可拆解的量化测试。这个项目适合三类读者第一类是刚接触 AI 应用开发的工程师想找一个结构简单、前端交互 后端接口都能练到的小项目第二类是做内容审核、编辑、运营的同学想系统性地测一测自己对 AI 文本的判断力顺便理解 AI 写作的常见特征第三类是研究 AI 检测方向的人可以通过这种问答游戏形式收集人机判别数据了解人类识别 AI 文本的真实准确率。本文会带你完整拆解这个 Quiz 的核心功能、数据组织方式、前后端交互逻辑并给出一套可复现的本地部署和接口测试流程。文章里涉及的技术点包括文本样本管理、Quiz 题组设计、前端答题交互、后端判定接口、评分与结果统计、以及 AI 文本检测的常见误区和合规边界。先放一个核心结论这一类“AI or Not”测验最有价值的不是准确率有多高而是它能让你批量建立对 AI 写作特征的敏感度。下面进入正题。1. 核心能力速览能力项说明项目类型人机文本判别问答应用Quiz核心功能展示文本样本让用户判断是否由 AI 生成并给出评分与解释输入素材需要准备人工文本和 AI 生成文本两组样本主要交互前端题目展示、选项点击、结果反馈、排行榜/统计后端能力题组分发出题、答案校验、用户得分统计、样本池管理启动方式Web 应用可本地命令启动是否支持 API可以拆成独立判定/出题接口方便二次开发是否支持批量任务样本导入和批量评测可以做成脚本实时答题是单次交互推荐环境普通开发机即可基本无 GPU 依赖数据依赖需要自备或自行生成足够数量的文本样本从这张表能看出来这个项目本质上是一个“文本鉴别任务”的 Web 化封装。它不依赖大模型推理不要求显卡也不需要本地跑权重。核心工作量在数据组织、交互设计和判定逻辑上。2. 适用场景与使用边界先搞清楚它能干什么。适用场景一人机判别能力训练。把 AI 生成的段落和真人写作的段落混在一起让用户不断判断、纠错、回看逐渐形成对 AI 文本的直觉。内容编辑、新媒体运营、审核人员可以用它做内部训练。适用场景二AI 文本特征研究。通过 Quiz 记录用户的判断结果可以统计出哪种类型的 AI 文本最容易骗过人哪些特征容易被误判不同模型生成的文本人类识别率差异有多大这些数据对内容安全工作很有参考价值。适用场景三教学演示。在 AI 通识课或技术分享中现场跑一轮 Quiz比讲十页 PPT 更能说明“AI 文本很难一眼识别”。不适合什么场景不适合作为正式的 AI 内容检测工具。人眼判断永远是概率性的不是检测标准。不适合用来给文本“定罪”。一段文字被判断为 AI 生成不意味着它真的由 AI 生成更不能作为处罚或封禁的唯一依据。不适合直接商用发布。如果要上线给别人用需要补充用户协议、隐私说明、免责声明。使用边界和合规提醒AI 文本检测本身存在两个根本性限制一是模型能力在快速迭代旧的判别经验会迅速失效二是任何检测手段都无法做到 100% 准确误判成本很高。因此凡涉及内容审核、版权认定、学术诚信判断的场景一定要结合其他证据不能只靠人眼判断或单一检测工具。如果后续要用 AI 生成样本文本请使用合法渠道获取模型服务并确认样本内容不侵犯他人版权、不包含个人隐私信息。涉及批量抓取文本时注意遵守数据来源网站的条款和 robots 协议。3. 整体架构与数据设计3.1 架构分层“Wikipedia: AI or Not Quiz”这类 Quiz 应用架构可以拆成四层前端展示层题目卡片、选项按钮、计分面板 接口服务层出题接口、提交答案接口、结果统计接口 数据管理层人工文本样本库、AI 文本样本库、答题记录 样本准备层文本采集、去重、长度归一化、标签标注对于本地部署或二次开发不需要过度设计。前端用原生 HTML/JS 或者 Vue/React 都可以后端用一个轻量框架提供 JSON 接口就够。关键是数据层要设计好样本结构。3.2 样本数据结构一段测试文本最好包含以下字段{ id: sample-001, content: 这是需要用户判断的正文内容……, source_type: ai, model_name: gpt-4o-mini, topic: 机器学习基础概念, difficulty: 1, used_count: 0, correct_rate: 0.0 }字段说明source_typeai或human这是答案标签model_name如果是 AI 样本记录生成时使用的模型方便后续分析topic文本主题方便按主题出题difficulty难度等级可以先由人工预设后期通过答题正确率动态调整used_count和correct_rate记录样本被使用次数和被答对比例用来淘汰过难或过易的题目。这里要注意一个数据偏差问题AI 样本是由某个模型在特定提示词下生成的人眼识别率只代表“那个模型 那个提示词”下的表现不能泛化成“AI 文本都这样”。所以样本数据里必须保留模型名和生成参数否则统计结果无法解释。3.3 样本准备流程准备样本的思路如下从公开语料中挑选人工文本优先选择有明确作者出处的段落确定主题范围比如科普、科技、生活、历史用不同模型、不同提示词批量生成 AI 样本对人工样本和 AI 样本做长度归一化避免“AI 文本长度差异”成为泄露答案的线索做一轮人工抽查去掉有明显格式特征、明显错误或包含敏感内容的样本打乱顺序导出成 JSON 文件作为题库。如果样本数量不大直接把题库文件放在后端目录里即可。样本量达到数千条后再考虑引入数据库。4. 环境准备与前置条件这个项目是典型的轻量 Web 应用环境准备非常简单Python 3.9用于后端服务和样本处理脚本Node.js 或纯静态前端如果只做演示原生 HTML 也可以一个本地终端一个浏览器无 GPU 依赖普通办公电脑即可磁盘占用通常在几百 MB 以内主要是依赖库和样本文件。如果后端使用 FastAPI需要安装以下依赖pip install fastapi uvicorn pydantic如果使用 Flaskpip install flask flask-cors如果前端使用 Vue/React按对应脚手架创建项目即可。这里不再展开。5. 后端接口设计与实现5.1 出题接口出题接口的核心逻辑是从样本池中随机抽取一条未被当前用户答过的样本返回同时隐藏答案标签。参考实现如下import random from fastapi import FastAPI, HTTPException from pydantic import BaseModel app FastAPI() # 模拟样本池实际项目可以从 JSON 文件或数据库读取 SAMPLE_POOL [ { id: s001, content: 机器学习是人工智能的一个重要分支它通过数据驱动的方式让计算机自动改进算法表现。, source_type: human, difficulty: 1, }, { id: s002, content: 在自然语言处理领域Transformer 架构通过自注意力机制有效建模文本中的长距离依赖关系。, source_type: ai, difficulty: 2, } ] class AnswerIn(BaseModel): sample_id: str user_answer: str # 取值 ai 或 human app.get(/api/quiz/next) def get_next_question(user_id: str guest): # 简化逻辑随机抽一条实际项目应排除已答过的样本 sample random.choice(SAMPLE_POOL) return { sample_id: sample[id], content: sample[content], difficulty: sample[difficulty] } app.post(/api/quiz/answer) def submit_answer(payload: AnswerIn): sample next((s for s in SAMPLE_POOL if s[id] payload.sample_id), None) if not sample: raise HTTPException(status_code404, detailsample not found) correct (sample[source_type] payload.user_answer) return { sample_id: sample[id], correct: correct, actual_type: sample[source_type] }注意几个细节出题接口不要返回source_type否则用户直接看接口响应就能作弊user_id用来记录答题进度避免同一用户反复抽到同一题真实项目里答题记录要持久化不能只存在内存里。5.2 结果统计接口结果统计接口返回用户的答题总数、正确数、正确率和错题列表app.get(/api/quiz/stats/{user_id}) def get_stats(user_id: str): # 实际项目从答题记录表聚合数据 return { user_id: user_id, total: 20, correct: 14, accuracy: 0.7, wrong_samples: [s003, s007] }5.3 启动服务后端写好之后启动命令uvicorn main:app --host 127.0.0.1 --port 8000 --reload启动后可以访问http://127.0.0.1:8000/docs查看 Swagger 接口文档。6. 前端答题页面设计如果不想引入复杂框架一个单页 HTML 就能完成基本交互。核心逻辑是页面加载时请求/api/quiz/next渲染文本内容用户点击“AI 生成”或“人类写作”提交答案到/api/quiz/answer展示判定结果并加载下一题。一个简化版前端示例!DOCTYPE html html langzh-CN head meta charsetUTF-8 titleAI or Not Quiz/title /head body div idquiz-box p idcontent加载中.../p button onclicksubmit(ai)AI 生成/button button onclicksubmit(human)人类写作/button p idresult/p /div script let currentSampleId ; async function loadNext() { const res await fetch(/api/quiz/next); const data await res.json(); currentSampleId data.sample_id; document.getElementById(content).innerText data.content; document.getElementById(result).innerText ; } async function submit(answer) { const res await fetch(/api/quiz/answer, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ sample_id: currentSampleId, user_answer: answer }) }); const data await res.json(); const feedback data.correct ? 回答正确 : 回答错误正确答案是 data.actual_type; document.getElementById(result).innerText feedback; setTimeout(loadNext, 1500); } loadNext(); /script /body /html如果你有 CORS 跨域需求后端需要配置允许跨域from fastapi.middleware.cors import CORSMiddleware app.add_middleware( CORSMiddleware, allow_origins[*], allow_methods[*], allow_headers[*] )注意allow_origins[*]只建议在本地测试环境使用。部署到公网时应配置为具体的域名列表。7. 批量样本生成与评测脚本7.1 批量生成 AI 文本样本如果你要通过大模型 API 批量生成测试样本可以写成脚本把生成结果直接落盘为 JSON。参考脚本框架pip install openaiimport json from openai import OpenAI client OpenAI( api_keyyour-api-key, base_urlyour-base-url # 如果使用代理服务替换为对应地址 ) topics [ 人工智能发展史, 机器学习基础概念, 深度学习在图像识别中的应用, 大语言模型的工作原理 ] samples [] for topic in topics: prompt ( f请写一篇 200 字左右的科普短文主题是「{topic}」。 要求表达自然、结构清晰、没有明显机器痕迹。 ) response client.chat.completions.create( modelyour-model-name, messages[{role: user, content: prompt}], temperature0.8 ) text response.choices[0].message.content.strip() samples.append({ id: fai-{len(samples)1:03d}, content: text, source_type: ai, model_name: your-model-name, topic: topic, difficulty: 1, used_count: 0, correct_rate: 0.0 }) with open(ai_samples.json, w, encodingutf-8) as f: json.dump(samples, f, ensure_asciiFalse, indent2) print(f已生成 {len(samples)} 条 AI 样本)注意不同模型的写作风格差异很大temperature参数也会影响文本多样性。建议每个主题生成多条样本并且让不同模型、不同参数混在一起避免题库里全是同一风格。7.2 样本质量检查生成完 AI 样本后需要做一轮质量检查。重点看是否存在事实错误或明显幻觉内容是否存在“作为AI语言模型”之类的 AI 自曝话术段落长度是否与人工样本匹配是否有明显的模板化开头比如“在当今社会”“随着科技进步”。这类特征如果大量存在会让 Quiz 变成“找模板”而不是“辨真假”降低测试价值。7.3 批量答题评测如果不想手动一题一题点可以写脚本直接调用出题和判定接口做批量评测。这种自动化方式适合收集大规模样本准确率import requests BASE_URL http://127.0.0.1:8000 user_id batch-user-001 total 0 correct 0 for _ in range(50): resp requests.get(f{BASE_URL}/api/quiz/next, params{user_id: user_id}) if resp.status_code ! 200: break question resp.json() # 这里可以替换成任意分类逻辑比如规则关键词、另一个模型、人工决策等 user_answer ai # 示例全部猜 AI可用于对照实验 answer_resp requests.post( f{BASE_URL}/api/quiz/answer, json{sample_id: question[sample_id], user_answer: user_answer} ) result answer_resp.json() total 1 if result[correct]: correct 1 print(ftotal{total}, correct{correct}, accuracy{correct / total:.2f})这个脚本的价值在于你可以设计多组对照实验。例如全部猜 AI 的基准正确率按文本长度字段判别的规则准确率某个提示词生成的样本人眼识别率真人短文本被误判为 AI 的概率。这些统计数据比单一题目的对错更有分析价值。8. 资源占用与性能观察这类 Quiz 应用性能瓶颈非常低。如果你在本地启动可以观察以下几点CPU 和内存后端服务只做随机出题和答案对比没有模型推理CPU 占用极低内存占用取决于题库大小。几千条样本加载到内存里几十分钟都没问题十万条以上建议换用 SQLite 或 PostgreSQL。响应时间本地启动后/api/quiz/next接口响应应该在几十毫秒量级。如果响应变慢优先检查是否每次请求都重新加载了题库文件。正确做法是启动时一次性加载后续请求只做查询。并发能力FastAPI Uvicorn 单进程可以轻松处理单机小规模并发。但如果用户量上来了要注意答题记录写入是否需要加锁出题接口是否会因为用户并发抽到同一样本是否需要限制单个用户的连续请求频率。网络带宽如果题库里的文本很长或者需要一次性返回大量样本列表注意接口响应体大小。一个 20 题的试卷接口返回几十 KB 是正常的但不要一次性把整个题库返回给前端。前端资源原生 HTML 页面几乎没有资源占用。如果使用 Vue/React 进行打包构建首屏资源通常也在几百 KB 以内不需要额外优化。8.1 如何观察接口耗时可以在启动 Uvicorn 时开启访问日志观察每个请求的耗时特征uvicorn main:app --host 0.0.0.0 --port 8000 --access-log如果要精确测量某个接口的性能可以写个简单压测脚本import time import requests BASE_URL http://127.0.0.1:8000 times [] for _ in range(100): start time.time() requests.get(f{BASE_URL}/api/quiz/next) times.append(time.time() - start) avg_time sum(times) / len(times) max_time max(times) print(favg{avg_time*1000:.1f}ms, max{max_time*1000:.1f}ms)注意压测数据只代表你的本地环境不同配置、不同题库大小结果会差很多。更稳妥的判断是只要接口平均响应在 200ms 以内对 Quiz 场景就没有感知差异。9. 功能测试与效果验证9.1 出题接口测试测试目的确认接口能返回不包含答案标签的随机题目。操作步骤启动后端服务访问http://127.0.0.1:8000/api/quiz/next检查返回 JSON 中是否包含source_type字段。预期结果{ sample_id: s002, content: 在自然语言处理领域Transformer 架构通过自注意力机制有效建模文本中的长距离依赖关系。, difficulty: 2 }判断标准响应里不能出现source_type否则属于接口设计缺陷。9.2 提交答案测试测试目的确认答案校验正确并返回实际答案。操作步骤curl -X POST http://127.0.0.1:8000/api/quiz/answer \ -H Content-Type: application/json \ -d {sample_id:s001,user_answer:ai}预期结果{ sample_id: s001, correct: false, actual_type: human }判断标准correct字段与样本真实标签一致。9.3 前端交互测试测试目的确认页面能正常加载题目、提交答案、展示结果。判断标准首次打开页面能显示题目文本点击按钮后能显示“回答正确/回答错误”1.5 秒后能自动加载下一题浏览器开发者工具中没有报错。常见失败原因后端没启动导致接口 404CORS 未配置导致前端无法跨域请求题库为空导致出题接口返回 404 或 500。9.4 批量评测脚本测试测试目的确认批量脚本能连续出题和判定不会因为单次失败中断。操作步骤先启动后端再运行批量脚本。判断标准脚本能跑完 50 次请求并按格式输出正确率中途任何一次请求失败脚本应有日志记录而不是静默跳过。9.5 数据偏差验证这是在样本准备完成后必须做的一步。测试目的确认题目中是否存在“一眼假”的特征导致用户不需要阅读内容就能答对。验证方法把 AI 样本和人工样本混合后找三个之前没接触过题库的人各做 20 题统计正确率。如果正确率接近 100%说明样本特征太明显题目失去了区分度如果正确率接近 50%说明样本已经达到“人眼无法稳定识别”的状态如果某个模型生成的样本被识别率特别高需要检查是否存在固定格式比如“总之”“总的来说”之类的模板化结尾。10. 常见问题与排查方法问题现象可能原因排查方式解决方案启动时报ModuleNotFoundError依赖未安装或版本不匹配执行pip list检查依赖按requirements.txt重新安装出题接口返回空内容题库文件未加载或格式错误检查后端日志和题库 JSON 结构确认content字段非空题库路径正确前端无法请求接口CORS 未配置或端口不一致打开浏览器开发者工具查看网络请求后端配置 CORS确保前端访问端口正确提交答案后一直卡住后端进程崩溃或无响应查看 Uvicorn 终端日志重启服务检查接口是否正常返回同一用户反复抽到同一题出题逻辑未记录已答题检查是否传入了user_id给每个用户维护当前会话的已答题目列表批量脚本中途报错接口偶发超时或返回 500给请求增加重试和日志每次请求设置timeout失败后重试 3 次答题结果显示错误答案样本标签source_type标错抽查题库 JSON 文件人工复核标签必要时重建样本池接口响应很慢每次请求重复加载题库查看代码中是否有文件读取逻辑将题库加载到内存启动时一次性读入端口被占用8000 端口已有其他服务使用lsof -i:8000或netstat -ano检查更换端口启动例如--port 800111. 最佳实践与使用建议第一样本管理要留元数据。每条样本至少保留来源类型、生成模型、主题、难度和命中次数。没有元数据的题库做出来的统计结论很容易失效。第二每次只做单变量对比。测试人眼识别率时一次只改变一个变量。比如固定模型只换主题或者固定主题只换模型。这样才能解释正确率变化的原因。第三记录答题数据。把用户的每次答题结果落库哪怕只是存成 JSON 行日志。积累一个月后回头分析你能看到 AI 生成文本风格变化对自己判断力的影响。第四控制题库难度。正确率长期高于 90% 的题目可以降权或下架正确率长期低于 50% 的题目要检查是否存在误导性特征。动态难度调节是 Quiz 类应用做好体验的关键。第五接口要加访问控制。如果部署到公网必须给接口加鉴权和限流。否则别人可以循环调用出题接口把所有样本抓走或者用脚本刷排行榜。第六不要回避误判风险。不管答题正确率多高这个项目本质上是一个教育/训练工具不是检测工具。在项目文档和界面上建议明确写出“判断结果仅供参考不能作为内容来源鉴定依据”。第七AI 文本检测要关注幻觉内容。你在准备 AI 样本时可能会发现某些模型生成的内容存在事实错误。这些内容在 Quiz 里可以用来测试用户的“阅读警惕性”但如果在内容生产场景里被误用会造成传播错误信息的风险。合法合规的 AI 内容生产必须经过事实核查。12. 本地一键启动参考如果你想把前后端串起来一个简单的方式是后端提供接口前端用静态文件托管。目录结构建议如下quiz-project/ ├── backend/ │ ├── main.py │ ├── samples/ │ │ ├── human_samples.json │ │ └── ai_samples.json │ └── requirements.txt └── frontend/ └── index.html启动顺序先启动后端cd backend pip install -r requirements.txt uvicorn main:app --host 127.0.0.1 --port 8000再启动前端静态服务在另一个终端cd frontend python -m http.server 8080浏览器访问http://127.0.0.1:8080即可开始答题。注意如果你的前端代码和后端接口不在同一个端口需要确保后端正确配置了 CORS或者让前端通过后端静态托管页面。13. 后续可扩展方向这个项目继续往下做有几个比较自然的方向方向一接入自动判定模型。把“用户判断”和“模型判断”放到同一套题目上对比统计人机识别率差异。这就变成了一个半演化的研判工具。方向二增加错题复盘。答错后展示正确答案同时标注原文中可能存在的线索比如逻辑连贯性、句式多样性、用词分布等。这对提升用户的文本鉴别能力很有帮助。方向三动态题库。接入文本样本池的自动扩充管线定期生成新样本人淘汰旧样本保持题目的时效性。方向四多人对战模式。多用户实时答题通过正确率和响应速度排名。这个方向的工程复杂度会明显上升需要考虑 WebSocket 通信和在线状态管理。最值得先验证的功能是样本质量检查。如果你能把 AI 样本准备到“人眼无法稳定识别”的程度这个 Quiz 就成功了一半。相比之下前端的交互轮播、计分动画、排行榜都不是核心难点。最容易踩的坑是样本标签错标。人工样本里混入 AI 生成内容或者 AI 样本里夹杂大量模板化句式都会直接毁掉整个题库的统计学意义。准备样本时宁可少一些也要确保每条样本的标签可靠。如果这个项目你准备继续深挖可以重点研究两个方向一是不同大模型生成文本的指纹特征二是人类对 AI 文本误判的心理机制。前者是工程问题后者是认知科学问题两者结合就是内容安全管理里非常实用的一层防御能力。
返回列表