导读:大模型和代码智能体正在把“写代码”的成本快速压低。但软件工程真正困难的部分,不只是写出能运行的代码,而是在复杂约束下构造一个长期可维护、可演化、可运行的软件系统。本文提出一个值得深入研究的问题:当前智能化开发工具缺少的,可能不是语法知识,而是软件工程常识。 |
一、问题:会写代码,不等于懂软件工程
过去几年,大模型和智能体技术快速进入软件开发现场。代码补全、自动生成函数、修复缺陷、生成测试、解释日志、维护文档,已经从实验室演示走向真实开发流程。越来越多开发者开始把 AI 编程工具当作日常助手使用,甚至把部分代码修改、测试补全和文档维护任务交给智能体完成。
但是,一个关键问题正在浮现:AI 生成的代码能够运行,是否就意味着它真正符合软件工程要求?答案显然是否定的。
真实的软件工程从来不只是“写出一段能跑的代码”。一个软件系统能否长期可靠运行,取决于模块边界是否清晰、接口是否稳定、依赖是否可控、测试是否充分、文档和配置是否同步、架构风格是否一致、后续维护成本是否可接受。很多代码在局部看起来正确,也能通过当前测试,但放入复杂系统后,可能破坏系统结构、引入隐性技术债,甚至给未来演化埋下风险。
本文的核心判断:当前代码智能体已经具备较强的代码生成能力,但尚未真正具备软件工程常识。 |
二、什么是软件工程常识
所谓软件工程常识,并不是教材中显式列出的语法规则、设计模式或测试方法,而是资深工程师在长期项目实践中形成的隐性判断能力。
例如,一个接口虽然可以改,但不能轻易改,因为它承载着历史兼容性;一个依赖库虽然能快速解决问题,但可能带来版本冲突、平台适配和长期维护风险;一个补丁虽然能让测试通过,但可能只是绕过现象,并没有修复根因;一段代码虽然功能正确,但可能破坏模块职责边界;一次功能修改不仅要改代码,还可能需要同步修改测试、文档、配置、数据库脚本和部署流程。
因此,软件工程常识可以理解为:支撑软件系统可靠构造和长期演化的一类隐性工程知识。它不是单点知识,而是分散在代码库、提交历史、缺陷报告、评审意见、构建日志、项目文档、运行反馈和团队规范中的工程经验集合。
三、先把“常识”拆开:十类软件工程常识
为了让这个问题具备研究和工程落地价值,需要把“软件工程常识”拆成可观察、可标注、可检索、可约束、可评审的对象。下面给出一个初步分类。
常识类型 | 核心问题 | 典型工程常识 | 大模型常见失误 |
结构常识 | 修改是否破坏系统结构 | 模块职责要清晰,不能为了局部功能把逻辑塞进错误层次。 | 在 Controller 写业务逻辑,在工具类里引入领域逻辑。 |
接口常识 | 接口是否稳定、兼容 | 公共 API、SDK 方法、数据库 schema 不能随意改。 | 改函数签名但不处理调用方,改字段名但不改 SQL/文档。 |
依赖常识 | 是否引入不必要复杂性 | 能用已有依赖就不随意加新库,新增依赖要考虑版本、许可证和部署成本。 | 为小功能引入大库,忽略依赖冲突和平台适配。 |
根因常识 | 是否真正修复问题 | 修 bug 要定位根因,不应只屏蔽异常或绕过失败。 | 吞掉异常、删除失败测试、硬编码特殊情况。 |
测试常识 | 测试是否匹配风险 | 改核心逻辑要补回归测试,改边界条件要补边界测试。 | 只改代码不补测试,生成测试只覆盖 happy path。 |
协同资产常识 | 相关工程资产是否同步 | 代码变化常常需要同步改配置、文档、迁移脚本、部署文件。 | 只改代码,不改 README、配置模板、数据库迁移文件。 |
演化常识 | 是否增加技术债 | 短期补丁不能破坏长期维护性。 | 重复实现、复制粘贴、把 workaround 永久化。 |
安全常识 | 是否破坏安全边界 | 认证、授权、输入校验、敏感信息处理不能被局部修改绕开。 | 为了通过功能测试关闭校验、日志打印 token、绕过权限判断。 |
性能常识 | 是否引入隐性性能风险 | 循环内 I/O、重复查询、无界缓存、大对象复制要谨慎。 | 把 O(n) 改成 O(n²),在循环里查数据库。 |
运行常识 | 是否考虑部署和运维 | 配置、日志、错误处理、灰度、回滚、可观测性是工程系统的一部分。 | 本地能跑但生产不可配置,错误日志不可定位。 |
四、为什么普通提示词不够
很多人试图用一句提示词解决这个问题,例如“请生成高质量、可维护的代码”。这通常不够。因为“高质量”和“可维护”在不同项目中含义不同:有的项目强调接口兼容,有的项目强调性能,有的项目强调最小依赖,有的项目强调领域分层,有的项目强调安全合规。
大模型缺少的不是通用编程知识,而是项目级工程上下文。它不知道这个项目的模块边界在哪里,不知道哪些接口有历史包袱,不知道团队为什么禁止某个依赖,不知道哪些测试是关键回归测试,也不知道哪些配置变化会影响生产部署。
因此,引导大模型遵循软件工程常识,不能只靠提示词,而要把工程常识转化为模型可感知、可检索、可约束、可检查的机制。
五、让大模型遵循工程常识:一个六层框架
1. 建立工程常识卡片
每条常识不应只是“接口要保持兼容”这样的口号,而应被结构化为常识名称、适用场景、触发条件、风险后果、证据来源、检查方法和建议动作。
示例:公共接口修改需保持兼容类型:接口常识触发条件:函数签名、字段名、返回格式、错误码发生变化工程规则:除非明确要求 breaking change,否则应保持向后兼容风险后果:调用方失败、测试失效、版本升级困难、线上兼容问题建议动作:保留旧接口、增加适配层、补迁移脚本、更新文档和测试 |
2. 给模型输入项目工程画像
模型不能只看当前文件。每次生成或修改代码前,应提供一个项目工程画像,包括架构风格、核心约束、测试策略、依赖策略和文档策略。
项目工程画像示例: 项目类型:Web 后端服务 架构风格:Controller-Service-Repository 分层 核心约束:Controller 不写业务逻辑;数据库访问集中在 Repository;公共 API 保持兼容 测试策略:Service 层必须有单元测试;API 变更必须有集成测试 依赖策略:新增第三方依赖需说明必要性,优先复用已有库 |
3. 在生成前检索相关常识
当任务涉及 API 返回字段时,应检索接口兼容、数据 schema、测试同步、文档同步和调用方影响等常识;当任务涉及性能优化时,应检索复杂度、缓存、数据库访问和可观测性相关常识。
4. 先生成修改计划,再生成代码
不要让模型直接写代码。先要求它回答:本次修改涉及哪些模块?是否影响公共接口或数据结构?是否引入新依赖?是否需要同步修改测试、文档、配置或脚本?是否可能只是绕过问题而非修复根因?有哪些长期维护风险?最小安全修改路径是什么?
5. 加入工程常识审查器
代码生成后,可以再让一个“工程常识审查器”从结构一致性、接口稳定性、依赖合理性、根因修复、测试充分性、协同资产一致性和技术债风险等维度检查。这个审查器不替代编译、测试和静态分析,而是补足它们难以覆盖的工程判断。
6. 用 PR Review 数据进行反馈学习
最有价值的数据不是代码本身,而是人类工程师的评审意见。PR diff、review comment、CI 结果、是否合入、后续是否 revert、review 要求修改的原因,都可以被组织成工程常识样本。
六、一个具体例子:如何避免模型随意引入依赖
普通提示词可能是:“请实现 Excel 文件解析功能。”模型很可能直接引入一个新库。工程常识增强后的提示应先让模型进行依赖决策。
任务:实现 Excel 文件解析功能。项目工程常识: 1. 新增第三方依赖必须说明必要性。 2. 优先复用项目已有依赖。 3. 新依赖需检查许可证、版本兼容性、包体积和部署环境。 4. 若功能简单,应优先考虑标准库或已有工具模块。 5. 新增依赖必须同步更新 requirements、部署文档和测试。请先输出:是否已有可复用依赖;是否必须新增依赖;新增依赖的风险;替代方案;推荐方案。然后再生成代码。 |
这类提示的关键不是“让模型多说几句话”,而是把原本隐性的工程判断显式化,把代码生成前移为“构造决策”。
七、结语:代码生成越容易,工程常识越重要
软件工程的本质,从来不是简单地把需求翻译成代码,而是在复杂约束下持续构造、维护和演化可靠系统。AI 编程工具的发展,让代码生成变得越来越容易。但越是在代码生成成本降低的时代,越需要重新重视那些隐藏在工程实践中的常识:什么样的代码值得合入,什么样的修改会破坏结构,什么样的补丁只是掩盖问题,什么样的系统才能长期维护。
从“会写代码”到“懂软件工程”,可能是下一阶段智能化软件开发必须跨越的一道关键门槛。软件工程常识不是一个漂亮概念,而是一类可以被观察、建模、抽取、检索、约束和评估的研究对象。
参考文献与延伸阅读
[1] MIT CSAIL / MIT News. Can AI really code? Study maps the roadblocks to autonomous software engineering. 2025.
[2] IEEE Computer Society. SWEBOK Guide V4.0 / V4.0a: Guide to the Software Engineering Body of Knowledge. 2025.
[3] ISO/IEC 25010:2023. Systems and software engineering — SQuaRE — Product quality model.
[4] Li, H., Zhang, H., Hassan, A. E. AIDev: Studying AI Coding Agents on GitHub. arXiv:2602.09185, 2026.
[5] Pinna, G., Gong, J., Williams, D., Sarro, F. Comparing AI Coding Agents: A Task-Stratified Analysis of Pull Request Acceptance. arXiv:2602.08915, 2026.
[6] Liu, Y., Widyasari, R., Zhao, Y., Irsan, I. C., Lo, D. Debt Behind the AI Boom: A Large-Scale Empirical Study of AI-Generated Code in the Wild. arXiv:2603.28592, 2026.
[7] Zhu, Y., Tsantalis, N., Rigby, P. C. AI-Generated Smells: An Analysis of Code and Architecture in LLM and Agent-Driven Development. arXiv:2605.02741, 2026.
[8] Kumar, C. et al. CodeSmellSynergy: hybrid ensemble learning framework for detecting python code smells. Discover Computing, 2026.
夜雨聆风