AI 辅助企业级系统开发:从「能用」到「好用」的实践与感悟

背景:公司 在线系统( 产品线),前端 Vue 3 + SpreadJS,后端 .NET 8 + Oracle,使用 Cursor AI Agent 进行日常开发。
时间跨度:2026 年 1月(实战)
定位:已投产生产系统的增量开发,非从零起步的绿地项目。


一、为什么在生产系统上用 AI?

企业级系统有几个典型特征:存量代码多、业务规则隐晦、跨系统依赖复杂、改错成本高

直觉上这类项目最不适合让 AI 插手——但换个角度看,这恰恰是 AI 最能体现价值的场景:

痛点 AI 可以做什么
新人看不懂存量代码 跨文件语义搜索、即时解释上下文
变更影响面难评估 自动扫描调用链、关联引用
重复性脚手架代码多 按约定批量生成 Entity/DTO/Service/Controller
调试信息分散 结构化注入诊断日志、自动清理
文档与代码容易脱节 规则约束下强制同步 Spec ↔ 代码 ↔ 测试

关键前提是:你要给 AI 足够的约束,否则「自由发挥」在生产系统上就是灾难


二、核心实践:规则驱动的 AI 协作

2.1 用 Rules 取代口头交代

最初的尝试是每次对话开头手动交代项目背景、命名规范、提交格式。问题显而易见——上下文容易丢失,同一件事要反复说

转折点是建立 .cursor/rules/ 规则体系(9 个 .mdc 文件),把以下内容固化为持久规则:

00-global.mdc          → 全局流程(SDD 四阶段、存量策略、禁止行为)
01-sdd-spec.mdc        → Spec 文档要素、状态机、代码注释关联
02-code-style.mdc      → 命名、函数体量、错误处理
03-testing.mdc         → Vitest / xUnit、AC 映射
04-security.mdc        → 输入验证、认证、数据安全
05-api.mdc             → .NET 分层、SqlSugar、Oracle 参数
06-frontend.mdc        → Vue 3 组件规范、Pinia、API 目录
07-git.mdc             → Conventional Commits、lint 前置、推送快照
conversation-principles.mdc → 回答结构、XY 问题识别、交互力度

实际效果

  • Agent 生成的代码风格与人工代码趋近一致,不再需要大量手工调格式
  • 新功能自动走 Specify → Plan → Tasks → Implement 四阶段,不会跳步
  • 提交信息自动用中文 + Conventional Commits + Spec ID 关联

核心感悟:规则不是写给自己看的文档,而是写给 AI 执行的「操作手册」。越具体、越可验证的规则,AI 执行得越好。

2.2 SDD(规格驱动开发)在 AI 场景下的价值

SDD 的核心是 Spec 先行:任何代码生成前,必须先有明确的功能规格和验收标准。

在纯人工开发中,这经常被视为「额外负担」。但在 AI 辅助开发中,Spec 的价值被放大了——它是 AI 理解需求边界的唯一可靠锚点

实际案例——业务签名功能的演进:

CHG-2026-0429(第一阶段)
  验收标准 AC-001:FDD 委托单工具栏可见「业务签名」按钮
  验收标准 AC-005:CTI 提交时若未签名则阻止提交

CHG-2026-0509(第二阶段)
  验收标准 AC-001:点击业务签名 → 自动从 LIMS 下载签名图
  验收标准 AC-002:LIMS 未维护时提示「请在 LIMS 维护签名信息」
  验收标准 AC-003:FTP/网络故障使用区分文案

Agent 在实现时,每个 AC 对应一个测试用例,代码注释标注 @spec FR-003。当需求从「手写签名」变更为「LIMS 自动拉取」时,Agent 读取新 Spec 就能准确理解变更范围,不会误改客户签章逻辑。

如果没有 Spec:Agent 可能把业务签名和客户签章的逻辑混在一起,或者"好心"地给其他产品线也加上签名功能——在生产系统上这就是事故。

2.3 存量代码策略:触碰即纳入

对已投产系统,我们的策略是:

  • 不动存量:已上线功能不主动补 Spec、注释、测试
  • 触碰即纳入:当存量功能需要变更时,先补简化版 Spec(状态标 Deployed),再走四阶段

这个策略让 AI 不会对着全库「自作主张」地重构,同时保证每次改动都有据可查。


三、四个真实案例:AI 擅长什么,踩坑在哪

案例 1:Oracle 跨库查询 — AI 不懂你的基础设施

任务:查询 LIMS 库的 CTI_FDD_DATA.USERS 表获取签名路径。

AI 的做法:直接生成 SqlSugar 查询 _limsUserRepository.Queryable<LimsUser>().Where(u => u.UsrNam == busrnam)

实际结果ORA-00904: "USRNAM": 标识符无效

根因:Oracle 跨库视图需要显式指定 schema,而 AI 对项目的 Oracle 多 schema 架构没有先验知识。

修复:添加 .AS("CTI_FDD_DATA.USERS")

教训:AI 对通用技术(SQL 语法、API 设计)很强,但对你的基础设施拓扑(跨库视图、dblink、schema 权限)几乎是盲区。这类信息必须通过 Rules 或 Skill 文件提前注入。

案例 2:FTP vs S3 — 信息不对称导致返工

任务:下载 LIMS 中 SIGN_IMAGE_PATH 指向的签名图片。

第一轮:路径形如 ftp://FTPIP/...,AI 合理推断用 FtpWebRequest,实现完整的 FTP 下载逻辑。

实际结果:连接失败。经人工沟通确认,FTPIP 是占位符,实际是 S3 兼容存储(HTTP 8080 端口)。

第二轮:重构为 S3Library2.GetObject(内部 SDK),配置走 appsettings.json

教训:AI 的推理基于你提供的信息。当关键信息缺失(存储协议、端口、凭据方式)时,AI 会按最合理的假设行事——但假设错了就是返工。越早把基础设施事实告诉 AI,返工越少

案例 3:JSON 序列化大小写 — 隐蔽的跨层 Bug

现象:前端调用后端 API 拿到数据,但 payload.imageBase64 始终为 undefined

排查过程

  1. 后端日志显示 S3 下载成功,Base64 数据非空
  2. 浏览器 Network Tab 检查响应体,发现 JSON 属性名是 imagebase64(全小写),而非前端期望的 imageBase64(camelCase)
  3. 根因:后端 System.Text.Json 配置了 LowerCaseNamingPolicy,但 DTO 上的 [JsonProperty] 是 Newtonsoft 注解,对 System.Text.Json 无效

修复:DTO 改用 [JsonPropertyName("imageBase64")](System.Text.Json 原生注解)。

教训

  • 项目中混用两套 JSON 序列化框架(Newtonsoft + System.Text.Json)是定时炸弹
  • AI 在生成 DTO 时默认用了 Newtonsoft 注解(因为项目中大量存量代码如此),但运行时序列化器已切换为 System.Text.Json
  • 这类「配置级别的隐式约定」是 AI 最容易踩的坑,因为它既不在代码逻辑里,也不在文档里

案例 4:日期格式不一致 — 人眼秒发现,AI 需要引导

现象:客户签章日期显示 2026-04-30,业务签名日期显示 2026-04-30T15:33:16

根因:业务签名用了后端返回的 ISO 时间戳,客户签章用了 orderInfoReactive.servertime(短日期格式)。

修复过程:用户截图指出"日期不对"→ AI 对比两处签章的日期来源 → 统一取 servertime

感悟:UI 一致性问题,人眼一看就知道不对,但 AI 不会主动比较两个功能的视觉效果。当你发现「看起来不对」的问题时,直接把两个对比目标告诉 AI,比让它自己去猜高效得多


四、调试方法论:结构化排障

在与 AI 协作调试的过程中,形成了一套可复用的排障流程:

1. 定位层次     前端 JS 错误?HTTP 响应异常?后端异常?数据库查询错误?
     ↓
2. 假设形成     根据错误信息形成 1-2 个假设
     ↓
3. 证据收集     注入 NDJSON 诊断日志(session 级文件隔离)
                 + 浏览器 Network Tab
                 + 后端 SQL 日志
     ↓
4. 交叉验证     三方证据交叉确认根因
     ↓
5. 最小修复     只改必须改的代码
     ↓
6. 清理收尾     移除所有诊断日志,保持代码整洁

为什么强调 NDJSON 日志:相比 Console.WriteLineconsole.log,结构化 JSON 日志可以被程序化解析,多个诊断点的日志可以按时间序列还原完整链路。而且 session 级文件隔离保证了不同调试会话之间互不干扰。

AI 在调试中的角色

  • 擅长:根据日志快速定位异常节点、生成精准的诊断代码、提出假设
  • 不擅长:判断"看起来不对"的 UI 问题、理解基础设施拓扑、知道哪些外部依赖在你的环境里不可达

五、感悟:与 AI 协作的心智模型

5.1 AI 是极快的初级开发者,不是架构师

AI 写代码的速度极快,对通用模式(CRUD、DTO 映射、组件模板)的掌握堪称熟练。但它缺少两样东西:

  • 项目历史记忆:不知道去年某个决策为什么这么定,不知道某个 workaround 背后的原因
  • 业务直觉:不知道"业务签名"和"客户签章"在业务流程上的权重差异

所以有效的协作模式是:人做决策,AI 做执行;人负责「做什么」和「为什么」,AI 负责「怎么做」和「做得快」

5.2 上下文管理是最被低估的技能

AI 的表现 = 模型能力 × 上下文质量。

同一个 Cursor,给它一句"加个签名功能"和给它一份包含 7 个验收标准的 Spec,产出质量天差地别。

我在项目中管理上下文的方式:

层级 载体 生命周期
全局约束 .cursor/rules/*.mdc 永久,跨会话
项目知识 CLAUDE.md、Skill 文件 永久,随结构变更更新
需求边界 docs/specs/docs/change/ 功能级,Spec 状态流转
会话上下文 对话记录、TodoWrite 单次会话
临时诊断 NDJSON 日志、session 级文件 用完即删

5.3 「禁止行为」比「鼓励行为」更重要

告诉 AI "用 Pinia 管理状态"不如告诉它 “禁止使用 EventBus” 有效。原因是 AI 倾向于在已知方案中选择最"安全"的——如果你不设禁区,它可能选择一个技术上可行但在你项目中不合适的方案。

我们的禁止行为清单:

  • 禁止生成无 Spec 依据的功能代码
  • 禁止生成无测试的代码
  • 禁止绕过类型检查
  • 禁止跳过四阶段中的任何阶段
  • 禁止未经授权自动 git commit / git push

最后一条是在实际使用中追加的——Agent 曾在调试循环中自动提交了一个半成品代码。

5.4 AI 犯错的模式是可预测的

经过两个月实战,AI 犯错的模式可以归纳为:

错误模式 频率 典型场景 应对策略
假设缺失信息 FTP vs S3、跨库 schema 提前在 Skill/Rules 中注入基础设施事实
沿用存量代码的旧模式 用 Newtonsoft 注解配 System.Text.Json Rules 中明确当前技术选型
过度工程化 为简单功能引入设计模式 conversation-principles 中的「最小充分解」
忽视 UI 一致性 日期格式不同、按钮风格不统一 用户侧截图对比,告知 AI 参照物
遗漏边界情况 Spec 中有 AC 但实现时漏了 测试驱动 + AC 映射 checklist

六、教训:踩过的坑

坑 1:信任但不验证

早期对 AI 生成的代码"看着差不多就提交",结果出了 JSON 序列化大小写问题——前端拿到数据字段名全错,但代码审查时没注意到 JsonProperty vs JsonPropertyName 的区别。

改进:所有新增 API 端点,必须在前后端联调时用 Network Tab 验证实际 JSON 响应,不能只看代码"逻辑上对不对"。

坑 2:让 AI 自主决定提交时机

Agent 在调试循环中可能会频繁修改代码,如果允许它自动 commit,Git 历史会充满半成品提交。

改进:修改规则,禁止自动 commit,所有提交必须经用户显式授权。

坑 3:规则写了但没维护

有一次后端的序列化器从 Newtonsoft 部分迁移到 System.Text.Json,但 Rules 中没有更新,导致 AI 继续用 Newtonsoft 的注解生成新 DTO。

改进:规则文件纳入代码审查范围,技术选型变更时同步更新 Rules。

坑 4:不区分「AI 擅长」和「AI 需要引导」的任务

把"从 LIMS 拉签名图"这种涉及外部系统集成的任务直接交给 AI,结果第一版实现的协议都是错的。但"在 SpreadJS 中插入图片并绑定单元格"这种纯前端逻辑,AI 一次就做对了。

改进:涉及外部系统集成、基础设施配置的任务,先人工确认关键参数(协议、端口、凭据方式),再交给 AI 实现。


七、改进:从这轮实践中提炼的方法

7.1 前置信息清单

在启动涉及外部系统的功能前,先填写信息清单:

□ 目标系统名称 / 用途
□ 通信协议(HTTP / FTP / S3 / gRPC / ...)
□ 主机 / 端口 / TLS
□ 认证方式(匿名 / 密码 / Token / IAM)
□ 凭据来源(配置文件 / 环境变量 / Vault)
□ 数据格式(JSON / XML / 二进制)
□ 本地是否可达(网络隔离 / VPN / 代理)

这份清单填完后作为 Spec 的附录,AI 读取后可以直接生成正确的集成代码。

7.2 序列化契约卡

每当新增前后端交互接口时,建一张契约卡:

端点:GET /api/Fdd/MyLimsBusinessSignatureImage
序列化器:System.Text.Json
命名策略:LowerCaseNamingPolicy(全局)+ JsonPropertyName 显式覆盖
前端属性名约定:camelCase
验证方式:Network Tab 实际响应 + 前端 console.log(payload)

7.3 渐进式信任

第 1 次用 AI 做某类任务 → 逐行 review + 联调验证
第 2 次同类任务          → 重点 review 边界情况
第 3 次同类任务          → 抽查 + 跑测试即可

信任是挣来的,不是给的。AI 在某类任务上证明了可靠性之后,可以逐步减少 review 力度。


八、展望:下一步想尝试的方向

8.1 MCP 集成:让 AI 直接查数据库

目前 AI 无法直接查询 Oracle 数据库,遇到"这个字段实际存了什么值"的问题需要人工去查。计划通过 MCP(Model Context Protocol)接入 Oracle 只读查询能力,让 AI 在排障时能直接验证数据。

8.2 Browser-Use:端到端验证

目前 UI 一致性问题(如日期格式、按钮位置)依赖人工截图反馈。计划利用 Cursor 的 Browser-Use 能力,让 Agent 自动打开页面、操作流程、截图对比。

8.3 多 Agent 协作

复杂功能(如简道云数据录入)涉及前端 UI + 后端 API + 第三方集成,目前是单 Agent 串行推进。计划尝试多 Agent 并行:一个负责前端、一个负责后端、一个负责测试,由 Plan 文档协调接口契约。

8.4 规则自动化验证

目前规则遵循度靠人工 review。计划编写 CI 脚本自动检查:

  • 新增功能代码是否有 @spec 注释
  • 新增文件是否有配套测试文件
  • Commit message 是否符合 Conventional Commits 格式
  • 变更文档的关联 Spec 是否存在

九、总结

两个月的 AI 辅助开发实践,总结为一句话:

AI 放大你的能力,也放大你的疏忽。用规则约束它的自由度,用 Spec 定义它的边界,用测试验证它的输出——这不是限制 AI,而是让 AI 真正可靠。

具体数字:

指标 数据
近一周代码产出 5 次提交,60+ 文件,净增 4,100+ 行
变更文档产出 8 份 CHG 文档 + 2 份 FR Spec
关键 Bug 修复 4 个跨层 Bug,平均 1-2 轮交互解决
规则文件数量 9 个 .mdc + 2 个 Skill + 1 个 CLAUDE.md
返工次数 2 次(FTP→S3 重构、Newtonsoft→System.Text.Json 注解)

对于正在考虑在企业项目中引入 AI 辅助开发的团队,我的建议是:

  1. 从增量功能开始,不要一上来就让 AI 重构存量代码
  2. 先建规则,再写代码——花一天时间写好 Rules,能省一周的返工
  3. 保持人在回路中——AI 做执行,人做判断;尤其是涉及生产环境的操作
  4. 记录和复盘——AI 犯的错往往有模式,发现模式后可以用规则预防

AI 辅助开发不是魔法,而是一种新的工程实践。掌握它的关键不在于 prompt 写得多漂亮,而在于你的工程体系(规则、Spec、测试、CI)有多扎实。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐