从恐惧到依赖:我用AI写代码和调试的真实体验与技巧
引言
还记得第一次尝试用AI写代码时的场景吗?我当时的体验是:生成一段看起来完美的代码,结果一运行就报错,然后花了比手写多两倍的时间去修复。这种“鸡肋”感让很多开发者对AI编程工具敬而远之。
然而,仅仅半年后,我的日常工作已经离不开AI了。从编写单元测试到调试棘手的并发Bug,AI成为了我最得力的“结对编程伙伴”。本文将分享我在这段时间积累的实战经验,包括如何让AI写出可用的代码、如何利用它进行高效调试,以及必须避开的坑。
一、AI写代码:不只是“复制粘贴”
很多人把AI写代码等同于“让AI生成一段代码,然后直接复制到项目中”。这是最大的误区。高质量的AI辅助编程更像是一个迭代的协作过程。
1.1 从模糊需求到精确指令
AI无法读取你的大脑,它只能理解你输入的提示词。一个模糊的提示如“写一个排序算法”和“用Python写一个针对大型数据集的快速排序,要求原地排序且时间复杂度为O(n log n)”得到的结果天差地别。
实战案例:生成一个REST API端点
假设我们需要一个用户注册接口。新手可能会这样问:
写一个用户注册的API
AI生成的代码往往缺乏错误处理、输入验证和安全性考虑。而经验丰富的开发者会这样分解任务:
- 定义数据模型:先让AI生成User模型(包含用户名、邮箱、密码哈希等字段)。
- 生成业务逻辑:要求AI实现密码加密、邮箱格式验证、用户名唯一性检查。
- 生成控制器:最后组装成完整的POST /api/register端点。
示例提示词(分步骤):
第一步:用Python和FastAPI创建一个User数据模型,包含username(字符串,唯一)、email(字符串,格式验证)、password_hash(字符串,存储bcrypt哈希值)。
第二步:编写一个函数register_user(db: Session, user: UserCreate),实现以下逻辑:
- 检查邮箱是否已被注册
- 检查用户名是否已被占用
- 使用bcrypt对密码进行哈希
- 将新用户写入数据库
第三步:基于以上函数,创建一个POST /api/register端点,返回201状态码和用户信息(不包含密码哈希)。
AI输出示例(部分):
from fastapi import FastAPI, HTTPException, Depends
from sqlalchemy.orm import Session
import bcrypt
# ... 模型定义 ...
def register_user(db: Session, user: UserCreate):
# 检查邮箱是否存在
existing_email = db.query(User).filter(User.email == user.email).first()
if existing_email:
raise HTTPException(status_code=400, detail="Email already registered")
# 检查用户名是否存在
existing_username = db.query(User).filter(User.username == user.username).first()
if existing_username:
raise HTTPException(status_code=400, detail="Username already taken")
# 密码哈希
hashed_password = bcrypt.hashpw(user.password.encode('utf-8'), bcrypt.gensalt())
# 创建用户
db_user = User(username=user.username, email=user.email, password_hash=hashed_password)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
关键点:通过拆解需求、提供上下文(如数据库Session、返回格式),AI生成的代码几乎可以直接集成到项目中,仅需微调。
1.2 代码补全 vs. 代码生成
GitHub Copilot这类工具擅长代码补全,而ChatGPT更适合代码生成。理解这两者的区别很重要:
- 代码补全:你写一个函数签名,AI帮你填充函数体。适合已知模式的重复性工作,如CRUD操作、数据转换。
- 代码生成:你描述一个功能,AI从零生成完整代码块。适合探索新库、编写测试用例或生成配置代码。
小技巧:在Copilot中,如果你觉得补全不够准确,可以尝试先写一段详细注释,再回车触发补全。注释就是你的提示词。
二、AI调试:从“黑盒”到“透明”
调试是AI最被低估的能力。传统调试依赖断点和日志,而AI可以帮你进行静态代码分析和错误根因推理。
2.1 错误信息的“翻译官”
当遇到一个看不懂的错误堆栈时,直接把错误信息丢给AI是最快的解决方式。
真实场景:一个Python项目中遇到了RecursionError: maximum recursion depth exceeded。
我的提示词:
我有以下Python代码(粘贴代码),运行时抛出RecursionError。请分析为什么会出现无限递归,并给出修复方案。注意:代码中使用了装饰器@lru_cache。
AI分析: AI指出,虽然使用了@lru_cache,但递归函数中有一个参数是可变对象(如列表),导致缓存失效,每次调用都重新计算,从而触发递归深度限制。修复方案是将可变参数转换为不可变元组。
关键点:AI不仅指出了错误,还解释了为什么缓存失效,这是传统调试器无法做到的。
2.2 单元测试的“自动生成器”
编写单元测试往往比写业务代码更耗时。AI可以极大地加速这一过程。
示例:为上述register_user函数生成测试
提示词:
为以下register_user函数编写pytest单元测试。要求:
1. 测试正常注册流程
2. 测试重复邮箱注册
3. 测试重复用户名注册
4. 使用unittest.mock模拟数据库Session
AI输出:
import pytest
from unittest.mock import MagicMock, patch
from your_module import register_user, UserCreate
def test_register_user_success():
# 模拟数据库
db = MagicMock()
db.query.return_value.filter.return_value.first.return_value = None
user_data = UserCreate(username="testuser", email="test@example.com", password="securepassword")
result = register_user(db, user_data)
# 验证用户被添加
db.add.assert_called_once()
db.commit.assert_called_once()
assert result.username == "testuser"
def test_register_user_duplicate_email():
db = MagicMock()
# 模拟已存在的邮箱
db.query.return_value.filter.return_value.first.side_effect = [MagicMock(), None]
user_data = UserCreate(username="testuser2", email="existing@example.com", password="pass")
with pytest.raises(HTTPException) as exc:
register_user(db, user_data)
assert exc.value.status_code == 400
经验:AI生成的测试通常覆盖了主要路径,但边界条件(如超长用户名、空密码)需要手动补充。把AI生成的测试作为起点,然后根据业务逻辑增强。
三、必须避开的陷阱
3.1 幻觉问题:AI会“编造”不存在的API
这是最危险的陷阱。AI可能会为你生成一个看似合理的函数调用,但实际上该函数并不存在。例如,让AI写一段使用某个第三方库的代码,它可能“发明”一个方便但不存在的方法。
解决方案:
- 交叉验证:对于不熟悉的库,让AI生成代码后,一定要查阅官方文档确认API是否存在。
- “请提供文档链接”:在提示词中要求AI提供官方文档引用,虽然AI可能也会编造链接,但至少会促使它生成更准确的代码。
3.2 安全漏洞:AI不关心你的安全
AI生成的代码通常关注功能实现,而忽略安全性。例如,它可能会生成直接拼接SQL字符串的代码(SQL注入风险),或者将密钥硬编码在代码中。
最佳实践:
- 永远不要直接使用AI生成的密码学或认证代码,除非你完全理解其原理。
- 在提示词中明确要求:“请使用参数化查询防止SQL注入”或“请使用环境变量管理密钥”。
3.3 上下文丢失:长对话中的“失忆”
在长时间对话中,AI可能会忘记之前的约定。例如,你定义了项目使用SQLAlchemy,但后续让它生成代码时,它可能突然使用Django ORM。
解决方案:
- 定期总结上下文:每几轮对话后,主动总结当前使用的库、框架和约定,让AI确认。
- 使用系统提示:在ChatGPT中,可以在对话开始前设置系统角色,例如:“你是一个精通FastAPI和SQLAlchemy的Python开发者,所有代码必须包含类型注解和错误处理。”
四、进阶技巧:让AI成为你的“私人导师”
除了写代码和调试,AI还可以帮助你学习新技术。
场景:学习Kubernetes的Service Mesh。
提示词:
我是一名有5年经验的Java后端开发者,但完全不懂Service Mesh。请用类比的方式解释Istio的核心概念(如Sidecar、VirtualService、DestinationRule),并给出一个微服务A调用微服务B时流量如何被拦截和路由的流程图描述。最后,提供一个简单的YAML配置示例,实现灰度发布。
这种“教学式”提示词,可以让AI根据你的知识水平调整解释深度,比阅读官方文档更高效。
结语
AI写代码和调试并不是要取代开发者,而是将我们从繁琐的重复劳动中解放出来,让我们能专注于架构设计、业务理解和创新。掌握与AI协作的技巧——精确的提示词、分步拆解、交叉验证——是未来开发者必备的核心竞争力。
下次当你面对一个空白的编辑器时,不妨先问问AI:“如果我要实现这个功能,最好的代码结构应该是什么?”你会发现,从恐惧到依赖,只需要一段高质量提示词的距离。
文档信息
- 本文作者:JiliangLee
- 本文链接:https://leejiliang.cn/2026/05/02/%E7%94%A8-AI-%E5%86%99%E4%BB%A3%E7%A0%81%E5%92%8C%E8%B0%83%E8%AF%95/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)