从Claude到ChatGPT:我在Prompt工程里踩过的坑和挖出的金子
回国快一年了,刚从硅谷一家中型SaaS公司裸辞回来。说实话,在那边三年多,每天写代码都得配着Lo-fi Hip Hop或者City Pop——不然总觉得少了点灵魂。现在在国内找下一份工作,一边投简历一边复盘自己过去几年在前端交互、动效上折腾过的东西。最近正好被一个老东家项目拉回去救火,顺手把这段时间在AI辅助开发上的“血泪史”整理出来,权当技术分享,也给自己攒点面试谈资。
起因:产品经理又画了个“会呼吸”的按钮
事情发生在上个月底,临近春节前最后一个迭代。产品小哥拉着我们开需求会,甩出一张Figma设计稿:“这个按钮要‘有生命力’,鼠标hover的时候要有轻微的呼吸感,点击要有反馈涟漪,还要支持无障碍……对了,下周三上线。”
我当时差点把耳机摔了——这不就是个普通按钮吗?结果一看动画曲线,贝塞尔函数参数复杂得像解微分方程,还要求60fps丝滑运行,兼容到IE11(别问,问就是客户还在用)。更离谱的是,团队里没人专门做过这种精细交互动效,设计师给的只是视觉稿,没导出Lottie也没给关键帧逻辑。
Deadline压顶,我脑子里第一个念头是:能不能让AI帮我生成基础代码?
于是,我的Prompt工程踩坑之旅正式开启。
第一坑:以为AI是万能码农,结果它连CSS transition都能写错
我先试了ChatGPT(用的是GPT-4),输入Prompt:
“用纯CSS写一个带呼吸效果的按钮,hover时缓慢放大再缩小,循环播放,支持无障碍focus状态”
结果它给了我一段代码,看起来挺像那么回事:
.pulse-button {
animation: breathe 2s infinite ease-in-out;
}
@keyframes breathe {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}
乍一看没问题,但一跑起来就露馅了——animation在hover时不会暂停!也就是说,鼠标移开后动画还在继续“喘”,完全不符合交互预期。而且focus状态下没有任何视觉反馈,WCAG直接挂掉。
我心想:是不是我Prompt写得太模糊?于是加了约束:
“hover时启动动画,移出停止;focus时加outline;不要使用JS”
这次GPT给了animation-play-state: paused/running的方案,但没处理初始状态,导致页面加载时按钮就在动。更搞笑的是,它建议用outline-offset: -2px来“美化”焦点框——这在深色背景下几乎看不见,测试同学当场翻白眼。
教训一:AI不懂交互上下文,你必须把“什么时候开始、什么时候结束、用户怎么感知”说清楚。
后来我重写了Prompt,明确生命周期:
“默认无动画。仅当:hover或:focus时,启动一个2秒无限循环的scale动画(1 → 1.05 → 1)。移出或blur后立即停止,不留残影。动画必须平滑,且不影响布局流。”
这次终于靠谱了,虽然还是漏了will-change: transform优化,但骨架对了。
第二坑:Claude Code说它懂React,结果Hooks用得像jQuery
不甘心只用ChatGPT,我又去试了Claude 3(Sonnet版本),听说它的Code能力更强。这次我要做一个带进度条的加载动效组件,支持自定义颜色、持续时间、回调。
我给的Prompt是:
“用React函数组件写一个CircularProgress组件,props包括size, color, duration, onComplete。用requestAnimationFrame驱动,不要用setTimeout。”
Claude回了一大段代码,开头是这样的:
import { useState, useEffect } from 'react';
export default function CircularProgress({ size = 40, color = '#3b82f6', duration = 2000, onComplete }) {
const [progress, setProgress] = useState(0);
useEffect(() => {
let start;
const animate = (timestamp) => {
if (!start) start = timestamp;
const elapsed = timestamp - start;
const percent = Math.min(elapsed / duration, 1);
setProgress(percent);
if (percent < 1) {
requestAnimationFrame(animate);
} else {
onComplete?.();
}
};
const id = requestAnimationFrame(animate);
return () => cancelAnimationFrame(id);
}, [duration, onComplete]);
// ...render logic
}
看起来挺专业?问题出在useEffect依赖数组——它没包含onComplete的引用变化!如果父组件传的是内联函数(比如() => console.log('done')),每次渲染都会触发effect重新执行,导致动画疯狂重启。典型的闭包陷阱。
更离谱的是,它在render里直接用了style={{ stroke: color }},但没考虑SSR场景——服务端没有window对象,某些构建工具会报错。
我吐槽给同事听,他说:“你指望AI写出生产级代码?它连useCallback都不知道要提醒你!”
教训二:AI生成的React代码,90%需要手动补全依赖数组和边界case。别信它的“最佳实践”标签。
后来我改用更结构化的Prompt:
“写React CircularProgress组件,注意:
- 使用useRef存储animationId
- onComplete必须用useCallback包裹后再传入,避免effect重复触发
- 支持SSR(不能假设window存在)
- 提供TypeScript类型定义”
这次Claude给出了接近可用的代码,虽然TS类型里漏了onComplete?: () => void的可选标记,但至少骨架健壮多了。
第三坑:Prompt越长越好?结果AI开始“脑补”不存在的需求
有一次我想用AI生成一个粒子背景动画,参考Three.js但希望轻量。我写了个超详细Prompt:
“用Canvas实现一个低CPU占用的粒子系统,粒子从屏幕中心发射,随机方向,带淡出效果。最多200个粒子,FPS不低于50。支持暂停/恢复API。不要外部依赖。提供init、start、stop方法。”
结果ChatGPT不仅实现了粒子系统,还“贴心”地加了鼠标跟随交互、粒子碰撞检测、甚至Web Worker分片渲染——这些我根本没要!代码膨胀到300行,性能反而因为过度设计而下降。
最气人的是,它用了一个全局变量particles,导致如果页面上有两个实例会互相干扰。我问它为什么加碰撞检测,它回:“用户通常希望粒子有物理感。” —— 我当时就想回:“用户只想要个背景动画,不是做游戏引擎!”
教训三:AI喜欢“过度服务”。明确说“不要XXX”比说“要XXX”更重要。
后来我学乖了,在Prompt结尾加上:
禁止添加未提及的功能。不要假设用户需要额外交互。保持代码极简。
效果立竿见影。
对比实测:ChatGPT vs Claude Code 到底谁更适合前端?
为了搞清楚哪个工具更值得投入时间,我做了个小对比实验。用同样的Prompt让两者生成一个“拖拽排序列表”组件(支持touch和mouse)。
| 维度 | ChatGPT (GPT-4) | Claude 3 Sonnet |
|---|---|---|
| 代码长度 | 180行 | 150行 |
| 是否处理touch事件 | 是(但没防抖) | 是(带touch-action: none) |
| 性能优化 | 用了transform | 用了transform + will-change |
| 错误处理 | 无 | 有try-catch包裹drag逻辑 |
| TS支持 | 需手动加 | 默认输出TS版本 |
| 可读性 | 注释较多 | 逻辑更紧凑 |
结论:Claude在工程严谨性上略胜一筹,ChatGPT在解释思路上更友好。 如果赶时间看逻辑,用GPT;如果要直接集成,Claude更省心。
不过两家都有通病:对CSS Grid/Flex细节掌握一般,经常写出justify-content: space-around却忘了容器要设display: flex。
我的Prompt工程实战技巧(血泪总结)
经过几十次翻车,我总结了几条保命原则:
角色扮演法:告诉AI“你现在是一个资深前端工程师,正在review新人代码”,它会自动提高标准。
你是一个有5年前端经验的工程师,请严格检查以下代码的性能、可访问性和兼容性问题...负面约束清单:明确列出“不要什么”。
不要使用jQuery风格的DOM操作;不要内联样式;不要假设浏览器支持IntersectionObserver...分步生成:别指望一次出完整方案。先要架构,再要细节。
第一步:列出实现呼吸按钮的三种技术方案(CSS/JS/Web Animations API),对比优劣 第二步:基于CSS方案,写出完整代码示例驱动:给一段错误代码,让它修正。
以下代码在hover移出后动画不停止,请修复: .btn { animation: pulse 1s infinite; }上下文锚定:绑定你的技术栈。
我们项目用React 18 + TypeScript + Tailwind CSS,请基于此生成代码
现在回头看:AI不是银弹,但能让你少加班
上周终于把那个“会呼吸”的按钮上线了。最后方案其实很简单:用CSS :hover 和 :focus 触发动画,配合animation-play-state控制启停,加上prefers-reduced-motion适配无障碍。核心代码不到20行。
但如果没有AI帮我快速排除错误路径(比如一开始想用JS轮询),我可能得花两倍时间调试。它像个有点呆但很勤奋的实习生——你得手把手教,但它能帮你搬砖、查文档、写初稿。
回国找工作这段时间,我发现很多国内团队对AI coding工具还停留在“玩具”阶段。其实只要Prompt写对,它真能提升交付效率,尤其是在做那些重复性高、文档不全的交互组件时。
当然,千万别把它当主力开发——毕竟,线上bug不会因为“这是AI写的”就放过你。上周五晚上运维群里@我:“首页按钮动画卡顿,用户投诉了”,我第一反应还是打开DevTools手动调,而不是再去问ChatGPT。
写这篇文章时,我正戴着耳机听YMO的《Rydeen》,窗外是上海阴晴不定的春天。三年海外经历让我习惯了用工具提效,但回国后发现,很多团队还在靠“人肉堆需求”。或许这就是我想找的新机会:既能发挥我在交互动效上的积累,又能推动工程效能升级的地方。
如果你也在探索AI辅助开发,欢迎交流踩坑经验。毕竟,程序员的浪漫,就是把别人的坑变成自己的梯子。
(完)
P.S. 投简历的朋友,我司急招前端,要求会调CSS动画、不怕和产品battle、接受偶尔用AI但绝不甩锅给AI——有兴趣私聊!

评论 0