关注【索引目录】服务号,更多精彩内容等你来探索!
还记得微软画图吗?就是那个Windows 95时代的经典软件,你曾经花上几个小时画火柴人,用油漆桶工具填充各种形状?好吧,我刚刚做了一个像素级完美复刻版……只不过这个版本还拥有人工智能超能力。说真的,Kiro让整个过程比预想的有趣得多。
理念:怀旧与人工智能的碰撞
想象一下:现在是2024年,我盯着我那些现代时尚的设计工具,心想“你知道还缺什么吗?斜面按钮和经典的灰色背景。”于是,我自然而然地决定用React和TypeScript做一个功能齐全的MS Paint克隆版。但这里有个特别之处——我赋予了它人工智能功能。为什么不让人工智能分析你的简笔画,然后礼貌地建议你“考虑给画面增加一些层次感”呢?
结果如何?一个看起来像是从 1995 年穿越而来的网页应用程序,但它可以根据文本生成图像,并像一个自命不凡的艺术学院教授一样点评你的作品。
隆重介绍 Kiro:我的 AI 结对编程伙伴
我本来可能要花好几个星期才能搞明白 Canvas API、调试填充算法,还要努力回忆那些 3D 按钮特效是怎么实现的。但现在,我有了 Kiro 作为我的编程伙伴,说实话,感觉就像有个超级聪明的朋友,永远不厌其烦地回答我的问题。
规范驱动方法
事情变得有趣起来了。Kiro 没有像我平时那样直接埋头写代码(我通常的做法是混乱的),而是帮助我按照规范正确地构建了这个东西。我们最终创建了:
- requirements.md
- 所有“这个东西应该做什么?”之类的东西 - design.md——
“我们该如何建造这个?”蓝图 - tasks.md
- 实际工作分解 - api-documentation.md
- 因为未来的我需要文档
感觉就像有个真正懂编程的项目经理。Kiro会仔细阅读我的需求,然后说:“好的,所以你想要16种工具、一个调色板,还有AI功能?我们来分析一下。”
有趣的部分
构建 Windows 95 用户界面:
我:“我想要那种带3D效果的经典斜面纽扣。”
Kiro:生成带有内嵌阴影和多色边框的完美 CSS
我:“我的天,就是这样!”
最棒的是什么?Kiro 完全理解了我想要的风格。我只要说“让它看起来像 Windows 95”,它就能完美地还原灰色背景、斜角边缘,甚至连字体选择都一模一样。它就像也拥有一个充满怀旧情怀的童年。
画布绘图逻辑:
在 HTML5 Canvas 上绘图可能……很麻烦。你需要处理鼠标事件、坐标追踪,以及各种行为不同的工具。我尤其担心填充算法(任何实现过这种算法的人都知道有多痛苦)。
我:“我需要一个不会导致浏览器崩溃的填充函数。”
Kiro:提供了一种基于栈而非递归的优化算法。
我:“你真是把我从 Stack Overflow 的地狱里救了出来!”
人工智能集成:
事情从这里开始变得棘手。我想要三个人工智能功能:
-
文本转图像生成(“画一只猫”) -
艺术作品分析(“你觉得我的画怎么样?”) -
一个有用的聊天机器人
Kiro帮我搭建了整个后端代理,集成了NVIDIA的API,并处理了流式响应。我们只用了一个小时就从“我有一个API密钥”变成了“我有一个可以正常运行的AI聊天机器人”。
最酷的是什么?Kiro 帮我实现了自然语言命令识别功能。所以用户可以说“给我画个日落”、“生成一个机器人”或者“创作抽象艺术”,它都能正常运行。无需任何复杂的命令语法。
发展流程
以下是一次典型的会议流程:
我: “我需要添加喷枪工具”
Kiro: “好的,我们把它添加到工具配置中,用随机喷射粒子实现绘图逻辑,并添加测试。”
五分钟后,喷枪开始工作了。
我: “聊天机器人应该能够检测到用户何时想要生成图像。”
Kiro: “这是一个正则表达式模式匹配器,可以处理各种格式的‘draw’、‘generate’、‘create’和‘make’命令。”
砰,搞定
这就像有一个编程伙伴,他非常擅长枯燥的部分(比如 TypeScript 类型),但也会对有趣的部分感到兴奋(比如 AI 生成的图像出现在你的画布上!)。
基于属性的测试启示
Kiro 向我介绍了基于属性的测试方法,并使用了 fast-check,我现在有点着迷了。与其写:
test('pencil draws a line', () => {
// Test one specific case
});
我们写道:
test('pencil draws correctly for ANY coordinates', () => {
// Test 100+ random cases automatically
});
这就像有一个QA团队,他们会用各种奇思妙想来测试你的代码。Kiro还详细解释了每个属性测试的重要性。
那些让我开怀大笑的瞬间
Clippy事件
好,我们来聊聊 Clippy。你还记得 Clippy 吧?就是微软 Office 里那个热情过头的回形针,明明你根本没在写信,它却会突然跳出来,说“看起来你好像在写信!”?
好吧,我不可能开发一款Windows 95时代的应用程序而不加入每个人最喜欢(或者说最烦人)的办公助手。但有趣的地方就在这里。
我: “我应该把 Clippy 添加到聊天机器人里吗?”
Kiro: “当然。但为什么只买一个 Clippy 呢?”
我: “……继续”
Kiro: “根据上下文赋予 Clippy 不同的性格”
就这样,我们最终得到了五种不同的 Clippy 变体,每一种都有其独特的风格:
🎃 万圣节回形针- 万圣节前后出现,可能会教你画南瓜灯和幽灵的技巧。它拥有那种“派对达人”的能量,只不过是以回形针的形式呈现。
🔬 科学家 Clippy - 戴着一副小眼镜(没错,就是一副眼镜的回形针)。当你做技术性工作时,它就会出现。它可能会极其详细地解释填充算法。“实际上,它是对颜色值匹配的相邻像素进行广度优先搜索……”
🎓 Clippy 老师——耐心十足。会在新手引导环节出现。即使你第五次点错工具,她也不会责怪你。“没关系!我们再试一次!” 能量:像喝了三杯咖啡的幼儿园老师。
🧙 巫师 Clippy——神秘莫测的那位。人工智能功能激活时出现。可能精通魔法(或者至少会机器学习)。浑身散发着“我见过你难以置信的事”的气息。绝对是最酷的 Clippy。
📎 经典 Clippy - 元老级人物。轻松自在,乐于助人。我们都熟悉且……能够接受的 Clippy 基本能量?
Clippy人格系统
事情是这样的——Kiro 帮我实现了一个系统,在这个系统中,Clippy 的性格会根据你正在做的事情而改变:
-
绘图工具?经典 Clippy 出现并提供基本提示 -
AI图像生成?魔法师Clippy带着神秘智慧现身。 -
还在学习使用界面吗?Clippy老师会耐心指导你。 -
十月?万圣节剪纸小精灵就在那里……吓唬人。 -
问技术问题?科学家 Clippy 正在调整他们的小眼镜。
最棒的是什么?每个角色都有略微不同的对话模式。巫师 Clippy 会说“看!人工智能已经生成了你的图像!”,而科学家 Clippy 则会说“图像生成完成。神经网络已成功处理您的提示。”
性格测试:
开发过程中最有趣的部分就是测试所有 Clippy 的变体。我会生成一张图片,然后 Wizard Clippy 就会弹出一条消息:“你的艺术构想已经实现!” 我就会说:“Kiro,这太完美了。”
然后我转而问一个技术问题,科学家 Clippy 就会出现,说“让我来解释一下 Canvas API 的坐标系”,然后我就想“好吧,这个回形针比我懂得多”。
万圣节小精灵Clippy会在十月出现,让一切都变得有点诡异。“嘘!想画南瓜吗?” 好啊,万圣节小精灵。我当然想。
为什么要使用多个 Clippy?
我: “五个 Clippy 是不是太多了?”
Kiro: “Clippy 会太多吗?”
我: “……有道理”
既然要拥抱复古美学,那就干脆做到极致。让 Clippy 根据情境变换性格,会让整个体验更有趣。这就像拥有一个既是聊天机器人又是方法派演员一样。
此外,这也给了我们一个创作不同 Clippy 素材的理由。每个 Clippy 都有自己独特的小服装或配饰。巫师 Clippy 戴着一顶小帽子。科学家 Clippy 戴着眼镜。万圣节 Clippy 则……有点吓人?它其实就是一个回形针,我们只能用手头现有的材料来制作。
Clippy 的彩蛋
我们还添加了一些有趣的互动功能:
-
多次点击 Clippy,它会生气:“我在帮忙!别戳我!” -
问问 Clippy 自己是什么样的人:“我是一枚有梦想和抱负的回形针” -
让 Clippy 离开:它会缩小,但会留下一个小角落可见,就像“如果你需要我,我仍然在这里” -
生成一张非常奇怪的图片:巫师 Clippy:“连我都没料到会这样”
个性化系统让 Clippy 不再像个烦人的弹窗,而更像是一个古灵精怪的伙伴。这正是你对一款具备人工智能功能的复古绘画应用所期待的。
状态栏:
我:“我希望状态栏中显示实时鼠标坐标”
Kiro:“很简单。另外,你想显示画布尺寸和工具信息吗?”
我:“……好的,谢谢。”
现在状态栏会显示所有信息,就像原版一样。细节决定成败。
人工智能艺术评论:
测试视觉分析功能真是太搞笑了。我画的都是些糟糕的火柴人,人工智能却会礼貌地指出“构图很有潜力”和“可以考虑添加更多细节来增强视觉趣味”。这就像拥有一个更圆滑的人工智能版鲍勃·罗斯。
我学到了什么
1. 规格参数确实有用
我以前觉得编写技术规范是枯燥乏味的公事。但有了这些文档,即使休息一段时间后,我也能迅速回到项目中,并且清楚地知道自己之前的工作进度。Kiro 让编写技术规范不再像做作业,而更像是和朋友一起规划一个很棒的项目。
2. 人工智能结对编程有所不同
Kiro 不仅仅是功能强大的自动补全工具。它更像是……一位非常有耐心的高级开发人员,他:
-
记住整个代码库 -
提出了更好的方法 -
编写测试用例时从不抱怨。 -
解释事物运作的原理,而不仅仅是运作方式。
3. 合适的工具至关重要
使用 Vite、React 19、TypeScript 和现代测试工具让一切都变得更加顺畅。而且 Kiro 深谙每项工具的最佳实践。再也不用在凌晨两点搜索“如何配置 Vitest”了。
最终产品
最后我们得到了什么结果?
- 16 种绘图工具
(铅笔、画笔、喷枪、形状、填充桶等) - 28色调色板
(经典的MS Paint颜色) - 像素级完美的 Windows 95 用户界面
(包括斜面按钮等所有细节) - AI文本转图像生成
(输入“画一只猫”,即可得到一只猫) - AI艺术作品分析
(获取关于您杰作的反馈) - 智能聊天机器人
(回答有关工具和技术的问题) - 基于属性的测试
(因为我们就是这么讲究)
整个程序都在浏览器中运行,界面看起来像1995年的样子,但却拥有2024年的人工智能能力。真是美妙的混乱。
自己动手试试
代码都在这里了。您可以:
-
克隆仓库 -
获取免费的 NVIDIA API 密钥 -
跑步 npm run dev -
画一些糟糕的火柴人,然后让人工智能礼貌地评价它们。
Kiro 的独特之处
我以前也用过人工智能编程工具。但Kiro给我的感觉不一样,因为:
- 它理解上下文
——不仅是当前文件,而是整个项目结构 - 它提出了更好的方法
——“嘿,你可以在这里使用引用(ref)”。 - 它编写了真正的文档
——不仅仅是代码注释,而是真正的文档。 - 它对架构设计很有帮助
——不仅仅是实现细节。 - 它让测试变得有趣
——基于属性的测试真的很酷!
如果靠我一个人完成这个项目,可能要花好几周时间。有了 Kiro 呢?几天就能享受到编程的乐趣。
要点总结
我很高兴自己做出了能让我开心的东西。
如果你正在开发某个东西,并且觉得“这得花好长时间”,不妨试试 Kiro。它有点像结对编程,只不过你的搭档是:
-
从不需要喝咖啡休息 -
不会对你的代码进行太多评判 -
实际上很喜欢编写测试题 -
让枯燥的部分变得不那么枯燥
此外,你最终可能会得到一款复古风格的绘图应用,它可以生成戴着巫师帽的猫咪图像。而这不正是我们真正想要的吗?
使用以下技术构建: React、TypeScript、Vite、NVIDIA AI、怀旧情怀和 Kiro
节省时间:大概几周
制作的斜面按钮:数不胜数
绘制的火柴人:数不胜数
MS Paint 克隆版 - 架构图
┌─────────────────────────────────────────────────────────────────────────────────┐
│ FRONTEND │
│ React 19.2 + TypeScript + Vite │
└─────────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────┐
│ USER INTERFACE LAYER │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ TitleBar │ │ MenuBar │ │ ThemeToggle │ │ StatusBar │ │
│ │ Component │ │ Component │ │ Component │ │ Component │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ App.tsx (Root) │ │
│ │ ┌──────────────────────────────────────────────────────────────┐ │ │
│ │ │ State Management: │ │ │
│ │ │ • selectedTool, selectedColor, theme │ │ │
│ │ │ • isChatbotOpen, isGeneratingImage │ │ │
│ │ │ • mousePos, canvasSize, showTour │ │ │
│ │ └──────────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────┐
│ DRAWING COMPONENTS │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌─────────────────────────────────────┐ │
│ │ Toolbar │ │ Canvas.tsx │ │
│ │ Component │ │ ┌───────────────────────────────┐ │ │
│ │ │ │ │ HTML5 Canvas API │ │ │
│ │ 16 Tools: │────────▶│ │ • Drawing Context │ │ │
│ │ • Pencil │ │ │ • Mouse Event Handlers │ │ │
│ │ • Brush │ │ │ • Tool Implementations │ │ │
│ │ • Airbrush │ │ └───────────────────────────────┘ │ │
│ │ • Eraser │ │ │ │
│ │ • Fill Bucket │ │ Exposed Methods (via ref): │ │
│ │ • Line │ │ • clear() │ │
│ │ • Rectangle │ │ • getCanvasImage() │ │
│ │ • Ellipse │ │ • drawImageOnCanvas() │ │
│ │ • etc... │ │ │ │
│ └──────────────────┘ └─────────────────────────────────────┘ │
│ │
│ ┌──────────────────┐ │
│ │ ColorPalette │ │
│ │ Component │ │
│ │ │ │
│ │ 28 Colors: │ │
│ │ 14×2 Grid │ │
│ └──────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────┐
│ AI COMPONENTS │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌─────────────────────────────────────┐ │
│ │ ChatbotWidget │ │ ChatbotPopup.tsx │ │
│ │ Component │────────▶│ ┌───────────────────────────────┐ │ │
│ │ │ │ │ Command Detection: │ │ │
│ │ 💬 Button │ │ │ • isDrawCommand() │ │ │
│ │ (Bottom-right) │ │ │ • isDrawingRelatedQuestion() │ │ │
│ └──────────────────┘ │ └───────────────────────────────┘ │ │
│ │ │ │
│ │ Message History: │ │
│ │ • User messages │ │
│ │ • Bot responses (streaming) │ │
│ │ • System notifications │ │
│ └─────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
│
│ HTTP Requests
▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│ BACKEND │
│ Express.js 5.1 + Node.js │
└─────────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────┐
│ API ENDPOINTS │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ POST /api/chat │ │
│ │ ┌──────────────────────────────────────────────────────────┐ │ │
│ │ │ Input: │ │ │
│ │ │ • messages: Array<{role, content}> │ │ │
│ │ │ • image?: base64 PNG (optional) │ │ │
│ │ │ │ │ │
│ │ │ Logic: │ │ │
│ │ │ • Detect if image present │ │ │
│ │ │ • Select model (vision vs text) │ │ │
│ │ │ • Format multi-modal message if needed │ │ │
│ │ │ • Stream response via SSE │ │ │
│ │ │ │ │ │
│ │ │ Output: Server-Sent Events (streaming text) │ │ │
│ │ └──────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ POST /api/generate-image │ │
│ │ ┌──────────────────────────────────────────────────────────┐ │ │
│ │ │ Input: │ │ │
│ │ │ • prompt: string │ │ │
│ │ │ │ │ │
│ │ │ Logic: │ │ │
│ │ │ • Validate prompt │ │ │
│ │ │ • Call NVIDIA SDXL API │ │ │
│ │ │ • Extract base64 image │ │ │
│ │ │ • Return to frontend │ │ │
│ │ │ │ │ │
│ │ │ Output: { image: base64_png } │ │ │
│ │ └──────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ Middleware: │ │
│ │ • CORS (allow frontend origin) │ │
│ │ • express.json() (parse JSON bodies) │ │
│ │ • Error handling │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
│
│ HTTPS + Bearer Token
▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│ NVIDIA API PLATFORM │
└─────────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────┐
│ AI MODELS │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ meta/llama-3.2-11b-vision-instruct │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │
│ │ │ Purpose: Artwork analysis & vision tasks │ │ │
│ │ │ Input: Text + Image (multi-modal) │ │ │
│ │ │ Output: Streaming text response │ │ │
│ │ │ Speed: 2-5 seconds │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ openai/gpt-oss-120b │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │
│ │ │ Purpose: Text chat & general assistance │ │ │
│ │ │ Input: Text messages only │ │ │
│ │ │ Output: Streaming text response │ │ │
│ │ │ Speed: 1-3 seconds │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ stabilityai/stable-diffusion-xl │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │
│ │ │ Purpose: Text-to-image generation │ │ │
│ │ │ Input: Text prompt + parameters │ │ │
│ │ │ Output: 1024×1024 PNG (base64) │ │ │
│ │ │ Speed: 10-30 seconds │ │ │
│ │ │ Parameters: │ │ │
│ │ │ • cfg_scale: 7 │ │ │
│ │ │ • steps: 30 │ │ │
│ │ │ • seed: 0 (random) │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────┐
│ DATA FLOW EXAMPLES │
└─────────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────┐
│ TEXT-TO-IMAGE GENERATION FLOW │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ User types "draw a cat" │
│ │ │
│ ▼ │
│ ChatbotPopup.isDrawCommand() → { isDraw: true, prompt: "a cat" } │
│ │ │
│ ▼ │
│ App.handleGenerateImage("a cat") │
│ │ │
│ ▼ │
│ POST /api/generate-image { prompt: "a cat" } │
│ │ │
│ ▼ │
│ Server → NVIDIA SDXL API │
│ │ │
│ ▼ │
│ NVIDIA generates 1024×1024 PNG (10-30s) │
│ │ │
│ ▼ │
│ Server returns { image: "base64..." } │
│ │ │
│ ▼ │
│ Canvas.drawImageOnCanvas(base64) │
│ │ │
│ ▼ │
│ Image scaled to 80% canvas width, centered, drawn as pixels │
│ │ │
│ ▼ │
│ User can now edit with any tool │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────┐
│ VISION ANALYSIS FLOW │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ User draws something │
│ │ │
│ ▼ │
│ User types "what do you think?" │
│ │ │
│ ▼ │
│ ChatbotPopup.isDrawingRelatedQuestion() → true │
│ │ │
│ ▼ │
│ Canvas.getCanvasImage() → base64 PNG │
│ │ │
│ ▼ │
│ POST /api/chat { messages: [...], image: "base64..." } │
│ │ │
│ ▼ │
│ Server formats multi-modal message: │
│ { role: "user", content: [ │
│ { type: "text", text: "what do you think?" }, │
│ { type: "image_url", image_url: { url: "data:image/png;base64,..." } } │
│ ]} │
│ │ │
│ ▼ │
│ Server → NVIDIA Vision API (Llama 3.2 Vision) │
│ │ │
│ ▼ │
│ NVIDIA analyzes image (2-5s) │
│ │ │
│ ▼ │
│ Server streams SSE chunks │
│ │ │
│ ▼ │
│ Frontend parses chunks, updates UI in real-time │
│ │ │
│ ▼ │
│ User sees critique: "I can see you've drawn..." │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────┐
│ TECHNOLOGY STACK SUMMARY │
└─────────────────────────────────────────────────────────────────────────────────┘
Frontend: Backend: AI/ML:
• React 19.2 • Express.js 5.1 • NVIDIA API Platform
• TypeScript 5.9 • Node.js • Llama 3.2 Vision (11B)
• Vite 7.2 • CORS • GPT-OSS (120B)
• HTML5 Canvas API • dotenv • Stable Diffusion XL
• Pure CSS (no frameworks)
Testing: Code Quality: Dev Tools:
• Vitest 4.0 • ESLint 9.39 • concurrently
• React Testing Library • TypeScript ESLint • Vite dev server
• fast-check 4.3 • React Hooks rules • Hot reload
• jsdom 27.2
关注【索引目录】服务号,更多精彩内容等你来探索!

