大家好,我是你们的技术博主朋友。
最近 AI 编程工具越来越强,不少朋友开始焦虑:既然 AI 都能自动写代码了,我是不是不用再花时间学基础了?是不是直接让 AI 生成整个项目就行?
恰好最近看到吴恩达关于 Agentic Coding 时代基本功更重要的一些观点,我深有感触。作为一个从手工写 SQL、手动配 Spring 走到今天的老开发,我想结合自己的项目经验,认真聊聊这个话题,并且给出一套在 Agentic Coding 时代依然非常实用的基本功学习路径。
这篇文章会围绕三个核心问题展开:
- Agentic Coding 到底是什么,它和普通 AI 辅助编程有什么区别。
- 为什么 AI 越强,开发者的基本功反而越重要。
- 具体怎么做,才能让基本功成为你驾驭 AI 的核心竞争力。
文章后半部分会给出大量代码示例、调试案例、测试思路和工程实践建议,不管你是刚入门的新手,还是已经在用 AI 提效的开发者,都能从里面找到有用的东西。
1. 背景与核心概念
1.1 什么是 Agentic Coding
在讨论基本功之前,先要把 Agentic Coding 这个概念说清楚。
Agentic Coding,翻译过来可以理解为“代理式编程”或“智能体编程”。它和我们平时用的代码补全工具不太一样。
传统的 AI 辅助编程,比如自动补全、代码提示、单行生成,本质上是“你写一句,AI 接一句”。你仍然掌握着整体方向,AI 只是帮你加快打字速度。
而 Agentic Coding 强调的是:AI 作为一个智能体(Agent),能够接收一个相对完整的任务目标,然后自主规划步骤、编写代码、运行测试、检查结果,甚至根据失败信息自动修改代码,直到完成任务。
通俗点说:
- 以前你问 AI:“这个 Python 函数怎么写?” AI 给你一段代码。这是被动辅助。
- 现在你告诉 Agent:“请帮我实现一个用户注册接口,包含参数校验、密码加密、重复注册检查,并编写单元测试,跑通后把结果告诉我。” Agent 自己拆任务、自己写代码、自己跑测试、自己修 bug。这是主动代理。
听起来很美好,对吧?
但在实际项目落地时,你会发现一个问题:Agent 确实能写出很多代码,但你自己能不能看懂它写的代码?能不能判断它写的方案是否符合项目规范?能不能在它跑偏的时候及时纠正?这些能力,恰恰就是基本功。
1.2 吴恩达观点的核心含义
吴恩达的观点并不是“AI 编程不重要”,也不是“大家不要用 AI”。他的核心意思是:在 Agentic Coding 时代,开发者对底层原理、编程基础、代码质量的理解变得比以往更重要。
为什么?
因为 AI 生成代码的效率提高之后,代码审查(Code Review)、问题定位、系统设计、质量把控这些环节,变成了开发者的主要工作。你不再只是“写代码的人”,而是“指挥 AI 并验证结果的人”。
如果你基本功不扎实,会出现什么情况?
- AI 生成的代码运行报错,你完全不知道从哪排查。
- AI 生成了一个看似正确的函数,但存在严重性能问题,你没有发现。
- AI 生成的 SQL 没有加 WHERE 条件,你直接执行了,数据全没了。
- AI 按它的理解实现了一个功能,但和你的业务需求完全是两码事,你却没有立刻察觉。
这些问题的根源,不是 AI 不够聪明,而是开发者缺少足够的基本功去判断、纠正和把控 AI 的输出。
所以吴恩达说基本功更重要,其实是在提醒我们:工具越强大,使用工具的人越需要有判断力。
1.3 为什么 AI 编程时代依然需要扎实基本功
我们再从技术演进的视角看一眼。
过去十年,软件开发经历了几个阶段:
- 手工编码时代:所有代码必须自己写,不懂语法就写不出程序。
- 框架封装时代:Spring Boot、MyBatis、Django 这类框架帮你省掉大量重复代码,你只需要懂配置和业务逻辑。
- AI 辅助时代:Copilot、ChatGPT 帮你生成模板代码、工具函数、测试用例。
- Agentic Coding 时代:AI 主动帮你规划、实现、测试、修复整个功能模块。
你会发现,每一轮工具升级,确实都降低了“写出代码”的门槛。但同时,每一轮升级对开发者的“判断力”要求反而变高了。
框架帮你省事,但你必须理解框架的运行机制,否则遇到诡异 bug 完全无从下手。AI 帮你写代码,但你必须理解代码为什么这么写,否则连怎么改都不敢动。
如果把软件开发比作开车,那基本功就是交通规则、车辆原理和驾驶技术。AI 是自动辅助驾驶,能帮你减轻操作负担,但你不能因为开了辅助驾驶,就完全不懂刹车失灵该怎么处理。
2. 环境准备与工具说明
聊完概念,我们进入实操环节。既然要讨论 Agentic Coding 时代的基本功,那我们需要一套可以实际动手的环境。
2.1 开发环境版本说明
本文示例以常见环境为例,版本需要根据你的实际项目情况调整,重点演示思路。
- 操作系统:Windows 10/11、macOS、Linux 均可。
- 编程语言:Python 3.8+ 或 Java 8+
- 开发工具:VS Code、IDEA 或 PyCharm
- 版本管理工具:Git
- 构建工具:Maven(Java)或 pip(Python)
- 测试框架:JUnit 5(Java)、pytest(Python)
注意:如果你已经在企业中使用了特定的技术栈,不要为了跟随本文示例而强行更换版本,关键是理解思路。
2.2 关于 AI 编程工具
目前常见的 AI 编程工具有很多,例如 GitHub Copilot、Cursor、通义灵码、CodeGeeX 等。它们的能力各有差异,但整体趋势都是朝着 Agentic Coding 的方向演进。
在本文中,我不会针对某一款工具做详细教学,而是围绕“基本功如何配合 AI 使用”这个主题展开。即使你使用的工具和我的不同,底层的方法论仍然适用。
建议你可以准备两个环境:
- 一个用于 AI 辅助编码实验,体验 Agent 自动写代码、跑测试。
- 一个用于纯手工练习基本功,确保自己离开 AI 也能完成核心开发任务。
这两个环境并不冲突,实际上它们是互补的。
2.3 准备一个示例项目
为了便于后续实战演示,我准备了一个非常简单的业务场景:用户注册模块。
这个模块包含以下功能:
- 接收用户名、密码、邮箱。
- 校验参数合法性。
- 密码加密存储。
- 检查用户名是否重复。
- 保存用户信息。
- 编写单元测试。
这是一个非常经典的入门级业务模块,覆盖了参数校验、异常处理、数据访问、单元测试等基本功点,非常适合用来练习,也非常适合用来观察 AI 在实现过程中的表现。
3. 基本功到底包含哪些能力
很多人一提“基本功”,第一反应是语法、数据结构、算法。这些当然是基本功,但只有这些远远不够。
在 Agentic Coding 时代,我认为基本功应该包括以下六个方面。
3.1 需求拆解与问题定义能力
这是很多人忽视的一项基本功。
AI 编程工具最擅长的是“接到明确任务后执行”,而不是“帮你搞清楚你到底想要什么”。如果你无法把一个模糊的业务需求拆解成清晰、可验证的小任务,AI 就没法给你有用的输出。
举个例子。
不好的需求描述:
帮我写一个用户注册功能。
这个描述太宽泛了。AI 可能给你生成一套复杂的 Spring Security 方案,也可能给你一个最简单的表单提交,完全取决于它的训练数据。
好一些的需求描述:
帮我实现一个用户注册接口,接收 username、password、email 三个参数。要求:
- username 长度 4-20 个字符,只能包含字母数字下划线。
- password 长度至少 8 位,必须包含字母和数字。
- username 不能重复,重复时返回错误码 1001。
- 密码使用 BCrypt 加密存储。
- 保存成功返回用户 ID。 请给出接口定义、实现代码、单元测试。
这个描述包含了输入、输出、约束、错误码、安全要求。AI 才能给出接近你预期的结果。
所以,需求拆解能力是你和 AI 协作的第一道基本功。
3.2 代码阅读与理解能力
很多人觉得写代码难,其实读代码更难。
在传统开发模式下,你的主要任务是写代码。但在 Agentic Coding 模式下,AI 写出大量代码之后,你需要快速判断这些代码是否符合需求、是否存在隐患。这就需要很强的代码阅读能力。
代码阅读能力包括:
- 快速理解函数的作用。
- 追踪数据在代码中的流转。
- 识别隐藏的副作用。
- 判断异常处理是否充分。
- 理解设计模式的应用。
我建议每个开发者都养成一个习惯:AI 生成的每一段核心代码,都要自己读一遍,读不懂的地方要追问、要查文档、要打断点调试,而不是直接信任。
3.3 调试与问题定位能力
这是基本功中的基本功。
AI 生成的代码一定会出错。这不是能力问题,而是概率问题。大型语言模型根据概率生成代码,难免会有逻辑错误、边界遗漏、API 误用等问题。
当你拿到一段有问题的代码时,如何定位问题?
我自己的排查顺序通常是这样:
- 先看报错信息,定位是哪一行出的错。
- 沿着调用链,确认传入的数据是否合法。
- 查看关键变量的值,确认是否符合预期。
- 缩小范围,用一个最小示例复现问题。
- 修复后,再跑一遍完整测试。
这套排查过程不依赖任何 AI 工具,但它决定了你用 AI 时的效率。如果 AI 生成的代码一直报错,你不会调试,就只能反复把报错贴给 AI,效率非常低。
3.4 测试与验证能力
Agentic Coding 时代,测试能力的重要性被大幅提高了。
原因很简单:AI 生成代码的速度快,但正确性需要验证。如果你不会写测试,就没办法快速、自动化地验证 AI 的输出质量。
很多同学会说:“我可以让 AI 自己写测试呀。”
没错,AI 确实能写测试。但问题来了:AI 写的测试可能和 AI 写的功能代码存在同样的错误假设。也就是说,它可能从错误的逻辑出发,写出的测试刚好验证了错误的实现。
这时候,就需要你自己来设计测试用例,补充边界情况,甚至要能判断“哪些测试是有意义的,哪些是自欺欺人”。
基本的测试能力包括:
- 能写单元测试,覆盖正常流程。
- 能测试边界条件,比如空字符串、超长字符串、特殊字符。
- 能测试异常路径,比如重复注册、数据库连接失败。
- 能阅读测试覆盖率,判断薄弱环节。
3.5 架构设计与代码组织能力
AI 擅长生成函数、类和模块,但它很难替你做全局规划。
一个大型项目的架构风格、模块边界、依赖关系、错误处理策略、日志规范,这些都需要人来决定。AI 只是在你的架构框架内,帮助填充代码。
如果基本功不够,你很可能被 AI 的输出牵着走。AI 生成一个类,你就加一个类;AI 生成一种风格,你就接受一种风格。最后项目变成一个大杂烩,技术债越来越重。
真正扎实的开发者,会给 AI 设定边界:
- 明确哪些模块由 AI 生成,哪些必须自己控制。
- 明确统一异常处理方式。
- 明确命名规范。
- 明确事务边界。
- 明确日志输出规范。
3.6 安全意识与性能意识
这两个意识往往被忽视,但非常重要。
AI 生成的代码,在语义上可能是正确的,但在安全和性能上可能存在隐患。
安全方面,常见问题包括:
- SQL 拼接导致注入风险。
- 密码明文存储。
- 越权访问未校验。
- 敏感信息写入日志。
- 文件上传未校验类型。
性能方面,常见问题包括:
- 在循环中查询数据库。
- 大量数据一次性加载到内存。
- 缺少数据库索引。
- 正则表达式死循环。
- 使用 N+1 查询模式。
如果你不懂这些,AI 生成的代码看起来跑得通,但一旦上线,轻则性能告警,重则安全事故。
4. 实战案例:基本功如何提升 AI 协作效率
下面我们通过几个实战场景,看看基本功是如何实际影响 AI 协作效率的。
4.1 场景一:给 AI 一个清晰的问题描述
我们先用一个 Python 函数来演示。
假设你要实现一个函数:把一个字符串中的手机号中间四位用星号隐藏。
如果你直接问 AI:
写一个手机号脱敏函数。
AI 可能会给出这样的代码:
def mask_phone(phone): return phone[:3] + '****' + phone[7:]这个函数看起来没错,但存在很多问题:
- 没有校验手机号长度。
- 没有处理空值。
- 没有校验是否真的是手机号。
- 如果用户传入一个 11 位但不是手机号的字符串,也照样脱敏。
- 如果业务上手机号可能包含国家区号,比如 +86,就会出错。
但如果你的需求拆解基本功足够好,你会这样描述:
请实现一个 Python 函数 mask_phone,输入参数为手机号字符串。要求:
- 如果输入为空或 None,返回空字符串。
- 如果输入长度不是 11 位,抛出 ValueError。
- 只保留前 3 位和后 4 位,中间 4 位用 * 代替。
- 参数只接受字符串类型。
AI 给出的代码就会严谨很多:
def mask_phone(phone: str) -> str: if phone is None or phone == '': return '' if not isinstance(phone, str): raise TypeError('phone must be a string') if len(phone) != 11: raise ValueError('phone length must be 11') return phone[:3] + '****' + phone[7:]看到了吗?同样的工具,同样的模型,需求的清晰程度决定了输出的质量。这不是 AI 能力的问题,是你的基本功问题。
4.2 场景二:读懂 AI 生成的代码并发现问题
下面是一段 AI 生成的 Java 代码片段,用于从数据库查询用户列表。
假设 AI 给出的代码如下:
// 文件路径:src/main/java/com/example/demo/service/UserService.java public List<User> getUsersByAge(int age) { String sql = "SELECT * FROM users WHERE age = " + age; List<User> users = jdbcTemplate.query(sql, new UserRowMapper()); return users; }这段代码能跑吗?能跑。但这显然存在 SQL 注入风险。
如果你具备扎实的 SQL 基本功和安全意识,你会立刻发现问题,并改造成这样:
// 文件路径:src/main/java/com/example/demo/service/UserService.java public List<User> getUsersByAge(int age) { String sql = "SELECT * FROM users WHERE age = ?"; List<User> users = jdbcTemplate.query(sql, new Object[]{age}, new UserRowMapper()); return users; }改动很小,但安全性完全不同。AI 能生成前一种写法,是因为互联网上有大量不安全的示例代码。你的基本功,就是识别并纠正这些问题的最后一道防线。
4.3 场景三:调试 AI 生成的代码
这是一个非常常见的场景。AI 写了一段代码,运行报错,我们把例子简化一下。
假设 AI 生成了如下 Python 代码:
def calculate_average(scores): total = sum(scores) return total / len(scores)我们调用它:
scores = [90, 85, 100] print(calculate_average(scores))输出结果:
91.66666666666667看起来没问题。但如果我们传入空列表呢?
scores = [] print(calculate_average(scores))程序直接崩溃:
ZeroDivisionError: division by zero如果基本功扎实,你就会知道:除法运算前必须检查除数是否为 0。修复方式很简单:
def calculate_average(scores): if not scores: return 0 total = sum(scores) return total / len(scores)这个例子很基础,但它揭示了一个核心逻辑:AI 生成的代码,通常覆盖的是“正常路径”,而边界条件的处理,需要靠你的基本功去补充。
在实际工作中,AI 生成的代码可能比这个复杂得多,比如处理分布式事务、消息队列重试、缓存穿透等问题。如果你连最基础的边界处理都意识不到,就更不可能发现那些深层问题。
4.4 场景四:用测试验证 AI 的输出
我们再来看一个测试的例子。
假设你让 AI 实现一个判断闰年的函数,AI 给出了如下代码:
def is_leap_year(year): return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)这个实现是正确的。但你的任务不是直接信任它,而是用测试用例来验证。
如果你具备扎实的测试基本功,你会设计这些用例:
import pytest def test_is_leap_year(): assert is_leap_year(2000) is True # 世纪年,能被 400 整除,是闰年 assert is_leap_year(2024) is True # 普通年份,能被 4 整除,是闰年 assert is_leap_year(1900) is False # 世纪年,能被 100 整除但不能被 400 整除,不是闰年 assert is_leap_year(2023) is False # 普通年份,不能被 4 整除,不是闰年运行测试:
pytest test_leap_year.py -v预期结果:
test_leap_year.py::test_is_leap_year PASSED这个测试用例集合,就验证了 AI 输出在边界情况上的正确性。如果你没有一个“用测试验证代码”的习惯,AI 生成的代码即使有问题,你也很难第一时间发现。
4.5 场景五:重构 AI 生成的代码
AI 生成的代码,往往能实现功能,但在可维护性上可能不够好。
假设 AI 生成了一段代码,用来处理订单状态流转:
def process_order(order, action): if action == "pay": order.status = "PAID" order.paid_time = datetime.now() send_notification(order.user_email, "支付成功") elif action == "ship": if order.status != "PAID": raise Exception("订单未支付,不能发货") order.status = "SHIPPED" order.shipped_time = datetime.now() send_notification(order.user_email, "已发货") elif action == "complete": if order.status != "SHIPPED": raise Exception("订单未发货,不能完成") order.status = "COMPLETED" else: raise Exception("未知操作")这段代码功能基本正确,但是所有逻辑堆在一个函数里,可读性差,扩展性也差。如果业务上要增加“退款”“取消”等操作,这个函数会越来越臃肿。
基本功扎实的开发者,会考虑用状态模式或者至少拆分成独立函数:
class OrderService: def pay(self, order): order.status = "PAID" order.paid_time = datetime.now() send_notification(order.user_email, "支付成功") def ship(self, order): if order.status != "PAID": raise Exception("订单未支付,不能发货") order.status = "SHIPPED" order.shipped_time = datetime.now() send_notification(order.user_email, "已发货") def complete(self, order): if order.status != "SHIPPED": raise Exception("订单未发货,不能完成") order.status = "COMPLETED"这个重构并不复杂,但它体现了一个开发者对代码结构、职责划分、可维护性的理解。AI 可以帮你生成初始版本,但让代码变得好维护、好扩展,依然需要你的基本功。
5. 常见问题与排查思路
在学习和使用 AI 编程的过程中,很多同学会遇到一些共性问题。这里我整理了一张排查表,供大家参考。
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| AI 生成的代码运行报错 | 当前上下文不完整,AI 基于错误假设编码 | 检查报错信息,补全缺失变量和方法;缩小问题范围后重新提问 |
| AI 生成的代码能用但看不懂 | 基础语法不熟,缺乏代码阅读训练 | 先拆解函数结构,逐行理解;多阅读开源项目源码,逐步提升阅读能力 |
| AI 一直生成同一种错误写法 | 需求描述中缺少约束条件 | 在提示中明确禁止使用的 API、必须遵守的规范、边界条件 |
| 项目越写越乱,AI 改了一处又坏一处 | 缺少架构边界和依赖管理 | 先明确模块结构,规定 AI 只能改哪些文件,不允许改哪些文件 |
| 自动化测试无法覆盖关键逻辑 | 测试设计能力不足,只测正常路径 | 学会画测试矩阵:正常分支、异常分支、边界值、空值、重复提交 |
| 对 AI 生成结果盲目信任导致线上事故 | 缺少代码审查和验证环节 | 建立强制 Code Review 流程,核心代码必须人工审查并补安全用例 |
以“AI 生成的代码能用但看不懂”为例,这里我多说几句。
很多初学者在遇到这种情况时,习惯性地选择跳过。但如果你真的想长期在编程这条路上走下去,我建议你采用以下策略:
- 把 AI 生成的代码复制到编辑器里。
- 逐行打断点,观察变量变化。
- 把不认识的语法或 API 单独查询。
- 尝试在不改变功能的前提下,用自己的方式重写一遍。
这个过程可能会比较慢,但它带来的提升是非常明显的。你会发现,一旦你真正理解了一段代码,后续使用 AI 的效率会成倍提高。
6. 最佳实践与工程建议
结合我自己的开发经验,这里分享几条在 Agentic Coding 时代非常实用的工程建议。
6.1 明确 AI 的职责边界
在实际项目中,不要把所有代码都交给 AI 生成,也不要完全拒绝 AI。建议如下:
- 模板代码:如 Controller 层增删改查、DTO 转换、简单的工具函数,交给 AI。
- 核心业务逻辑:必须自己先设计清楚,再让 AI 辅助实现。
- 架构设计:由人完成,AI 只提供参考建议。
- 异常处理和边界条件:AI 生成后需要人工补充。
- 测试用例:AI 可以生成初版,但核心用例必须自己设计和补充。
6.2 建立代码审查习惯
无论 AI 生成的代码多么顺眼,都要经过审查。审查时重点关注:
- 业务逻辑是否与需求一致。
- 是否存在越权、注入、敏感信息泄露等安全问题。
- 是否存在明显的性能问题。
- 异常处理是否完整。
- 命名是否清晰,结构是否合理。
如果团队有条件,建议强制要求所有 AI 生成代码也必须走 Code Review 流程。
6.3 用测试保护 AI 重构
AI 在重构代码时,可能会引入隐藏问题。解决办法是在重构前,确保测试覆盖率达到一定水平。这样 AI 重构后,跑一遍测试就能发现大部分问题。
这也是为什么测试基本功如此重要的原因。它不仅能验证你的代码,也能验证 AI 的代码。
6.4 持续做基础训练
不要因为有了 AI 就放弃基础训练。我的建议是:
- 每周抽出时间,不用 AI,手写一个完整的业务模块。
- 每周阅读一段开源项目源码,写阅读笔记。
- 每周练习一个调试场景,尝试不用 AI 独立定位问题。
- 每周做一次安全审查,检查项目中是否有常见漏洞模式。
这些训练会不断强化你的基本功,让你在使用 AI 时更游刃有余。
6.5 关注提示词设计,但不迷信提示词
提示词工程确实是提升 AI 输出质量的重要手段,但提示词只是基本功的补充,而不是替代品。
如果你对一个技术领域没有基本的理解,你再怎么优化提示词,也很难准确判断 AI 输出是否正确。反过来,如果基本功扎实,即使提示词稍微差一点,你也能快速发现并修正 AI 的错误。
所以我的建议是:把提示词优化看作基本功的自然延伸,而不是独立技能。
7. 总结与后续学习方向
Agentic Coding 时代已经来了。AI 正在从一个“代码补全工具”进化成“能够独立完成开发任务的智能体”,这确实会改变我们的工作方式。
但正如吴恩达所说,越是在这样的时代,基本功越重要。工具越强,使用工具的人的判断力就越关键。
这篇文章中,我重点讲了六项基本功:
- 需求拆解与问题定义能力。
- 代码阅读与理解能力。
- 调试与问题定位能力。
- 测试与验证能力。
- 架构设计与代码组织能力。
- 安全意识与性能意识。
还用 Python 和 Java 的示例演示了基本功如何直接影响 AI 协作效率。
接下来,你可以从这几个方向继续学习:
- 深入学习数据结构与算法,这是所有基本功的底层支撑。
- 学习数据库原理,包括索引、事务、锁,这对理解 AI 生成的数据库代码非常关键。
- 学习设计模式,提升代码组织能力。
- 学习安全编程,掌握常见 Web 漏洞的原理与修复方式。
- 多参与实际项目,在真实业务中打磨调试和测试能力。
如果你也想在 Agentic Coding 时代保持竞争力,我建议你从今天开始,制定一个“基本功训练计划”,每天留出半小时专门做基础练习。相信我,这些时间投入的回报,会超乎你的想象。
如果这篇文章对你有帮助,可以收藏备用,也欢迎在评论区分享你使用 AI 编程时遇到的坑。我们下篇文章再见。