前阵子我想验证一个很实际的问题:一个没系统学过前端的人,能不能靠对话式AI编程工具从零做出一个真正能用的网页工具。挑来挑去,最后选了一个qr_code二维码生成网页。选它的理由很直白——二维码这个功能,用户需求极其清晰:打开页面、输入文字或链接、点击生成、扫码验证、下载保存,流程完全闭环。它没有复杂的业务逻辑,却有足够的技术知识点让AI去处理,做好了还能拿手机当场验证,生成结果对不对一目了然。
整趟试下来,我拿到了一个能正常生成、能扫码识别、能下载PNG图片的网页。过程不算一路顺畅,中间遇到过下载按钮没反应、中文内容扫码后显示异常、页面在手机上排版错位这些小问题,基本都靠和AI工具来回对话修掉了。这篇文章就完整记录一下我的选型思路、二维码背后的原理、用AI生成代码的实操过程,以及最后的人工审查心得,给想拿AI工具练手的人一个可以直接参考的样本。
1. 选型理由:为什么拿二维码当第一个AI辅助项目
1.1 这个项目踩在难度黄金分割点上
如果只做最简版本,整个二维码生成网页就是一张HTML文件,里面放一个文本输入框、一个生成按钮、一个展示区域、一个下载按钮。核心逻辑调用现成的二维码生成库,把用户输入的字符串变成Canvas上的黑白方块。加起来不到一百行有效代码,很多AI编程工具一次就能生成。
可它又不像倒计时器、备忘录那样简单到没法暴露问题。这个项目至少牵扯五个技术点:DOM事件绑定、Canvas绘图、图片导出、字符编码、布局适配。每个环节出错,表现都不一样。比如按钮绑定了事件但没触发下载,二维码画出来了但中文变成乱码,页面在电脑上正常但手机上一塌糊涂。这种"有点技术含量但又不会难到失控"的项目,正好用来试探AI生成代码的质量边界。
我当时给自己定的验收标准就三条:第一,输入任意文本能生成二维码;第二,生成的二维码用手机相机能扫出原始内容;第三,能下载生成好的图片。这三条全部满足,就算这个练手项目成功。
1.2 明确的功能边界,天然适合对话式开发
跟AI协作写代码,最怕的就是需求模糊。你说"帮我做个工具页面",它大概率会自由发挥出一堆你不需要的东西。而二维码生成器的功能边界非常清晰,核心名词就那几个:文本输入、生成按钮、二维码画布、下载按钮。这些名词在对话里反复出现,AI不需要猜测业务逻辑,犯错的概率会小很多。
这里也想提醒一句:如果你想让AI生成一个你自己都没搞明白功能的目标,那翻车的概率极高。最好的练手项目应该是那种"你清楚知道它该怎么用,只是还不会写代码"的东西。我对二维码的最终形态有明确认知——就是输入内容后出现一个黑白色块矩阵,所以当AI生成结果跑偏时,我能第一时间判断出来并纠正它。这种判断力,比会背语法重要得多。
1.3 一句真心话:别把AI生成的代码当成品
零基础用户用AI编程,最容易陷入的误区是看到页面能跑就认为交付完成。AI生成的代码经常是"看起来合理、浏览器一跑就露馅",或者"当前场景正常、换一个输入立刻出错"。二维码项目有个天然优势——端到端验证极简单。页面生成完,掏出手机对着屏幕扫一下,能不能识别、内容对不对,几秒钟就有答案。这种强验证机制,特别适合用来训练自己审查AI代码的习惯。
我见过有人用AI写完代码连测都不测就直接说"做完了",这种做法在二维码这种小工具上可能没大碍,换成有账号体系、有支付逻辑的项目就是灾难。所以这篇记录里,我把最后的人工审查章节写得比较重,因为那才是AI辅助开发里真正值钱的经验。
2. 看懂二维码底层逻辑,才好判断AI写没写对
2.1 二维码的本质与三种核心能力
二维码本质上是一套二进制矩阵。黑色方块代表二进制1,白色方块代表0,扫描器按照特定规则读取这些方块,还原出原始文本内容。所以二维码不是"加密图片",它的内容理论上可以直接被肉眼读取,只是人眼处理不过来几千个方块的信息密度。
二维码能快速流行,靠的是三个能力。第一是信息容量大,同样面积能装下几百个字符,网址、文本、联系方式都能塞进去;第二是识别速度快,手机摄像头对着拍一下就能解码,不需要对焦在一个很小的区域;第三是容错能力强,就算图案被遮挡、破损、打印模糊,扫描器依然能根据冗余数据还原出大部分内容。这也是为什么二维码允许在中间放Logo,允许被印在弯曲的杯子上,依然能扫出来。
还有一个基础知识:二维码有三个角的"回"字形定位图案。这三个图案的作用是让扫描器确定二维码的方位、大小和畸变程度。正因如此,二维码印在不平整的表面上也能被识别。AI生成代码时不会显式处理这些底层图案,因为它调用的是现成生成库,但了解这一点能帮你在调试时不会朝错误方向乱猜——当你发现二维码扫不出来时,先检查对比度和清晰度,而不是怀疑生成逻辑。
2.2 纠错等级:一个影响"能不能扫出来"的参数
二维码生成库通常暴露一个纠错等级参数,常见的有四个等级,从低到高是L、M、Q、H。纠错等级越高,生成的二维码里塞的冗余数据越多,越抗遮挡,代价是图案越复杂、可容纳的有效内容越少。
| 纠错等级 | 约可恢复的污损比例 | 典型适用场景 |
|---|---|---|
| L | 7% | 打印质量好、没有遮挡的纸面二维码 |
| M | 15% | 屏幕展示、普通打印,日常默认选择 |
| Q | 25% | 中间加了Logo、表面有部分遮挡 |
| H | 30% | 极端环境、磨损表面、容错要求极高 |
这次实操中,AI生成代码默认选的纠错等级是M。这个选择没有错,屏幕展示场景用M级很合理。但如果你打算在二维码中间加一个品牌Logo,那等于主动牺牲了中心区域约30%的图案,M级就会变得不够用,应该至少上调到Q级。这个逻辑不是AI能替你决定的,它取决于你要把二维码用在什么场景、要不要放Logo、会不会有遮挡。所以这个参数必须你自己理解,而不是无脑用默认值。
2.3 生成库的基本工作方式
市面上的二维码生成库很多,实现思路大同小异:接收一个字符串,内部按二维码标准把字符串编码成二进制矩阵,再绘制到Canvas或SVG上。这次我用的是常见做法——通过script标签在HTML页面里引入一个qrcode库文件,然后直接调用。
核心调用代码长这样:
const qr = new QRCode(document.getElementById("qrcode"), { text: "https://example.com", width: 256, height: 256, colorDark: "#000000", colorLight: "#ffffff", correctLevel: QRCode.CorrectLevel.M }); // 用户输入变化后,可以用 makeCode 更新二维码 qr.makeCode("新的内容");理解这段代码的关键是:width和height控制生成图片的像素尺寸,colorDark和colorLight控制方块颜色,correctLevel对应上一小节说的纠错等级。AI生成第一版时基本就会给出类似结构,你后面要做的所有定制化调整,几乎都围绕这几个参数展开。
这里也要提一个很实际的坑:AI生成代码时常默认用CDN链接引入库文件。联网状态下一切正常,可一旦你想把这个网页放到U盘里带到断网环境演示,二维码功能会直接失灵。我后来把库文件下载到本地项目目录,改成相对路径引用,才算彻底解决离线可用性的问题。做工具类网页,离线可用是一个不该忽略的需求。
3. 实操全程记录:一句话需求如何变成可运行页面
3.1 第一版提示词,我只给了三句话
我在本地建了一个项目文件夹,里面放了一个空的HTML文件,然后在AI编程工具的对话框里写下了第一版需求。提示词没有写得多花哨,就是把验收标准翻译成人话:
"做一个二维码工具网页。用户在文本框里输入内容,点击生成按钮后,下面显示对应的二维码。支持选择生成图片的尺寸,支持下载PNG图片。"
就这三句话。AI工具生成了一段完整HTML,打开浏览器预览,页面上确实有输入框、生成按钮、二维码展示区、下载按钮,输入内容点击生成,二维码立刻出现。用手机扫了一下,还原出的字符串和输入内容一致。第一版在线功能实际上是通的。
这里有个细节值得说:为什么我不把需求写成"帮我做一个高级的二维码平台",因为对话式AI在模糊需求下会自作主张。需求越具体,生成结果越可控。我宁可让它先出一个朴素版本,然后一步步加功能,也不想让它自由发挥出一堆我根本不知道该怎么维护的代码。后面所有功能调整,都是在这个朴素版本上对话完成的。
3.2 生成结果:能出图,但下载按钮是摆设
第一版页面明显有个问题:下载按钮点击后没有任何反应。这属于AI生成代码里的高频翻车点。最常见的病因有三个:一是按钮绑定了事件但触发逻辑没有真正调用下载;二是下载逻辑用了不兼容的写法;三是脚本执行时机太早,DOM元素还没加载完就尝试绑定。
当时我去看AI生成的代码,症状确实典型——下载函数内部试图直接把二维码所在的Canvas转成图片,但某种浏览器环境下转出来的数据没被正确触发下载。我没有自己闷头改,而是在对话框里追加了一句:"点击下载按钮没有反应,请检查Canvas转图片并触发下载的部分,优先使用toBlob配合URL.createObjectURL的方式。"AI很快把下载逻辑改成了标准写法。
修正后的下载逻辑大概是这样的:
const canvas = document.querySelector("#qrcode canvas"); canvas.toBlob(function(blob) { const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "qrcode.png"; a.click(); URL.revokeObjectURL(url); });之所以推荐toBlob而不是toDataURL,是因为二维码图片尺寸调大之后,toDataURL生成的超长Base64字符串在部分浏览器里会拖慢页面甚至触发数据长度限制。用Blob方式走内存对象,再通过URL.createObjectURL生成临时链接,对浏览器更友好。这个经验在生成高分辨率二维码时尤其重要。
3.3 用对话式追问代替百度,修复中文乱码问题
下载功能修好之后,我又发现一个新问题:输入中文内容并生成二维码,手机扫描出来的结果偶尔出现乱码。这其实是二维码生成过程中常见的中文字符编码问题。二维码标准支持UTF-8编码,但某些库在内部处理时可能没有显式按UTF-8编码字符串,导致扫描器按默认字符集解读时错位。
解决思路是确保传给生成库的字符串是UTF-8格式。很多情况下,把输入内容转换成UTF-8编码即可:
const text = input.value.trim(); qr.makeCode(unescape(encodeURIComponent(text)));这里用encodeURIComponent先把字符串做UTF-8百分号编码,再用unescape还原成二进制内容,能规避部分库对非ASCII字符处理不完善的问题。在AI工具对话框里,我描述的现象是"输入中文后扫码结果乱码",它给出的方案就是这类字符编码处理。这个坑属于那种"没遇过就完全想不到"的类型,但一旦知道,以后再碰到就不会慌。
3.4 提示词的三个实用技巧
经过这次实操,我自己总结出跟AI编程工具协作的提示词三原则。
第一,一次只聚焦一个问题。在对话框里同时说"下载坏了、中文乱码、手机布局也乱了",AI很可能只处理其中一个,或者改完一个又弄坏另一个。一次一个目标,改完立刻验证,效率反而更高。
第二,用"要怎么做"代替"不要怎么做"。比如"点击下载没有反应,帮我改用toBlob触发下载"比"不要用toDataURL"更有效。AI对负面指令的理解经常不够精确,给它明确的方向比禁止它做什么更稳。
第三,让AI解释关键代码。生成完下载逻辑后,我追问"这段代码每一行是干什么的",AI会逐行解释。这个动作不只是让零基础的人看明白,更重要的是让AI自己重新审视代码,很多时候它在解释的过程中会发现潜在的边界条件问题。
4. 功能打磨:把"能扫出来"升级成"用户愿意用"
4.1 尺寸、边距和容错率的现场取舍
基础版本跑通后,我开始给页面加"用户可调节"的能力。第一个加的是尺寸调节。UI上放了一个下拉框,可选128、256、512三个像素尺寸,对应小图展示、常规下载、高清打印三种场景。这里有一个容易被忽略的细节:生成二维码时width和height最好设置相同值,否则二维码会变成矩形,虽然扫描器一般也能识别,但视觉上不专业。
边距同样重要。二维码四周需要留一圈安静区域,也就是空白边距,扫描器要靠它来确定图案边界。库参数里通常会有一个控制边距的选项,具体名称可能是margin,它控制的是二维码矩阵和Canvas边缘的间距。默认值不算小,但如果你把二维码放在花纹复杂的背景上,光有默认边距还不够,建议在UI上再加一点白色底衬。
纠错等级我也开放给了用户,下拉框里L、M、Q、H四个选项全列出来,默认选中M。这个功能对普通用户可能有些超纲,但好处是遇到"加了Logo之后扫不出来"的场景,用户可以自己切换到Q或H再重新生成,不需要改代码。作为工具页面,让用户在界面层自己调整参数,比埋头改代码再刷新页面直观得多。
4.2 颜色与风格:好看的前提是保持对比度
二维码默认是黑色方块加白色背景,这是识别率最高的配色。很多工具类网站为了让页面好看,会把二维码改成蓝色、红色甚至彩色渐变。颜色可以改,但前提是深色方块和浅色背景之间必须保持足够的对比度。以我实测的经验来看,前景色建议使用深色系,比如黑色、深蓝、墨绿,背景色建议接近白色或非常浅的灰色。浅黄色背景加白色方块这种组合,看着清新,手机扫起来大概率失败。
我在页面上加了一个简单的颜色选择器,允许用户选一个前景色,背景固定为白色。生成时把选中的前景色传给colorDark参数。这里还有个小技巧:深色方块颜色可以不是纯黑,但亮度和纯黑相差不能太大。我曾经选了一个深红色二维码,电脑上看非常漂亮,手机也能扫出来,但打印后颜色饱和度下降,识别率明显变低。所以如果这个二维码要用于打印,建议还是用默认黑白色。
4.3 下载文件名的细节处理
下载功能能跑之后,我又让AI工具优化了文件名的生成规则。固定命名为qrcode.png有个问题:用户连续下载多个二维码,文件名相同,容易混淆。改成带时间戳或者带内容摘要的命名会合理很多。
实现起来很简单,就是在下载时拼接一个时间字符串:
const timestamp = new Date().toISOString().slice(0, 19).replace(/:/g, "-"); a.download = "qrcode_" + timestamp + ".png";这样每次下载的文件名都不同,方便归档。如果想更友好一点,可以截取输入内容的前几个字符放进文件名里,比如qrcode_赶火车清单.png。不过要注意清理文件名里的特殊字符,斜杠、冒号这些在某些操作系统里会触发保存异常。这个小细节直接拉高了工具的专业感,属于那种"用户说不出来但能感觉到"的体验提升。
4.4 移动端适配的小改造
第一版页面在手机浏览器上打开,布局会有点散。原因很简单:AI生成的初始版本只考虑了桌面端,没有加手机适配。移动端适配这件事,说难不算难,但堆起来也是一串事。
最先要处理的是HTML头部加一行视口声明:
<meta name="viewport" content="width=device-width, initial-scale=1.0" />没有这行声明,手机浏览器会按桌面宽度渲染页面,用户需要双指缩放才能看全,体验非常差。其次是文本框和按钮的宽度,桌面端可以设置固定宽度,移动端应该让输入框撑满可用宽度,按钮则适合做成整行宽度,方便拇指点按。还有一个我实测发现的小问题:手机浏览器输入内容时,默认会把页面缩放一下,如果输入框字号小于16px,iOS会触发自动聚焦放大,也就是用户一输入,页面就"跳"一下。解决办法是让输入框字号不小于16px。
这些适配细节AI工具通常不会在你第一版里全部顾上,但你把"用手机打开看看效果"这个反馈丢给它,它会逐项补上。每次补一项就实机验证一次,几次下来页面在手机上的表现就正常了。
5. 实测效果与AI代码审查心得
5.1 用三种环境验证"能扫、能下、能改"
全部功能加完以后,我做了一轮完整验收。验证方式比想象中简单,核心就三件事:能不能扫、能不能下、能不能改。
扫的验证分两个环境。第一个是手机原生相机,直接对着屏幕上的二维码拍,识别速度很快,内容完全正确;第二个是常用App里的扫码功能,同样能正常识别。为了测不同尺寸,我特意在128像素、256像素、512像素三个尺寸下各生成了一次二维码,分别让手机扫。实测下来256像素和512像素的识别都很顺,128像素的二维码图案略小,手机离近一点也能扫出来,但太远就会偶尔识别失败。考虑到这个尺寸主要用于页面缩略展示,用户下载高清图时会调到512,所以这个表现可以接受。
下的验证我做了两类:一类是在电脑浏览器上点下载,确认文件进入默认下载目录;另一类是在手机浏览器上点下载,确认生成的PNG文件能用手机打开。这里发现一个预期内的小问题:手机浏览器触屏点击偶尔会被判定为滑动手势,导致下载按钮不响应。解决办法是给按钮加上touch-action: manipulation样式,避免双击缩放和手势误判。
改的验证是多次生成不同内容,确认每次都会更新二维码而不是叠加。页面连续生成十个不同的文本,每生成一个用手机扫一下,内容都和输入一致。在多次生成的过程中也验证了清空逻辑,输入框清空后点击生成,页面会给出提示而不是打印一个空白二维码。
5.2 拿到生成代码后,我按这个顺序做人工审查
AI生成的代码不是不能出问题,而是问题往往藏得很深。经过这次实操,我整理了一份"拿到AI代码后的人工审查清单",顺序固定,逐项检查,基本能把大头风险过滤掉。
第一项,依赖引入方式。检查所有外部库是本地的还是CDN的。如果页面可能要在断网环境运行,就要改成本地引用。第二项,脚本执行时机。确认事件绑定代码在DOM加载完成后执行,否则可能出现"找不到元素"的报错。常见做法是把脚本放在body底部,或者用DOMContentLoaded事件包起来。第三项,画布清空逻辑。每次生成前是否清理旧内容,防止多次生成时新旧二维码叠在一起。第四项,输入校验。空内容、超长内容、纯数字内容是否有处理,不能直接把异常状态交绘图形库。第五项,下载命名与格式。PNG导出是否走Blob方式,文件名是否有区分度。
这个清单看起来琐碎,但它治的是AI代码的通病。AI编程的特点是大方向永远正确,细节往往粗糙。你不指望它一次写完美,但要养成一个习惯——每个功能点至少追问一个"这个场景下会不会出问题",然后按清单过一遍代码。经过这个流程,生成代码的可用性会从"能跑"提升到"稳定"。
5.3 AI工具在这次实验里的边界与可用性结论
最后说说AI工具本身。这次实际用下来,它的优点很明确:搭建页面骨架、写通用逻辑、修复常见API用法问题的速度远超人工手写。原本可能需要琢磨半天的Canvas导出代码,它几秒钟就能给出可用版本。缺点也同样明显:它对上下文的理解有上限,多轮对话后偶尔会忘掉前面已经确定的功能约束;遇到小众或版本更新的API,它可能给出"看起来像真的但其实不对"的代码;还有,它只会对你描述的问题负责,你自己没说需求,它就不会主动处理。
对零基础的人来说,我的建议是把它当成一个反应极快的同事,而不是一个全知全能的老师。你需要能看懂它写的关键代码在做什么,需要具备基本的验证能力,遇到问题要知道怎么描述现象。这三板斧练熟之后,AI编程工具可以用来做大量实用小工具。
做完这个二维码项目,我最大的体会是:所谓"AI替代程序员"在现阶段并不准确,更准确的描述是"AI把实现成本拉低了,但判断力和验证意识依然在人身上"。一个功能边界清晰、验证手段简单的小项目,恰好是把这种协作模式跑通的最佳切入点。这之后我又用同样的思路试着做了一个简易计算器页面,虽然过程中同样踩了几个坑,但整体流程已经熟练很多。如果你正想尝试AI辅助开发,找一个像二维码生成器这样的项目起步,你会发现这条路确实走得通。