最近在做一个运维巡检小程序的项目,核心是离线告警规则引擎,开发基座选的是华为云码道 CodeArts,过程中让 AI 智能体深度参与,从需求建模、接口设计、代码生成到检视修复都走了一遍。名字听起来有点唬人,但需求本身很朴素:巡检人员背着手机进弱电间、下地下室、跑园区边缘机房,这些地方 Wi-Fi 覆盖差、专网时断时续,设备指标异常判定不能老是依赖云端在线算。如果网络一断告警就失灵,那巡检就失去了意义。所以我们需要一个"本地有规则、断网也能跑"的引擎,把规则前置到端侧,网络恢复后再把结果同步回去。
这篇文章不打算做成教程式流水账,而是想把这些天的真实决策、数据和踩坑记录成一条可参考的路径,给正在做类似离线引擎或巡检小程序的朋友一些实际帮助。
1. 巡检告警为什么非得"离线":需求背景与边界定义
1.1 一次断网后的"集体哑火"倒逼出来的需求
这个项目的起因是一次挺尴尬的故障。当时某园区机房夏季高温,空调机组先告警后掉线,但我们的在线巡检平台因为恰好处于网络割接窗口,采集链路断了将近四十分钟。四十分钟里,设备侧的温度指标一路飙升,云端却没产生任何一条告警,因为告警规则引擎依赖的实时数据流断供,判定逻辑全部空转。最后是现场师傅用体温计和手背贴机柜发现异常的,非常荒谬。
事后复盘时大家意识到:巡检场景和普通业务系统不一样,它的物理环境决定了"实时在线"是理想态,不是常态。弱电间信号屏蔽严重、地下室无覆盖、园区边缘专网质量差,还有各种网络割接、设备掉线、路由器重启。如果告警判定完全放在云端,则网络丢掉的不仅是数据,还包括"发现异常"的能力。于是就有了这个需求的雏形:能不能给巡检人员一个离线也能判定异常、联网后自动补齐告警的机制?这比单纯做一个"指标采集工具"要复杂得多,因为它涉及规则存储、定时采集、本地判定、断网缓存、回传合并,是一个完整的小型规则引擎。
1.2 "离线"到底划到哪里:计算前置与数据回传的边界
刚开始讨论时,团队里有人提议直接拿边缘网关做,设备数据全部落地,离线训练模型都放上去。那太重了,巡检工具根本不需要这一步。我们反复确认后,把"离线"的范围卡在一个比较保守的边界上:规则计算前置,数据回传靠后。
具体来说,规则引擎不再完全依赖服务端在线的数据推送,而是把规则集以"规则包"的形式预先下发到端侧,端侧在本地读取巡检采集到的指标快照,执行条件匹配,产生告警事件。这些事件先落本地缓存,网络恢复后批量上报给云端,云端再做二次确认和工单流转。这样做的优点是工程量可控、不需要改造硬件、纯软件层就能落地;缺点是"端侧的判定可信度"要自己负责,规则失效、时间偏差、数据缺失都得在端侧处理,不能推给云端兜底。这个边界一旦定清楚,后面所有设计都有了靶子。
1.3 为什么这次选华为云 CodeArts 作为开发基座
开发工具链是另一个必须交代的决策。之前我们团队用开源工具拼过 DevOps 流水线,代码托管、检查、发布各用各的,维护成本其实不低。这次项目启动时,我决定试试华为云 CodeArts,理由有三个:一是它有 CodeArts Check 这类开箱即用的代码检查能力,和 AI 智能体结合起来,能在我写代码的同时发现问题;二是我们后续的部署环境就在华为云,代码仓库、流水线、云上部署天然打通,省掉很多中间转发配置;三是新项目想验证一下"AI 智能体辅助开发"在真实工程里的效率,而不是停留在 Demo 层面。
后面的事实证明,这个选择在接口设计和代码生成阶段确实省了不少时间,尤其是写小程序端那些重复性很高的页面代码,智能体直接把骨架拉起来,我只需要改业务逻辑。但我也要提前说一句:AI 智能体不是省掉了思考,而是省掉了打字,架构上的判断和取舍还是得自己拿主意,这一点后面专门展开讲。
2. 需求转方案:AI 智能体在架构设计阶段帮了哪些忙
2.1 我是怎么给智能体"下需求"的
很多朋友问我智能体怎么用在正式项目里,第一步卡住的地方通常是"不知道该怎么问"。我的经验是把需求当成给一位新同事讲背景,不能只扔一句话过去。我第一次给码道智能体下的指令大概是这样的:
需求背景:我们有一个运维巡检小程序,巡检员在弱网环境下采集设备指标,断网时也需要本地判定异常并产生告警。请帮我设计一个离线告警规则引擎的规则元模型,要求:支持数值阈值、字符串状态判断、连续N次触发、恢复条件、静默期;端侧用 JavaScript 实现解析,服务端用 Java 实现;数据样例是每5分钟采集一次的 CPU 使用率和温度。请输出规则 JSON 结构示例、核心字段说明和匹配判定流程。
这里的关键是把约束条件全部前置:平台是什么、数据长什么样、触发和恢复的语义是什么、部署边界在哪里。智能体收到的上下文越像一份需求文档,它产出的方案越能直接用。如果只是问一句"怎么设计规则引擎",它大概率会给你一个通用但没法落地的八股答案,还得返工。
2.2 智能体产出的规则引擎架构草案与我的取舍
第一轮对话后,智能体给了一个相当完整的草案:规则用 JSON 表达,支持条件树嵌套,触发和恢复分开配置,还建议了告警去重和通知策略。说实话,整体骨架比我预想的要贴近实际,省掉了我从零写文档的时间。
但我没有直接全盘接受,而是按项目实际约束做了四个调整:
- 去掉 WebSocket 实时下发:智能体默认假设规则要实时推送,技术上没问题,但离线场景的核心诉求是"规则在端上稳定存在",与其搞长连接保活,不如用版本拉取+本地缓存,网络恢复时检查更新即可。
- 不引入自研 DSL:智能体给出了类似表达式语言的方案,灵活但代价大,小程序端解析 DSL 需要引入额外的语法解析器,包体积和复杂度都上去了。我改成纯 JSON 条件树,端侧用一个递归评估函数就能算。
- 存储用本地缓存而非 SQLite:小程序端不适合引入 SQLite,数据量也没大到需要数据库,用 storage 按 key 管理足够,还能避免原生插件带来的兼容问题。
- 告警事件增加状态机:智能体初版的告警模型只有"产生/恢复"两态,我扩展成 PENDING、ACTIVE、ACK、RESOLVED 四态,为了给云端审核留出操作空间。
这轮调整让我意识到,智能体适合当"架构讨论者"而不是"决策者"。它能够快速枚举方案、补全细节,但工程取舍必须结合线上真实约束,这两者结合才有效。
2.3 哪些地方不能全信:几条真实经验
- 架构建议要警惕"理想网络假设":智能体给出的架构默认网络是连通的,离线语义需要你反复在提示词里强调,否则它会自动滑向在线实时计算的思路。
- 分阶段投喂更靠谱:一次性把需求、数据库表、接口文档全塞给它,回复质量反而下降。我习惯拆成"规则模型→接口设计→页面骨架"三个会话,每轮聚焦一个主题,生成结果明显更清晰。
- 代码生成之后必须自己过一遍边界:智能体生成的代码在常见路径上很正确,但异常分支往往缺失。比如它生成的上报接口没有考虑幂等键,重复提交时会产生重复告警,这种问题它不提醒,得靠代码检视和自己测试来兜底。
3. 离线告警规则引擎核心设计:规则模型、匹配算法与告警收敛
3.1 规则元模型:JSON 条件树的字段设计
规则元模型是整个引擎的地基。我最终采用的是嵌套条件树结构,字段设计如下表:
| 字段 | 类型 | 说明 |
|---|---|---|
| ruleId | string | 规则唯一标识,全局唯一 |
| name | string | 规则名称,方便巡检端展示 |
| scope | object | 规则适用范围,如设备类型、分组 |
| conditions | object | 条件树根节点,支持 and / or / compare |
| window | object | 统计窗口,如最近15分钟内的采样点 |
| trigger | object | 触发条件:连续N次异常、阈值等 |
| recovery | object | 恢复条件:连续M次正常 |
| notify | object | 通知策略:静默期、限频次数 |
| version | long | 规则版本号,配合增量下发 |
| enabled | boolean | 是否启用,删除用软删 |
conditions 是递归结构,核心节点类型有 compare(比较)、and(与)、or(或)、aggregate(聚合)。一段简化后的 JSON 长这样:
{ "ruleId": "rule_cpu_001", "name": "CPU使用率持续过高", "scope": { "deviceType": "server", "tags": ["机房A"] }, "conditions": { "op": "and", "items": [ { "op": "compare", "metric": "cpu_usage", "operator": ">", "value": 85 }, { "op": "aggregate", "metric": "cpu_usage", "func": "avg", "operator": ">", "value": 80 } ] }, "window": { "duration": "15m", "sampleCount": 3 }, "trigger": { "type": "continuous", "count": 3 }, "recovery": { "type": "continuous", "count": 2 }, "notify": { "silenceMinutes": 30, "maxPerHour": 6 } }为什么坚持用 JSON 而不是表达式字符串?因为 JSON 可以被小程序端JSON.parse后直接遍历,Java 端用 Jackson 也能无缝对接。它不需要引入额外的语法解析器,规则校验也可以直接在两端复用同一套 schema。对于离线引擎来说,解析链越短,出错概率越低,这一点在设备端尤其重要。
3.2 匹配引擎:滑动窗口与触发/恢复判定
规则引擎的判定核心不是某一瞬间的指标值,而是"一段时间内是否稳定异常"。我采用的是滑动窗口加连续计数模型:窗口内保存最近若干个采样点,每次新采样到达时,窗口滑动一格,重新评估窗口内的条件和触发计数。
伪代码逻辑如下:
function evaluateSnapshot(snapshot, rule) { const windowKey = rule.ruleId + ':' + snapshot.deviceId; const queue = cache.get(windowKey) || []; queue.push(snapshot); if (queue.length > rule.window.sampleCount) { queue.shift(); // 移除最旧的点,保持滑动窗口大小 } cache.set(windowKey, queue); const matched = matchConditions(snapshot, rule.conditions); const windowMatched = matchWindowAggregate(queue, rule.conditions); if (matched && windowMatched) { rule.trigger.currentCount++; rule.recovery.currentCount = 0; } else { rule.recovery.currentCount++; if (!matched) rule.trigger.currentCount = 0; // 连续计数只在异常时累加 } if (rule.trigger.currentCount >= rule.trigger.count) { emitAlert(rule, snapshot, 'ACTIVE'); } if (rule.recovery.currentCount >= rule.recovery.count && alertExists(rule)) { emitAlert(rule, snapshot, 'RESOLVED'); } }这段逻辑有一个隐藏的关键点:触发计数和恢复计数必须分开维护,不能只用一个布尔状态。刚开始我就是简单地把alerting置为 true 或 false,结果在一次异常抖动中,错误地产生了"告警-恢复-告警"的振荡,原因是一个异常点被窗口丢弃后,布尔状态立刻翻转。后来改成两个独立计数器,用连续计数做迟滞,效果立刻稳定了。这本质上是给规则引擎加了一点类似"施密特触发器"的滞回特性,离线场景下没有实时人工介入,这种设计非常有必要。
3.3 告警收敛:静默期、去重与恢复事件
告警引擎最怕的事情之一就是告警风暴。端侧断网恢复后,如果积压的所有事件一股脑上报,云端服务和值班群都会被冲垮。我在 notify 策略里做了三层收敛:
- 静默期:同一规则的同一个设备,产生告警后进入静默期(比如30分钟),静默期内重复触发不再生成新事件,只更新原事件的最后触发时间。
- 限频:每小时内最多上报告警数量,超过部分直接丢弃计数,避免某个坏设备刷屏。
- 恢复事件合并:只有从 ACTIVE 变回正常时才单独产生 RESOLVED 事件,中间反复异常的抖动点不再逐条上报。
这三层看着简单,但在离线场景里直接影响了用户体验。没有静默期时,一个小程序页面能被同一个机房的告警刷出两百多条记录,值班同事直接不看告警了。加了静默期之后,告警列表终于回到了"一眼能看懂"的状态。
4. 基于 CodeArts 智能体搭建后端服务与小程序端代码骨架
4.1 后端服务骨架:规则下发、事件上报、工单关联
后端我用 Java 写,核心是两个 REST 接口加一个状态机。
规则下发接口(GET /openapi/v1/rule/packages):按版本号返回规则包。端侧拿着本地版本号来拉,如果版本一致就返回 304,不一致就返回全量规则包。规则包做了 md5 校验,避免传输过程损坏。这个接口的逻辑很简单,但智能体生成代码时帮我省了很多时间,包括分页、条件查询、DTO 映射这些样板代码基本一次成型。
事件上报接口(POST /openapi/v1/alerts/batch):接收端侧批量上报的告警事件,按 alertId 做幂等处理,已存在的直接忽略。事件进入状态机:PENDING(待确认)→ ACTIVE(已确认)→ RESOLVED(已恢复)→ CLOSED(关闭)。云端的二次确认逻辑是这样的:端侧上报的所有事件先落到 PENDING,由后台对原始采样点再做一次规则复核,复核通过的转 ACTIVE 并通知值班人员,复核不通过的标记为"端侧误报"并丢弃。这一步是双轨机制里很关键的一环,它并不推翻端侧判断,但能把因为端侧时钟偏差、数据缺失造成的明显误报挡在正式告警之外。
4.2 小程序端骨架:巡检任务、离线判定与告警卡片
小程序端我拆成了两个相对独立的部分:一部分是常规的巡检任务流,另一部分是本地规则引擎模块。
页面结构上最常用的是四个页面:
- 巡检任务列表:展示今日待巡检的设备清单,按机房和楼层分组。
- 设备详情页:展示实时指标快照,支持手动录入温度、湿度等离线数据。
- 离线判定区:这是本地引擎的工作台,展示当前规则包版本、最近几次判定结果、待上报事件数量。
- 告警记录页:按设备、时间展示本地已触发的告警卡片,卡片上标注"已同步/待同步"状态。
本地规则引擎模块是一个纯 JavaScript 文件,封装了规则加载、条件匹配、滑动窗口和事件队列。小程序端没有用任何第三方规则库,全部用原生 JS 实现。原因是离线引擎在端侧要尽可能轻,一个库就是一份体积和兼容性风险。实际跑起来之后,规则解析和匹配的性能完全够用:一条规则对一千个采样点的批量回放,几百毫秒内能算完,巡检场景根本碰不到性能瓶颈。
4.3 检视修复智能体的实测体验:像第二双眼睛
写代码最怕的是自己看自己代码永远觉得没问题。这次项目里,CodeArts 的检视修复智能体帮了不少忙。我提交代码后,它在几秒钟内给出了几十条检视意见,其中有一部分是空白符、命名这类小问题,但有几条确实让我冷汗直冒:
- 时区处理:我最初在小程序端直接
new Date()生成事件时间戳,检视提醒需要考虑设备时区和 UTC 的差异。后来所有上报时间统一转成 UTC 字符串,再在云端转换展示,彻底规避了"北京时间差8小时"的经典坑。 - 空指针风险:后端接口里读取规则包配置时,有一个嵌套字段没有判空,智能体直接标注了 NPE 风险和复现路径,这在自测里基本很难触发。
- 重复上报风险:它发现批量上传接口里没有对
alertId做唯一索引,可能导致同一事件重复落库,这正好呼应了我在 2.3 里担心的问题。
我体验下来的结论是:检视智能体更适合当"第二双眼睛",不能替代代码评审人。它擅长发现模式化的问题,比如空指针、时区、资源未关闭;但业务语义层面的问题,比如"这条规则放在这里会不会误伤其他设备类型",它很难理解深层次的业务背景。代码评审该开还是得开,但有了它之后,评审会的讨论质量确实提高了,大家不再围着低级问题打转。
5. 离线数据链路与一致性设计:双向同步、幂等与补偿
5.1 规则怎么安全地下发到端侧:版本与校验
离线的意思是"计算不依赖实时网络",但规则包本身还得靠网络同步到端侧。规则下发我用的是"全量快照 + 增量版本"模式。
端侧每次启动或进入前台时,先检查本地是否有可用的规则包缓存。有就用缓存版本,同时异步请求最新版本号,比较之后决定要不要拉全量包。断网时直接使用缓存版本,并在界面提示"规则版本 v12,更新于 3 小时前"。规则包的传输除了 HTTP 本身,我额外做了两层防护:一是 md5 校验,防止压缩包损坏;二是规则包的包内字段校验,加载时先跑一遍 JSON Schema,任何字段类型不对直接拒绝加载,并标记规则包异常回退到上一版本。
这里有个经验值得分享:规则包的回滚机制必须做成"默认回退",而不是"报错停止"。早期版本里,如果端侧发现规则包损坏,我直接让引擎停摆,结果是一辆车坏了一个轮胎,整辆车趴窝。改成回退到上一已知良好版本后,最坏情况是用旧规则跑一段时间,总比没有规则强。
5.2 告警和巡检数据怎么回传:幂等键、批量补传、冲突合并
网络恢复后,端侧积压的告警事件和巡检数据需要回传。这部分最容易出问题的就是"重复"和"乱序"。
幂等键我设计为:hash(ruleId + deviceId + firstTriggerAt),其中firstTriggerAt是第一次触发告警的时间戳。同一个规则、同一个设备、同一次连续异常,不管上报多少次,云端通过唯一索引直接丢弃重复项。巡检采样数据则用设备 ID 加采集时间作为唯一键,乱序到达时不直接覆盖,而是对比数据时间戳,只保留时间更新的记录。
云端冲突合并策略是这样的:事件从 PENDING 到 ACTIVE 是"端侧上报、云端复核";从 ACTIVE 到 RESOLVED 则两种路径都能触发。离线恢复事件允许在端侧判定并上报,但云端在复核时会检查原始采样序列,防止端侧因为时钟跳变产生"假恢复"。这条规则帮我挡掉了一次很典型的误恢复:某个设备时钟因为手动校时向前拨了5分钟,端侧判定窗口里恰好都是正常值,于是产生 RESOLVED 事件。云端复核时发现原始采样怎么都对不上,把这条恢复事件直接标记为异常,没有打扰值班人员。
5.3 小程序离线缓存被系统回收怎么办:持久化兜底
小程序和原生 App 有一个很大的不同:它的后台生命周期不受开发者完全控制。用户切走、系统内存吃紧、或者小程序长时间在后台,都可能导致 JS 执行环境被销毁。如果这时候待上报事件只存在内存队列里,数据就永远丢了。
我做的兜底是三层:
- 第一层,所有待上报事件实时写入
wx.setStorage,不在内存里攒批。虽然牺牲了一点点性能,但换来了"随时可被杀"的可靠性。 - 第二层,启动时从 storage 恢复未上报队列,先补传再进入正常巡检流程。
- 第三层,传输本身带
offset游标和失败重试机制,单条事件失败不影响整批队列。
这块是整个项目里最"不值得炫耀但必须做对"的地方。很多离线方案在真机压测前都是好的,一遇到系统强杀就露馅。把存储和传输做成分离的两层,哪怕小程序被杀一百次,只要 storage 没清空,数据就能在下次启动后被救回来。
6. 压测与真实踩坑:误报、误恢复与时间戳的那些事
6.1 第一次联调压测的数据与主要问题
系统联调阶段,我组织了一次模拟 1000 台设备的离线压测,端侧模拟弱网环境(周期性断网),在断网区间持续产生异常数据,恢复网络后观察上报和复核结果。第一轮数据出来,问题比预想的多:
| 问题现象 | 根因 | 修复方式 |
|---|---|---|
| 断网期间误报率高,大量正常设备被判定为异常 | 数据缺失时窗口内采样点不足,条件计算得到错误结果 | 增加"数据缺失"状态,缺失不累计、不清零,采样不足时不触发 |
| 恢复事件误产生,ACTIVE 状态被提前解除 | 异常点被滑出窗口后,恢复计数开始累加 | 恢复判定必须基于"连续M个采样点全部正常",且原始采样序列通过云端复核 |
| 告警时间比真实发生时间晚了8小时 | 端侧使用本地时间生成时间戳,云端按 UTC 解析 | 统一使用 UTC 字符串,展示层再转本地时区 |
| 同一设备重复产生多条相同告警 | 规则静默期只在内存中保存,进程被杀后失效 | 静默期状态持久化到 storage,启动后重新加载 |
这张表里的前三条,基本就是"离线规则引擎最容易犯的三大错",如果你也在做类似的东西,建议直接把这三条当成预检清单。
6.2 "丢数当正常"与"丢数当异常":缺失数据的处理策略
数据缺失是离线场景里最防不胜防的坑。我在第一版里用的是简单逻辑:某采样点到达时,如果窗口里数据不足,就直接跳过判定。这个策略在"偶发丢点"时勉强能用,但在"持续断网几分钟"的场景下有严重问题——因为窗口里的点全部是断网前的旧数据,判定结果自然停留在过去的状态,如果过去状态是正常,引擎就会误认为设备一直正常,产生"丢数当正常"的漏报。
反过来,如果我把缺失一律当成异常,又会在网络抖动时疯狂触发告警,变成"丢数当异常"的误报。真正有用的处理策略是引入三值状态:正常(OK)、异常(CRITICAL)、缺失(UNKNOWN)。
当窗口内最新采样点的时间戳与当前时间差超过阈值时,该点标记为 UNKNOWN。UNKNOWN 不参与触发计数累加,也不参与恢复计数累加。只有当缺失持续时间超过上报告警的容忍上限(比如10分钟),引擎才认为"数据缺失本身就是一种异常",单独产生一条数据中断告警,并关联到网络链路而不是设备指标。这样就把"设备真的坏了"和"网络断了导致看不到设备"两条路径分开,值班人员看到告警时能立刻理解问题的性质。
6.3 小程序端几个看似玄学但必须注意的问题
除了数据链路,小程序端还有几个容易让人抓狂的细节:
- JS Number 精度问题:设备 ID 如果超过 2^53,JSON 解析后精度会丢失。我在设计时把所有设备标识统一用字符串类型,后端也全部用字符串接收,彻底避开这个雷区。
- iOS / Android 时间差异:同一台设备在两套系统上
Date.now()的精度和时区行为有差异,尤其安卓某些定制 ROM 会有时间偏移。因此我从来不信任"端到端对时",所有时间戳一律带时区标识,云端判断先后顺序时只认 UTC 毫秒数。 - storage 写入频繁导致的性能劣化:每次采样都写 storage 会卡顿,尤其低端安卓机。我最后采用"事件级实时写、采样点批量写"的分层策略:告警事件必须秒级落盘,普通采样数据先攒 30 秒再批量写入。
- 小程序包体积:规则引擎的 JS 文件加页面代码很容易逼近 2MB 限制。我把规则引擎单独拆成独立模块,用分包加载,主包只留巡检任务列表和登录逻辑,告警详情和离线统计全部塞进分包,实测首屏体积降了 40%。
7. 后续还能怎么扩展:自动动作联动与协作模式反思
7.1 从"告警"到"自动运维动作"
离线告警引擎跑通之后,一个很自然的扩展方向是从"发现问题"走到"自动处置问题"。比如温度告警产生后,本地规则引擎可以通过 WebHook 触发边缘节点上的风扇调速脚本,或者直接给对应机柜下发重启指令。这些动作必须严格定义"授权边界":自动动作只能执行预设的操作清单,任何需要变更配置的步骤都要先挂起,由人工审批后执行。
现阶段关于自动动作的扩展我只做了统一的动作注册表,目的先把"告警产生 → 执行动作 → 结果回传"的闭环跑通。核心思路是不在端侧硬写死动作逻辑,而是把动作也当成一种"规则包"下发,端侧只执行动作脚本的若干白名单命令。未来即便要接入更多设备类型,也不需要重新发版。
7.2 我对 CodeArts AI 协作模式的真实感受
最后说点个人体会。这次用 CodeArts 加 AI 智能体辅助开发,和我之前纯手写代码的感受完全不一样。最明显的变化是,大量重复的样板代码和接口胶水层被智能体消化掉之后,我的注意力能集中在真正复杂的业务上,比如告警收敛策略、数据缺失处理、幂等设计这些"一旦做错就要返工"的部分。
但我也必须说,智能体并没有让我变得更轻松,它改变的是工作负担的分配:原来写一百行业务代码要花一个小时,现在生成可能只要几分钟,但 review 这堆代码、验证边界条件、设计测试用例的时间反而变多了。整个项目下来,我对"AI 提效"的理解变成了这样一句话:它把从零到一的成本降得很低,但从一到可靠的距离,仍然需要人来走完。
如果你正准备做一个类似的离线规则引擎或者巡检小程序,我建议你把重心放在这四件事上:清晰的规则元模型、三值状态的数据缺失处理、全链路幂等和持久化、以及一套能兜底的代码检视流程。把这些做扎实之后,AI 生成的那些代码才能真正帮你跑起来。