从零构建CatGPT:纯前端趣味项目与AI辅助开发实战
1. 项目概述当一只猫决定接管对话如果你觉得那些一本正经的AI助手过于沉闷总想从它们那里得到点“不按常理出牌”的回应那么你大概能理解我当初那个有点无厘头的想法如果回答问题的是只猫会怎样于是CatGPT诞生了。这纯粹是一个出于好玩和个人兴趣的Web项目它的核心逻辑简单到令人发笑——用随机生成的“喵”声来模仿一次AI对话。但正是这个简单的想法让我完整地体验了一次从概念构思、技术选型、借助AI辅助开发到最终部署上线的全流程。更重要的是它让我对当前AI工具在创意编程中的定位有了非常具体和深刻的体会。这个项目本质上是一个静态网站完全由前端技术HTML, CSS, JavaScript构建部署在Netlify上。它没有任何后端逻辑不调用任何真实的AI API也不会处理或存储用户的任何输入数据纯粹在浏览器端运行。它的全部“智能”都来源于一个精心设计的、能生成看似合理猫语回复的JavaScript函数。接下来我将详细拆解这个项目的构建过程分享其中有趣的技术细节、我如何利用ChatGPT作为“初级码农”以及最终为何它只能是个“辅助”而非“主力”的实战心得。2. 核心思路与方案选型2.1 从“玩笑”到“产品”的定义最初的想法只是一个模糊的玩笑“做个像ChatGPT的网站但让猫来回答”。要把它变成一个可访问的网站我需要明确它的产品形态。我将其定义为一个极简、仿ChatGPT UI的对话模拟器。核心功能只有两个用户输入一个文本输入框用于提交问题。猫式输出一个对话区域用Markdown样式渲染对话历史其中“AI回复”部分是由程序生成的随机猫语。这个定义排除了许多复杂可能性比如连接真正的语言模型、实现多轮对话记忆、用户账户系统等。它确保项目范围极小可以快速实现和上线。技术栈的选择也随之变得清晰纯前端技术栈是最佳选择既能实现功能又免去了服务器、数据库的维护成本。2.2 技术栈决策为什么是纯静态网站选择纯静态网站HTML/CSS/JS部署在Netlify是基于以下几个关键考量成本与复杂度为零Netlify为静态网站提供免费的自动化构建和全球CDN分发绑定自定义域名也非常方便。这意味着从开发到上线我没有在服务器和运维上花费一分钱或一分钟。完美的功能匹配项目不需要任何服务器端计算或数据持久化。所有交互用户输入、生成回复、渲染界面都可以在用户的浏览器中瞬时完成。使用静态托管是最直接、最高效的方案。开发体验流畅现代前端工具链虽然本项目未使用复杂框架配合Netlify的Git集成可以实现“代码推送即部署”的自动化流程极大简化了持续迭代的过程。安全与隐私由于所有代码都在客户端执行且不向任何服务器发送用户数据从根本上杜绝了数据隐私泄露的风险。这在项目声明中也是一个重要的加分项。注意对于任何功能简单、以展示和前端交互为核心的项目都应优先考虑静态站点方案。它能把你的精力完全集中在产品逻辑和用户体验上而非基础设施。2.3 设计目标像素级模仿与趣味性平衡UI设计的目标是“形似神不似”。形似是为了让用户一眼就能认出这是在对标ChatGPT降低学习成本并产生幽默的反差感。神不似则是要通过细节注入猫的个性。布局模仿经典的左右布局或上下布局左侧/上方为对话历史底部为输入框和发送按钮。采用类似的配色方案深色主题、字体如Inter,Segoe UI和间距。细节“猫化”Logo将OpenAI的旋涡Logo替换为一个猫爪印或猫头剪影。头像用户头像使用一个标准的人形图标而“AI”头像则替换为一张可爱的猫图片项目中用的是我的猫Suus的照片。提示文本输入框的占位符可以从“Send a message”改为“Meow something...”。回复指示器当“猫”在“思考”实际上是生成回复的短暂延迟时不是显示“ChatGPT is typing...”而是显示“Cat is thinking...”或一个跳动的“”符号。这些细微的改动成本极低但能极大增强项目的趣味性和沉浸感是此类趣味项目的精髓所在。3. 核心实现细节拆解3.1 HTML结构与CSS样式构建ChatGPT的“外壳”我首先需要搭建一个静态页面框架。这里是我第一次引入ChatGPT作为助手。我向它提出了明确的指令“创建一个具有类似ChatGPT界面的HTML和CSS文件包括一个标题、一个消息容器、一个底部输入区域。”ChatGPT迅速生成了一个基础版本包含了基本的深色主题、flexbox布局和样式。这为我节省了大量从零开始编写布局CSS的时间。然而生成的代码是通用且粗糙的HTML结构过于简单消息容器可能只是一个简单的div缺乏针对每条消息用户/猫的结构化标签。CSS缺乏细节阴影、圆角、输入框焦点状态、滚动条样式等提升质感的细节都没有。缺乏响应式设计未考虑不同屏幕尺寸的适配。我的手动优化工作结构化消息我将消息容器改为按消息条目渲染的结构。每条消息是一个div classmessage内部包含头像img和内容div classcontent并为用户和AI的消息添加不同的CSS类如.user-message,.ai-message以便分别样式化。精细化CSS为消息框添加了微妙的box-shadow和border-radius。美化了输入框设置padding、border并定义了:focus状态下的高亮效果。使用CSS自定义了滚动条样式使其更符合整体暗色主题。通过media查询实现了基本的响应式布局确保在手机端也能良好显示。引入字体与图标通过CDN引入Inter字体并从FontAwesome和Iconsax获取了飞机发送图标和用户头像图标。猫的头像则使用本地图片。实操心得ChatGPT生成的UI代码是一个优秀的“起点”或“灵感来源”但它无法理解你对像素级细节、可维护性结构或特定交互效果的追求。它生成的是“能用”的代码而非“优秀”的代码。前端开发中对UI细节的掌控必须由开发者自己完成。3.2 JavaScript逻辑创造一只“有逻辑”的猫这是项目的核心灵魂。我们需要一个函数它接收任意的人类问题返回一个看似合理的猫语回答。关键点在于完全随机会显得很蠢需要一定的模式来制造“智能”假象。最初的ChatGPT尝试我让ChatGPT“编写一个函数生成像猫说话一样的随机回复”。它给出了一些基于固定数组随机选择回复的版本比如[Meow, Purr..., Hiss!]。这显然太简陋了。我设计的“猫语生成算法” 目标是让回复看起来有长度变化、有简单的“语法”结构甚至能“回应”某些关键词。我构建了一个多层次的生成策略function generateCatResponse(userInput) { // 1. 基础词汇库 const catWords [Meow, Mrow, Prrr, Hiss, Chirp, Yowl, Mew, Brrp, Ack, ...]; const connectors [ , ... , ~ , ! ]; const endings [., !, ?, ..., ~~]; // 2. 简单关键词触发制造“理解”的错觉 const lowerInput userInput.toLowerCase(); if (lowerInput.includes(food) || lowerInput.includes(hungry) || lowerInput.includes(eat)) { return Meow! Meow! Meow! (翻译罐头立刻马上); } if (lowerInput.includes(sleep) || lowerInput.includes(bed)) { return Prrrrr... zZZZ; } if (lowerInput.includes(love)) { return Purr... 3; } // 3. 根据输入长度决定回复“复杂程度”一个小心机 const complexity userInput.length 20 ? 3 : (userInput.length 10 ? 2 : 1); // 4. 构造回复 let response ; for (let i 0; i complexity; i) { const word catWords[Math.floor(Math.random() * catWords.length)]; const connector i complexity - 1 ? connectors[Math.floor(Math.random() * connectors.length)] : ; response word connector; } response endings[Math.floor(Math.random() * endings.length)]; // 5. 小概率生成“长句” if (Math.random() 0.1) { response response generateCatResponse(); // 递归拼接一段 } return response; }逻辑解析关键词触发这是制造“智能感”最重要的把戏。当用户输入中包含特定词汇时返回一个预设的、看似相关的回复。用户会觉得“这猫好像听懂了”实际上只是一个简单的字符串匹配。复杂度关联将回复的长度与用户输入的长度粗略关联。用户输入很长时猫的回复也倾向于更长这符合对话的直觉。随机构造从词汇库中随机选取单词用连接符拼接最后加上随机结尾。这保证了回复的多样性和不可预测性。随机长句通过一个小概率事件递归调用自身来生成更长的“喵喵句”打破模式增加趣味性。3.3 对话流程管理与UI更新有了回复生成器接下来需要管理对话状态和更新界面。状态管理 对于一个简单项目使用一个全局数组来存储对话历史就足够了。let conversationHistory [ { sender: ai, text: Meow! I am CatGPT. Ask me anything (I might just meow back). } ];核心交互函数sendMessage()获取输入从输入框获取用户文本并清空输入框。更新历史将用户消息对象{ sender: user, text: userText }加入conversationHistory。UI更新立即将用户消息渲染到对话容器中。模拟“思考”显示一个“Cat is thinking...”的加载指示器。生成并添加回复使用setTimeout模拟一个短暂的网络延迟如500-1000毫秒然后调用generateCatResponse(userText)生成猫回复。将AI消息对象加入历史并更新UI同时隐藏加载指示器。滚动到底部每次添加新消息后将对话容器的滚动条滚动到底部确保始终看到最新消息。UI渲染函数 这个函数遍历conversationHistory数组为每条消息创建对应的DOM元素头像、内容气泡并将其插入到对话容器中。需要注意在每次更新时先清空容器再重新渲染或者更高效地只追加新消息。注意事项在模拟“思考”状态时一定要确保UI的响应性。虽然用了setTimeout延迟但主线程不能被阻塞。所有DOM操作都应该是快速的。如果生成回复的逻辑变得异常复杂在本项目中不会就需要考虑用Web Worker来避免界面卡顿。4. 与ChatGPT协作的实战经验CatGPT项目本身是关于猫的但它的构建过程却是我与ChatGPT作为编程助手的一次深度合作实验。我的体会非常具体。4.1 ChatGPT的优势高效的“脚手架”生成器快速启动当我对一个技术栈比如一个不常用的CSS布局概念模糊时直接描述需求让ChatGPT生成示例代码能让我迅速越过“从零开始”的空白期。例如“用Flexbox实现一个固定在底部的输入栏”这类问题它都能给出正确的基础代码。提供备选方案当我询问“如何用JavaScript在页面中添加一个打字机效果”时它不仅能给出使用setInterval逐字打印的方案还能提到使用CSSkeyframes动画的另一种思路这拓宽了我的解决方案视野。解释代码片段当我从Stack Overflow复制了一段不太理解的代码时让ChatGPT逐行解释学习效率远高于自己苦苦搜索。4.2 ChatGPT的局限缺乏上下文与创造力“失忆”与破坏性修改这是本次开发中最大的痛点。当我基于它生成的初始代码进行了一系列手动修改后再要求它“在现有代码基础上添加一个黑暗模式切换按钮”它给出的代码往往是基于它最初记忆的那个“原始版本”完全忽略了我后来添加的消息结构、样式优化等直接覆盖就会导致网站崩溃。它无法真正理解“当前项目”的完整上下文。缺乏真正的创造力与逻辑正如我的“猫语生成器”所示ChatGPT无法凭空创造出有趣、有深度的业务逻辑。它只能基于海量数据组合出常见的、平均的解决方案。项目的核心创意和精妙的“伪智能”逻辑必须由人类开发者来设计和实现。代码质量参差不齐生成的代码往往追求功能实现而非最佳实践。可能包含冗余、缺乏错误处理、性能考虑不周等问题。例如它可能不会建议使用事件委托来管理动态添加的消息按钮事件。4.3 有效协作模式总结经过这个项目我形成了一套与AI编程助手协作的工作流明确需求自己设计在向AI提问前我必须先在脑中或纸上想清楚我要什么甚至画出草图。我不能问“做一个聊天应用”而要问“用HTML/CSS创建一个如下布局的静态页面[详细描述或草图]”。分而治之小块索取不要一次性要求生成整个项目。应该按模块索取“生成一个具有以下样式的导航栏CSS”、“写一个从数组随机返回元素的函数”。这样生成的代码更可控也更容易集成。将AI输出视为“草案”永远不要直接复制粘贴并相信它能工作。必须将生成的代码放入自己的开发环境仔细阅读、理解、测试并按照自己的项目标准和架构进行重构和集成。人类负责核心与整合项目的核心业务逻辑如generateCatResponse、整体架构设计、不同模块之间的整合、错误边界处理、性能优化这些体现创造力和工程素养的部分必须由自己完成。让AI充当高级搜索引擎和解释器用它来查询特定API的用法、学习新概念、调试错误信息将错误日志丢给它分析、优化代码片段“如何让这段排序代码更高效”。5. 部署、优化与问题排查5.1 使用Netlify进行一键部署部署过程简单得不可思议将代码推送到GitHub仓库。登录Netlify选择“New site from Git”。授权并选择对应的GitHub仓库。构建设置由于是纯静态站点构建命令留空发布目录填写./(或/表示根目录)。点击“Deploy site”。几十秒后网站就拥有了一个[site-name].netlify.app的临时域名。之后我只需在域名服务商那里添加一条CNAME记录指向Netlify提供的域名并在Netlify后台配置自定义域名即可通过catgpt.wvd.io访问。5.2 性能与体验优化即使是一个小项目也有优化空间图片优化猫的头像图片使用工具如Squoosh进行压缩在不损失肉眼可见质量的前提下将文件大小减少了70%加快加载速度。防止输入框快速重复提交在sendMessage函数开始时检查一个标志位如isWaitingForResponse如果正在等待AI回复则忽略新的发送请求防止用户快速点击导致对话混乱。本地存储对话历史使用localStorage在用户关闭页面后保存对话历史下次打开时能恢复提升了用户体验。代码大致如下// 保存 localStorage.setItem(catGPTConvo, JSON.stringify(conversationHistory)); // 读取 const saved localStorage.getItem(catGPTConvo); if (saved) conversationHistory JSON.parse(saved);添加辅助功能为图片添加alt文本为按钮添加aria-label确保键盘导航可用让网站对屏幕阅读器用户更友好。5.3 常见问题与排查实录在开发过程中我遇到并解决了一些典型问题问题在手机上输入框被系统键盘遮挡。排查这是因为移动浏览器中固定定位(position: fixed)的元素在键盘弹出时的行为不一致。解决改用position: sticky布局并确保对话容器具有固定的高度和overflow-y: auto让页面可以正常滚动。或者使用JavaScript在输入框聚焦时轻微滚动页面。问题生成的猫语回复有时会出现“undefined”。排查检查generateCatResponse函数发现某个数组访问可能越界或者变量在某种条件下未定义。解决在随机索引访问前确保索引值在数组长度范围内。使用Math.floor(Math.random() * array.length)是安全的但要确保array本身不为空。对所有可能为undefined的变量添加空值合并操作符 (??) 或条件判断。问题Netlify部署后网站更新了代码但访问到的还是旧版本。排查浏览器缓存了旧的静态资源JS、CSS文件。解决这不是Netlify的问题。可以通过在引用资源时添加查询字符串版本号来强制更新缓存例如script srcapp.js?v1.2。更专业的做法是配置构建工具如Webpack对文件名添加哈希值。问题用户报告说在某个旧版本浏览器上样式错乱。排查我使用了某些较新的CSS属性如gap属性用于Flexbox。解决对于个人趣味项目我选择在网站页脚注明“推荐使用现代浏览器”。对于商业项目则需要使用Autoprefixer等工具后处理CSS或避免使用兼容性差的特性。6. 项目总结与扩展思考CatGPT作为一个周末项目已经达到了它的所有目标它有趣、完整、在线可访问并且让我实践了完整的开发流程。但更重要的是它成为了一个绝佳的“案例”让我思考工具与创造者之间的关系。这个项目清晰地展示了当前AI辅助编程的边界它是一位强大的“实习生”可以快速完成定义清晰的、模式化的任务比如生成样板代码、解释错误、提供标准算法实现。但它不是“架构师”或“产品经理”无法理解复杂的业务上下文无法做出有创意的设计决策更无法替代开发者对项目整体的把握和深度思考。对于想要尝试类似趣味项目的开发者我的建议是大胆地用AI帮你跳过那些枯燥的起步阶段但务必亲手握住方向盘驶向你自己定义的终点。你可以用同样的模式去构建“DogGPT”只会回答“汪”、“PirateGPT”用海盗黑话回答或者任何能结合你的兴趣和一点简单编程逻辑的想法。重点不在于技术的复杂性而在于创意和完整的实现体验。最后关于项目本身所有的代码都已开源在GitHub上遵循CC BY 4.0协议。这意味着你可以随意查看、复制、修改它甚至用它来构建你自己的版本。如果你也做了一个欢迎告诉我——毕竟互联网上多几只这样“不务正业”的电子宠物或许会更有趣一些。