当 coding agent 可以替你写出大部分代码时,开发者最重要的能力会转向哪里?Andrew Ng 给出的答案很直接:软件工程基础仍然重要。代理可以生成实现,却不会自动知道某个项目更看重低延迟、低成本、强一致性,还是故障隔离。
这也是 vibe coding 容易遇到的边界。不了解软件基础的人,确实可以快速做出简单应用;应用一旦涉及真实用户、数据和长期维护,代理替你做出的隐含决定就可能逐渐变成延迟、可用性、可靠性、可维护性、简洁性或成本问题。
这篇文章把 Andrew Ng 帖子中的五项能力重新整理成一张工程自检表:先看能否理解完整系统,再看数据和架构,最后检查安全、可靠性与生产运行。重点不在记住更多语法,重点在于知道每个决定会影响什么。
先理解完整的软件系统
Agentic coding 让更多开发者可以承担过去由前端、后端或移动端开发者分别负责的工作。代理能够补足陌生领域的代码,但开发者仍要理解这些代码在系统中的位置。
一项功能至少会经过下面这些环节:界面组件与页面渲染、API 的选择和设计、认证、状态与会话管理、异步处理、数据持久化、测试、安全与无障碍。只盯着当前文件,容易忽略跨层影响。例如,一个看似简单的列表页,可能同时涉及缓存失效、分页接口、权限过滤、加载状态和键盘操作。
因此,使用 coding agent 时,先描述系统边界,再让它实现局部任务,通常比直接让它“把功能做出来”更容易控制结果。你需要能读懂它生成的接口、状态流和错误处理,并能指出哪些地方与现有系统约束冲突。
数据决定系统能走多远
Andrew Ng 特别强调数据,因为数据基础一旦选错,后续迁移的代价往往很高。工程师需要先了解访问模式,再决定保存哪些数据、保存多久,以及使用关系表、文档、键值存储还是图结构。
这组决定会影响速度、扩展性、可用性、可靠性和费用。事务、并发、数据清洁度、一致性、新鲜度、隐私、治理、合规和数据生命周期,也都属于数据管理的一部分。
对 AI 应用来说,数据问题还会直接变成上下文问题。应用从数据源提供给模型的内容,决定模型能看到什么。如果数据架构缺少权限、更新时间或关联关系,模型就可能在看不见关键信息的情况下生成看似完整的回答。代理可以帮你写迁移脚本,却无法凭空补齐业务背景。
一个实用的检查方法是追问三件事:这条数据由谁产生,谁会按什么条件读取,过期或删除时怎么处理。回答不清楚时,先补数据设计,再继续扩大代码量。
架构要随着阶段变化
系统架构没有脱离场景的唯一答案。设计时至少要考虑用户规模、延迟要求、成本上限、前后端边界、状态放置位置、模块拆分方式,以及语言、运行时、框架和数据技术的组合。
原型阶段选择简单的单体结构,可能是为了尽快验证需求;第一套生产系统则要补上权限、监控、部署和故障处理;用户量继续增长后,又可能需要调整服务边界、索引、复制或分片。每个阶段都应重新检查原先的取舍。
coding agent 很擅长根据局部上下文提出一个能运行的方案,却未必知道这个方案是否适合项目当前阶段。把架构问题拆成可比较的实验,会更容易和代理协作:明确候选方案,给出真实约束,测量延迟、资源和维护成本,再决定是否采用。
安全与可靠性要提前考虑
可靠性来自对失败的预先设计。开发者需要决定测试策略,包括单元测试与集成测试的组合、测试框架和覆盖范围;也要考虑 API 限流、依赖失败、部分服务不可用时如何优雅降级,以及怎样限制一次故障的影响范围。
安全工作同样应尽早进入开发过程。AI 工具可以扫描漏洞、检查依赖供应链和云配置,但扫描结果需要有人判断风险是否真实、权限是否过宽、修复是否会破坏业务。提示注入、越权工具调用和数据泄露,也需要通过权限设计与对抗性测试提前验证。
可以把代理生成的代码当成一次候选实现来审查:它处理了哪些失败?失败时返回什么?是否泄露内部信息?重试会不会造成重复写入?这些问题比“代码能否通过一次演示”更接近真实运行条件。
生产运行是软件能力的一部分
真正服务用户,还需要完成完整的软件开发生命周期:配置部署环境,选择发布策略,建立 CI/CD,理解基础设施服务,并在上线后持续观察系统。
生产环境至少要能回答:请求在哪里变慢,错误从哪个依赖开始,模型或数据是否发生变化,费用是否超出预期,用户遇到问题时谁来处理。为此需要日志、指标、链路追踪、告警和事件响应流程。
当负载上升时,还要理解服务器扩展、负载均衡,以及索引、复制、分片或架构调整的代价。版本控制、代码评审、依赖维护和技术债管理,则决定系统能否继续演进。
这说明“会让代理写代码”与“能负责一个线上系统”之间仍有明显距离。后者要求你理解发布之后发生的事情,并能根据证据修正系统。
把五项能力变成自检表
Andrew Ng 的原文列出了五个方向:构建全栈应用、管理数据、设计系统架构、建立安全可靠的系统、扩展并运行生产系统。为了方便日常使用,可以压缩成下面四组问题:
| 检查方向 | 先问自己什么 | 代理可以帮什么忙 |
|---|---|---|
| 全栈 | 我能解释请求从界面到数据库的完整路径吗? | 生成组件、接口和测试草稿 |
| 数据 | 数据的来源、访问模式、保留规则和权限清楚吗? | 编写模型、查询、迁移和校验代码 |
| 架构 | 当前方案适合这个阶段的用户量、延迟和成本吗? | 比较候选结构,补齐实验代码 |
| 可靠生产 | 失败、攻击、发布、监控和扩容路径都验证过吗? | 生成测试、监控配置和排错脚本 |
这张表的用法很简单:每次让代理实现较大的功能前,先选一行写出约束;合并代码前,再用同一行检查证据。若只剩“看起来能跑”,就说明还缺少测试、数据或运行信息。
结语
AI 编程减少了手写代码的时间,却提高了对系统判断的要求。语法记忆的重要性会下降,理解数据、架构、失败模式和生产环境的能力会继续影响结果。
如果你已经有一个 AI 原型,可以从一次真实请求开始:画出它经过的组件,记录数据来源和工具调用,补一个最小评测集,再找出延迟、权限、失败处理或成本上的一个缺口。让 coding agent 参与修复,但由你定义约束、检查证据和承担取舍。
Aide Hub 会继续分享 AI 助手、开发工具和软件工程实践。