Claude Code实战:从零构建会断电自救的赛博城市 用 Claude 现场从零生成一个会断电自救的赛博城市从提示词到可运行 HTML 的完整实践最近很多开发者在讨论用 Claude 生成网页项目从商品落地页、个人主页到各种小游戏确实“能生成”和“生成得好”之间差别非常大。大部分演示视频里AI 只是生成了一张静态画面节奏一到就停下来真正有价值的是让 AI 生成一个“有系统行为”的页面——不是画一张赛博朋克风格的图而是一个会运转、会响应事件、有内部状态的城市模拟器。这篇文章要分享的就是一条完整的实操路径用 Claude 从零生成一个单文件 HTML 赛博城市并且这个城市具备“断电自救”的能力。所谓断电自救不是简单地把灯熄灭再亮起来而是要让城市内部有一套电力管理系统检测断电事件、按优先级调度备用电源、分批恢复关键设施供电。整座城市会“活着”——灯火会流动、大楼会闪烁、断电时会有自己的应急反应。这背后真正的技术变化是 Claude Code 这类终端 AI 编程工具把“想法到可运行原型”的转换成本压到了很低的程度。过去手写这样一个项目至少需要半天到一天要处理 Canvas 绘制、动画循环、状态管理等一堆细节现在用 Claude Code可以在命令行里通过对话逐步完成。但这条路线也有不少坑提示词怎么写、生成后怎么审阅、断电逻辑怎么调、安装过程会遇到什么报错很多新手都是卡在这些地方。读完这篇文章你会得到三样东西第一一套完整的 Claude Code 环境搭建和配置方法包括常见的安装问题排查。 第二一份可以直接复制的赛博城市提示词模板以及 Claude 生成代码后的审阅思路。 第三一个具备断电自救机制的 HTML 单页项目实现能直接运行和扩展。如果你正打算用 AI 生成复杂网页项目或者已经试过但效果不理想这篇文章应该能帮你少走不少弯路。1. 为什么用 Claude 生成一个“会自救”的赛博城市先问一个更底层的问题网页版的 Claude 和很多在线 AI 工具已经能生成 HTML 页面为什么还要专门用 Claude Code 在终端里做这件事原因在于项目复杂度。一个赛博城市长什么样和它如何运转是两个难度级别完全不同的事。如果只是让 Claude 生成一个赛博城市页面它很可能给你一个带霓虹灯的静态页面背景是深紫色渐变中间是几栋发光的建筑剪影灯是 CSS 动画在闪烁。视觉效果不错但没有任何系统逻辑。页面打开后是固定的用户没法干预城市也不会对任何事件做出反应。但“断电自救”这个需求直接把项目从“视觉实现”拉到了“系统模拟”的层级。它要求页面具备几个关键能力城市里有多个建筑每个建筑都有电力状态、用电量、优先级和备用电池容量。城市正常运行时电网统一供电所有建筑正常发光。某个时刻触发断电事件电网停止供电建筑灯光开始变化。系统按优先级启动备用电源关键设施优先恢复非关键设施延迟恢复或降载运行。整个过程中画面要有持续的动画反馈让用户能直观看到电力调度过程。这些逻辑加起来意味着页面里需要有一组数据结构、一个状态机、一个调度算法以及一个持续运行的渲染循环。这不是一句提示词能一次搞定的需要分步骤、分模块地让 AI 生成更需要你去理解、调整和验证。这正是 Claude Code 擅长的地方。与网页版对话相比Claude Code 直接跑在你本地的工作目录里能读取和编辑真实文件能运行命令查看结果能配合 Git 做版本管理。你可以在这个文件里不断迭代每次只让 AI 改一个模块然后运行验证再继续下一步。这个工作流更加接近真实的开发过程而不仅仅是一次性的对话式问答。此外Claude Code 还支持 Skill 等扩展机制。Skill 本质上是一种预先定义好的工作流模板你可以把“生成赛博城市项目”写成一份 Skill规定好目录结构、技术选型和代码风格之后每次生成都复用同一套标准。对于需要重复创建项目的团队来说这个机制很值得研究。关于 Claude 是不是“没有灵感”我的判断是对于这种小型创意项目它完全够用。真正决定项目质量的不是 AI 的能力上限而是你的提示词质量和工程素养。2. Claude Code 是什么以及它和网页版 Claude 的区别很多朋友对 Claude 的认知停留在网页聊天窗口。实际上Claude 生态系统里有一整套开发工具其中和程序员关系最近的就是 Claude Code。Claude Code 是 Anthropic 推出的终端编程助手。它以命令行工具的形式运行可以直接在项目目录中工作。你可以让它读取文件、修改代码、执行命令、运行测试甚至让它自己提交 Git commit。它和网页版的区别可以参考这个表格维度网页版 ClaudeClaude Code使用场景问答、文档总结、一次性代码生成多文件项目迭代、终端工作流、本地代码修改文件访问需要手动上传可以直接读取工作目录中的文件命令执行不支持支持执行终端命令工作方式单轮或多轮对话可以持续迭代、增量修改适合项目小型脚本、单文件页面中大型项目、需要反复调优的开发任务对赛博城市这类项目来说网页版 Claude 也能生成但迭代体验完全不同。你用网页版生成一个单文件 HTML如果后续想调整断电逻辑需要复制粘贴整段代码重新提问非常痛苦。用 Claude Code直接说“把医院建筑的备用电池容量提高一倍”它就会精准地修改对应代码行改完你立刻运行看效果。另一种常见使用方式是在 VSCode 中配置 Claude Code。在 VSCode 的终端里启动 Claude Code左边是编辑器右边是 AI 对话窗口改代码的同时可以直接观察文件变化。对于 HTML 页面这种需要频繁预览效果的项目这种配置体验很好。需要说明的是Claude Code 是一个相对新的工具它的安装方式、配置项和可用模型会随版本更新而变化。这篇文章重点演示通用思路具体版本号请以实际安装时为准。3. 环境准备安装与配置 Claude Code这一步我们解决一个核心问题把 Claude Code 装好、跑起来、能访问你的项目目录。3.1 前置条件Claude Code 依赖 Node.js 运行环境因此需要先确认本机已经安装 Node.js 和 npm。在终端中执行node --version npm --version如果提示找不到命令需要先安装 Node.js。安装完成后建议重新打开终端再执行一次确保 PATH 已生效。另外需要确保本机网络能够正常访问相关服务。这里不展开具体网络细节但提醒一句使用 Claude 相关服务前请确认你的网络环境和账号使用方式符合服务条款和当地法律要求。3.2 安装 Claude CodeClaude Code 的安装方式主要是通过 npm 全局安装。在终端执行npm install -g anthropic-ai/claude-code安装完成后在任意目录执行claude首次运行会进入初始化流程。通常会要求你登录 Claude 账号并授权按照终端提示完成即可。这个授权是为了让 Claude Code 能以你的身份调用模型服务。安装过程中有几个常见报错这里提前说明后面还会在常见问题章节详细展开。第一个是error: claude native binary not installed. either postinstall did not run...。这个问题通常出现在 npm 包安装不完整的时候可能原因包括网络中断、npm 缓存问题或安装权限不足。常见的处理方法是删除全局 node_modules 中的相关目录后重新安装npm uninstall -g anthropic-ai/claude-code npm cache clean --force npm install -g anthropic-ai/claude-code第二个是账号或组织层面的限制。有些用户会看到类似your organization has disabled claude subscription access for claude code的提示这说明当前账号所属的组织在管理后台关闭了 Claude Code 的订阅访问权限。这种情况需要联系组织管理员开通或者使用个人账号。第三个是模型版本不识别。Claude Code 对模型名称有版本要求如果你在配置中填入了它不认识的模型名会报错。解决方法是在配置中使用官方支持的模型标识。3.3 在 VSCode 中使用 Claude Code如果你习惯在编辑器里工作可以在 VSCode 的终端中直接启动 Claude Code。打开你的项目目录在 VSCode 内置终端里执行claudeClaude Code 会自动识别当前工作目录后续生成的文件都会放在这个目录下。注意建议把 Claude Code 放在一个独立的 Git 仓库中方便追踪每一步改动。如果项目被 AI 改坏了随时可以回滚。3.4 创建项目目录在正式生成赛博城市之前先建一个干净的项目目录mkdir cyber-city cd cyber-city git init claude这样做的原因是Claude Code 会在当前目录生成文件如果目录里已有其他项目AI 可能会错误地读取和修改无关文件。独立目录能隔离风险也方便测试。4. 赛博城市架构设计一开始就要想清楚系统这一步最容易被忽略。很多人一上来就让 Claude “生成一个赛博城市”结果 AI 返回一个结构混乱的页面改起来很痛苦。正确做法是先想清楚这个城市的技术架构再让 AI 照着架构实现。我们把赛博城市拆成四个模块4.1 建筑实体层每个建筑都是一组数据对象包含以下属性属性含义示例值id建筑唯一标识hospital-01name建筑名称中央医院type建筑类型hospital / residential / commercial />请用 HTML CSS JavaScript 在单个 HTML 文件中实现一个赛博朋克风格的动态城市模拟器要求如下 1. 使用 Canvas 绘制整座城市城市中包含至少 12 栋建筑建筑类型包括医院、数据中心、住宅楼、商业楼、警察局。 2. 每栋建筑都是一个 JavaScript 对象包含以下属性id、name、type、x、y、width、height、priority、powerUsage、batteryCapacity、batteryLevel、status。 3. 城市有一个电网系统正常运行状态下所有建筑由电网供电建筑灯光正常显示。 4. 实现一个全局函数 triggerBlackout()调用后电网停电建筑灯光按调度策略变化 - 优先级为 1 的建筑如医院优先切换备用电池灯光保持明亮但颜色变为绿色。 - 优先级为 2 的建筑如数据中心切换备用电池灯光保持蓝色。 - 优先级为 3 及以上的建筑如住宅、商业在电池电量耗尽后灯光熄灭。 5. 实现一个全局函数 restorePower()调用后电网恢复供电所有建筑恢复正常灯光。 6. 页面底部显示一个控制面板包含两个按钮“触发断电” 和 “恢复供电”。 7. 使用 requestAnimationFrame 实现动画循环每帧更新电池电量并重绘画面。 8. 视觉风格深紫色夜空背景建筑使用霓虹灯配色夜空中添加星星和流动的云层。 9. 在画面左上角显示当前城市电力状态包括电网状态和总电池电量。 10. 代码需要完整可运行不要省略关键逻辑。这段提示词看起来很长但每一项都是在约束 AI 的行为。特别是第 4 条它明确规定了断电后的表现方式——不同优先级建筑的灯光变化不同这是“自救”机制的核心。生成代码后不要直接运行就结束。先让 Claude 解释它的设计思路请解释以下内容 1. triggerBlackout() 函数内部如何分配备用电源 2. 如果电池电量不足会发生什么 3. 动画循环每帧执行了哪些计算这一步非常重要。AI 生成的代码不一定符合你的预期让它解释逻辑能帮你快速发现理解偏差。如果发现调度逻辑不对直接让它修改当前调度逻辑是按顺序分配电量我希望改成电池电量按优先级动态分配如果优先级为 1 的建筑电量不足可以从优先级为 2 的建筑借电。请修改 triggerBlackout() 函数。这种迭代式开发是 AI 编程工具相比传统搜索引擎最大的优势。6. 核心代码实现HTML、CSS 与 JavaScript这一节我们直接进入代码实现。考虑到可读性我会把完整的赛博城市拆成三个部分来展示HTML 骨架、CSS 样式、JavaScript 核心逻辑。最终你可以把它们合并成一个index.html文件运行。6.1 HTML 骨架!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title赛博城市 - 断电自救模拟器/title style /* CSS 样式见 6.2 */ /style /head body div idcity-container canvas idcityCanvas width900 height600/canvas div idstatus-panel div classstatus-item span classlabel电网状态/span span idgridStatus classvalue正常/span /div div classstatus-item span classlabel总电池电量/span span idbatteryTotal classvalue100%/span /div /div div idcontrol-panel button idblackoutBtn onclicktriggerBlackout()触发断电/button button idrestoreBtn onclickrestorePower()恢复供电/button /div /div script // JavaScript 逻辑见 6.3 和 6.4 /script /body /html这段骨架定义了三块区域#cityCanvasCanvas 画布城市就在这块画布上绘制。#status-panel左上角的电力状态面板展示电网状态和总电池电量。#control-panel底部控制按钮用来触发断电和恢复供电。6.2 CSS 样式* { margin: 0; padding: 0; box-sizing: border-box; } body { background: #0a0015; font-family: Courier New, monospace; display: flex; justify-content: center; align-items: center; min-height: 100vh; } #city-container { position: relative; width: 900px; height: 600px; border: 2px solid #ff00ff; box-shadow: 0 0 20px #ff00ff66, 0 0 40px #00ffff44; border-radius: 8px; overflow: hidden; } #cityCanvas { display: block; background: linear-gradient(to bottom, #0a0015 0%, #1a0033 50%, #0d002b 100%); } #status-panel { position: absolute; top: 15px; left: 15px; background: rgba(10, 0, 20, 0.8); border: 1px solid #00ffff; border-radius: 6px; padding: 10px 16px; color: #00ffff; font-size: 14px; } .status-item { margin-bottom: 4px; } .value { font-weight: bold; } #control-panel { position: absolute; bottom: 15px; left: 50%; transform: translateX(-50%); display: flex; gap: 12px; } #control-panel button { padding: 8px 20px; background: transparent; border: 1px solid #ff00ff; border-radius: 4px; color: #ff00ff; font-family: Courier New, monospace; font-size: 14px; cursor: pointer; transition: all 0.3s; } #control-panel button:hover { background: #ff00ff22; box-shadow: 0 0 10px #ff00ff; }这套样式做了几件事让页面背景变深紫营造赛博朋克氛围给 Canvas 容器加上霓虹边框把状态面板放在左上角把控制按钮放在底部居中。按钮的悬停效果让它看起来更像一个可交互的模拟器。6.3 JavaScript城市数据与渲染循环接下来是核心逻辑。先定义建筑数据结构和城市初始化逻辑。// 文件路径index.html 内 script 标签 const canvas document.getElementById(cityCanvas); const ctx canvas.getContext(2d); const gridStatusEl document.getElementById(gridStatus); const batteryTotalEl document.getElementById(batteryTotal); // 城市状态 let isGridUp true; let blackoutTimer null; // 建筑构造函数 class Building { constructor(building) { this.id building.id; this.name building.name; this.type building.type; this.x building.x; this.y building.y; this.width building.width; this.height building.height; this.priority building.priority; this.powerUsage building.powerUsage; this.batteryCapacity building.batteryCapacity; this.batteryLevel building.batteryCapacity; this.status grid; // grid / battery / off // 颜色配置 this.colors building.colors || { grid: #ffdd00, battery: #00ff88, off: #1a1a2e }; } // 绘制建筑 draw() { let color; if (this.status grid) { color this.colors.grid; } else if (this.status battery) { color this.colors.battery; } else { color this.colors.off; } // 建筑主体 ctx.fillStyle #12122e; ctx.fillRect(this.x, this.y, this.width, this.height); // 建筑灯光 ctx.strokeStyle color; ctx.lineWidth 2; ctx.shadowBlur 15; ctx.shadowColor color; // 绘制窗口简单的网格线表示窗户灯光 const windowRows Math.floor(this.height / 12); const windowCols Math.floor(this.width / 10); for (let row 0; row windowRows; row) { for (let col 0; col windowCols; col) { ctx.fillStyle Math.random() 0.3 ? color : transparent; ctx.fillRect(this.x 4 col * 10, this.y 4 row * 12, 4, 5); } } ctx.shadowBlur 0; } } // 城市建筑列表 const buildings [ new Building({ id: hospital-01, name: 中央医院, type: hospital, x: 100, y: 350, width: 90, height: 140, priority: 1, powerUsage: 120, batteryCapacity: 500, colors: { grid: #00ff88, battery: #00ff88, off: #1a1a2e } }), new Building({ id: data-center-01, name: 数据中心, type: data-center, x: 620, y: 300, width: 100, height: 120, priority: 2, powerUsage: 180, batteryCapacity: 350, colors: { grid: #00ccff, battery: #00ccff, off: #1a1a2e } }), new Building({ id: police-01, name: 警察局, type: police, x: 400, y: 380, width: 80, height: 100, priority: 2, powerUsage: 80, batteryCapacity: 250, colors: { grid: #ff5500, battery: #00ff88, off: #1a1a2e } }), // 住宅楼和商业楼可以按相同方式继续添加 new Building({ id: residential-01, name: 住宅楼, type: residential, x: 220, y: 380, width: 70, height: 110, priority: 3, powerUsage: 60, batteryCapacity: 120, colors: { grid: #ffdd00, battery: #00ff88, off: #1a1a2e } }), new Building({ id: commercial-01, name: 商业大厦, type: commercial, x: 500, y: 320, width: 80, height: 160, priority: 4, powerUsage: 140, batteryCapacity: 150, colors: { grid: #ff00ff, battery: #00ff88, off: #1a1a2e } }) ]; // 绘制夜空背景 function drawSky() { const gradient ctx.createLinearGradient(0, 0, 0, canvas.height); gradient.addColorStop(0, #050010); gradient.addColorStop(0.5, #12002e); gradient.addColorStop(1, #0d002b); ctx.fillStyle gradient; ctx.fillRect(0, 0, canvas.width, canvas.height); // 星星 ctx.fillStyle #ffffff; for (let i 0; i 80; i) { const x Math.random() * canvas.width; const y Math.random() * canvas.height * 0.4; const size Math.random() * 1.5 0.5; ctx.globalAlpha Math.random() * 0.7 0.3; ctx.fillRect(x, y, size, size); } ctx.globalAlpha 1; } // 计算总电池电量 function getTotalBattery() { const total buildings.reduce((sum, b) sum b.batteryLevel, 0); const max buildings.reduce((sum, b) sum b.batteryCapacity, 0); return max 0 ? Math.round((total / max) * 100) : 0; } // 动画循环 function animate() { drawSky(); // 如果电网断电每帧减少电池电量 if (!isGridUp) { buildings.forEach(building { if (building.status battery) { building.batteryLevel Math.max(0, building.batteryLevel - 0.3); if (building.batteryLevel 0) { building.status off; } } }); } // 绘制所有建筑 buildings.forEach(building building.draw()); // 更新状态面板 gridStatusEl.textContent isGridUp ? 正常 : 断电; gridStatusEl.style.color isGridUp ? #00ff88 : #ff0044; batteryTotalEl.textContent getTotalBattery() %; requestAnimationFrame(animate); } // 启动动画 animate();这段代码有四个关键点第一Building类封装了建筑的所有属性。每个建筑都有自己的电池容量和当前电量状态有三种grid电网供电、battery备用电池供电、off断电。第二draw()方法根据状态选择不同颜色。电网正常时不同建筑有各自的霓虹色电池供电时统一变为绿色表示应急状态断电后变为深色。第三animate()是动画主循环每帧调用一次requestAnimationFrame。电网断电时电池电量逐帧减少当某一栋建筑电量耗尽灯光熄灭。第四星星的背景用Math.random()生成每一帧都会变化让夜空有一种动态闪烁的感觉。6.4 JavaScript断电自救调度逻辑接下来是最核心的部分——triggerBlackout()和restorePower()。// 触发断电 function triggerBlackout() { if (!isGridUp) return; isGridUp false; // 按优先级排序priority 数字越小优先级越高 const sortedBuildings [...buildings].sort((a, b) a.priority - b.priority); // 依次分配备用电源 sortedBuildings.forEach(building { if (building.priority 2) { // 高优先级建筑切换到电池供电 building.status battery; } else { // 低优先级建筑检查电池剩余电量 if (building.batteryLevel 0) { building.status battery; } else { building.status off; } } }); console.log([电网] 断电事件触发启动应急电源调度); } // 恢复供电 function restorePower() { if (isGridUp) return; isGridUp true; // 所有建筑恢复电网供电 buildings.forEach(building { building.status grid; building.batteryLevel building.batteryCapacity; }); console.log([电网] 电力恢复城市供电正常); } // 自动断电演示页面加载 10 秒后触发一次断电 setTimeout(() { if (isGridUp) { triggerBlackout(); } }, 10000);这段逻辑的核心是“按优先级调度”。触发断电时先把所有建筑按 priority 排序然后依次让它们切换状态。priority 为 1 和 2 的建筑无条件切换为电池供电priority 更高的建筑需要检查自身电池是否还有余量有余量才能切换否则直接断电。这个调度算法虽然简单但已经能模拟真实的灾备场景医院和数据中心这些关键设施优先保障供电普通住宅和商业楼只能靠自身电池硬撑电池耗尽后灯光熄灭。城市看起来就像真的在“自救”。restorePower()的逻辑很简单电网恢复后所有建筑回到正常状态同时把电池电量充满为下一次断电事件做准备。代码末尾加了一个 10 秒定时器页面打开 10 秒后会自动触发一次断电方便演示效果。如果你想手动控制可以删掉这个定时器只用按钮触发。7. 运行与效果验证代码写好之后验证环节同样重要。下面介绍如何运行这个项目以及如何判断断电自救机制是否正常工作。7.1 运行项目从 Claude Code 退出后在项目目录中直接用浏览器打开index.html即可open index.html或者使用 VSCode 的 Live Server 插件启动本地服务这样改代码后浏览器会自动刷新体验更好。如果不想安装任何插件也可以在终端里启动一个简单的 HTTP 服务器python3 -m http.server 8080然后访问http://localhost:8080。7.2 验证断电自救打开页面后正常状态下所有建筑灯光都是亮的左上角电网状态显示“正常”总电池电量为 100%。点击“触发断电”按钮后观察页面变化左上角电网状态变为红色“断电”。医院和数据中心的灯光保持明亮颜色变为绿色。住宅楼和商业楼的灯光变暗电池电量逐帧减少最终熄灭。总电池电量百分比逐渐下降。等待几秒钟再次点击“恢复供电”所有建筑恢复正常灯光电池电量恢复为 100%。如果这些变化都能正常出现说明断电自救系统运行正确。7.3 调试技巧如果页面逻辑出现问题可以打开浏览器的开发者工具F12在 Console 面板中直接调用函数来测试// 手动触发断电 triggerBlackout(); // 查看某栋建筑的当前状态 buildings.forEach(b console.log(${b.name}: ${b.status}, battery${b.batteryLevel.toFixed(1)})); // 手动恢复供电 restorePower();Console 面板会输出[电网] 断电事件触发启动应急电源调度之类的日志方便确认函数是否被正确调用。8. 常见问题与排查方法在实际操作中不管是用 Claude 生成代码还是运行 HTML 项目都可能遇到问题。这里整理了几个高频场景和对应的排查思路。问题现象可能原因排查方式解决方案Claude Code 安装报错error: claude native binary not installednpm 安装不完整postinstall 脚本未执行查看 npm 安装日志卸载后清缓存重新安装确认网络正常提示组织禁止了 Claude Code 访问当前账号的组织后台关闭了订阅访问检查账号类型和组织设置联系组织管理员开启或改用个人账号模型名称无法识别配置了当前版本不支持的模型标识查看 Claude Code 配置文档改用官方支持的模型名称浏览器打开 HTML 后黑屏Canvas 初始化失败或 JS 报错打开 DevTools Console 查看报错确认canvas元素 id 是否正确检查脚本是否引用了未定义的变量点击“触发断电”后建筑不变暗逻辑中未调用draw()方法或状态未更新Console 执行triggerBlackout()并输出建筑状态检查调度逻辑是否修改了building.status确认动画循环在使用最新状态电池电量不减少动画循环中的扣电逻辑没生效在animate()中加日志确认isGridUp状态正确扣电逻辑放在动画循环内Claude 生成的代码风格混乱提示词未明确项目结构和编码规范检查提示词是否包含模块划分说明重新生成前补充“请使用类封装、函数职责单一”等约束页面显示乱码HTML 文件编码问题查看文件编码确保meta charsetUTF-8存在于head中排在前面的是 Claude Code 的安装问题。这类报错大多和 npm 包安装不完整有关先卸载、再清缓存、再重装能解决大部分情况。如果仍然解决不了建议去项目官方文档查看最新安装说明因为不同版本的安装方式可能有差异。排在后面的是 HTML 项目本身的运行问题。核心思路是“先看 Console再造数据”打开开发者工具看控制台有没有红色报错然后在 Console 里直接调用函数、修改变量观察页面变化。这种调试方式比反复刷新页面更要高效。9. 最佳实践AI 生成网页项目的工程建议通过这次从零生成赛博城市的实践我总结出几条对你有实际帮助的建议。9.1 提示词要像需求文档一样写不要指望 AI 读懂你心中模糊的想法。一句话提示词只能得到粗糙的结果。写提示词时要包含项目背景、技术选型、数据结构和行为逻辑。特别要描述“异常情况下的行为”比如断电后按什么策略调度。AI 处理规则性描述比处理感受性描述可靠得多。9.2 生成后先审阅后运行AI 生成的代码不一定能直接跑通。运行之前先花两分钟通读代码结构确认以下几点关键函数是否完整定义比如triggerBlackout和restorePower。数据结构和代码调用是否匹配。是否存在明显的基础语法错误。如果发现问题直接在对话中要求 AI 修复而不是自己手改。AI 可能比你先发现另一个更隐蔽的问题。9.3 使用 Git 做版本控制AI 迭代生成代码时经常会出现“改一个 Bug 引入两个新 Bug”的情况。每次让 AI 做较大改动前先提交一次 Git commit。这样即使改动失败也能快速回滚到可用状态。git add . git commit -m feat: 初始赛博城市版本9.4 让 AI 解释代码而不是只给代码很多新手拿到 AI 生成的代码后直接跑跑通就完事。但真正重要的是理解代码背后的逻辑。可以要求 AI 逐段解释它写的代码或者让它画一个函数调用关系图用文字描述。当你发现自己能解释清楚整个系统的运行流程时这个项目才真正属于你了。9.5 逐步扩展功能不要一次要求太多如果你想给赛博城市加更多功能比如按钮触发不同区域的断电、增加天气系统、添加 AI 交通流模拟不要一次全部扔给 AI。一次只加一个功能运行验证通过后再加下一个。逐次迭代的成功率远高于一次到位。9.6 安全与合规提醒使用 Claude Code 时注意账号权限和远程服务的使用合规性。不要让它执行你不理解的命令也不要让它访问包含敏感信息的目录。对于从 AI 获取的代码最终部署前最好有基本的安全审查特别是涉及用户输入、外部请求和本地文件操作的场景。10. 结合 Code 工作流拓展从单文件演示到完整项目如果只是做一个演示项目单文件 HTML 已经足够。但在实际开发中你可能会想把赛博城市扩展成一个更完整的工程。这时候你就需要借助 Claude Code 的多文件编辑能力了。例如你可以请求 Claude Code 将代码重构为多文件结构请把当前的单文件 HTML 重构为一个标准前端项目结构如下 - index.html页面入口 - css/style.css样式文件 - js/buildings.js建筑数据定义 - js/power.js电力系统逻辑 - js/main.js主入口和动画循环Claude Code 会直接创建这些文件并在文件之间建立模块引用关系。这种能力对从“写个页面玩一玩”到“做一个完整应用”的跨越很有帮助。更进一步你还可以把赛博城市画面背后的“电力调度算法”抽象出来用在真实的物联网边缘设备管理、机房负载均衡、校车站点调度等场景中。项目本身只是一个载体真正有价值的是你在这过程中建立的系统思维和 AI 协作工作流。对于想继续深入的朋友我提出三个可选的扩展方向第一把城市规模扩大。当前只有 12 栋建筑你可以让 Claude 生成 50 栋甚至 100 栋建筑并观察 Canvas 的渲染性能。这会自然引出前端性能优化的话题。第二引入数据可视化。把城市电力状态绘制成实时图表用 ECharts 或 Chart.js 展示各区域用电情况让项目从“模拟器”升级成“可视化监控平台”。第三接入真实数据源。比如接入天气 API雨天时城市灯光自动调暗接入时间 API模拟昼夜更替。这套动静结合的模式能让项目更接近真实世界的数字孪生应用。最后再提醒一句AI 生成代码的能力一直在进步但工程素养不会自动提升。善用工具、保持审阅习惯、理解代码背后的设计逻辑才能把 AI 的效率真正转化为项目质量。建议收藏这篇文章下一次从零搭建 AI 创意网页项目时它会是一个值得参考的起点。