1. 项目概述:当AI成为主力程序员,命名的难题反而被放大了

“计算机科学领域只有两件难事:缓存失效和给东西起名字。” Phil Karlton 的这句名言,在AI编程时代被赋予了全新的含义。作为一名在SRE/DevOps领域摸爬滚打了十多年的工程师,过去一年我深度将AI工具融入日常工作流。在运维场景里,AI就像一个极其高效且绝对服从的助手——通过MCP协议跨服务收集指标、生成Terraform模块、编排Helm Chart、自动化那些重复到令人麻木的脚本。这里没有“哇塞”的瞬间,只有纯粹的速度提升。我不需要它发挥创意,更不希望它自作主张,我只需要可预测的、符合我已有模板和约束的输出。控制权,始终牢牢握在我手里。

然而,当我切换上下文,开始用AI辅助真正的软件开发时,一切都变了。作为AWS Community Builder,我有机会提前体验像Kiro这类基于Anthropic等大模型的智能开发环境。工具本身强大得令人惊叹,但它们却无情地暴露了一个更深层的问题——这个问题不在AI,而在我们人类自己。真正的瓶颈,从来不是生成代码的速度,而是我们如何清晰、无歧义地描述我们到底想要什么。这不是语法问题,也不是框架选型问题,甚至不是架构设计问题,而是 语言和定义 的问题。如果你的指令模糊、前后矛盾或充满了未经言明的假设,那么AI的输出就会完美地反映这些缺陷,并且它不会像人类同事那样主动追问细节,它只会生成一堆“看起来正确”但“本质上错误”的东西。而这一切混乱的根源,往往始于一个最基础的动作:命名。

2. 核心困境解析:为什么糟糕的命名在AI时代是灾难性的

2.1 一个真实的“命名泥潭”案例

让我分享一个近期处理的真实项目。这是一个废弃了近8年的旧系统,目标很明确:更新依赖、剔除过时功能、增加新特性。代码本身并不复杂,但真正的噩梦是命名。整个代码库中,同一个核心业务概念——“媒体文件”,在不同的模块里有着完全不同的称呼:

  • 后端服务 数据库模型 里,它叫 Product (产品)。
  • 旧版移动端APP 的代码中,它被称作 Track (音轨)。
  • 管理后台前端 的组件和API交互里,它又变成了 Item (条目)。

调查后发现,这是不同时期、不同外包团队各自为政的后果。从人类程序员的角度看,这很烦人,需要不断进行“脑内翻译”。但从AI的角度看,这简直是灾难。大模型的工作原理是基于上下文和统计规律进行“推断”。当它看到 Product.price Track.duration Item.metadata 时,它会努力寻找这些实体间的潜在关联。它会“猜测” Product 可能是一个电商商品, Track 属于一个播放列表,而 Item 可能是一个待办事项。基于这些错误的猜测,AI生成的代码、数据库查询、甚至是业务逻辑,都会从一开始就走上歧路。

在这个项目里,我不得不先停下所有功能开发,做了三件事:

  1. 回溯真实的领域模型 :抛开代码,与业务方确认这个核心对象到底是什么,有哪些属性和行为。
  2. 统一术语表 :确定一个唯一、准确的名称,我们最终选择了 MediaAsset
  3. 全量重构命名 :在AI的辅助下,进行跨仓库、跨模块的全局重命名。

只有完成这套“正名”仪式后,AI才重新变得可靠。这次经历让我深刻意识到: 在AI编程时代,混乱的命名不再是“技术债”,而是直接堵塞价值交付的“血栓”

2.2 非母语者的独特挑战与意外优势

作为非英语母语者,我遇到了另一个维度的限制:我的词汇量相对较窄,倾向于使用更简单、更通用的词汇。例如,我可能习惯性地说“get user data”(获取用户数据),这个词在技术上是正确的,但语义上非常模糊——是获取用户个人资料?还是获取用户产生的所有数据?对于人类同事,结合上下文和后续追问可以厘清。但对于AI,这种模糊性会导致生成的函数或API端点意图不清,为后续的理解和维护埋下隐患。

然而,这个“劣势”也迫使我养成一个极其重要的习惯: 追求极致的精确性,而非华丽的表达 。因为我无法依赖丰富的词汇来迂回表达,所以我必须更直接、更结构化地定义事物。我会这样描述:

“我们需要一个函数,输入是用户ID(整数类型),输出是一个JSON对象,包含该用户的 profile 字段(姓名、邮箱)和 settings 字段(主题、时区)。函数名需要明确体现这是‘读取’操作,且数据来自数据库主库。”

这种描述虽然不那么“优雅”,但消除了几乎所有歧义。在AI协作中, 精确远胜于生动 。这反而成了一种优势。

3. 方法论转变:从“直接建造”到“先定义,后生成”

大多数开发者初次接触AI编程时,都容易陷入一个效率陷阱:脑子里有一个酷炫的想法,然后立刻对AI说:“做一个类似Twitter的社交应用。” 这是最快得到一堆不可用垃圾的方法。正确的协作模式,应该更像是在与一位极度严谨、但缺乏背景知识的业务分析师或架构师合作。

3.1 五步定义法:为AI绘制精确的蓝图

我总结了一套与AI协作的“五步定义法”,这能从根本上提升生成代码的质量。

第一步:定义核心术语表 在写第一行代码之前,先创建一个纯文本文件(如 TERMINOLOGY.md )或直接在对话中明确。为你的项目定义关键名词。

## 核心实体
- **User**: 系统的注册使用者。属性包括:id (UUID), username (字符串), email (字符串)。
- **Post**: 用户创建的短内容。属性包括:id (UUID), content (文本), author_id (关联User.id)。
- **Timeline**: 一个按时间倒序排列的Post集合,用于展示。

## 关键操作
- **publish**: 特指User创建一个新Post并使其对外可见的动作。
- **follow**: User A 订阅 User B 未来Post的行为。
- **feed**: 为某个User生成的、聚合了其关注者最新Post的Timeline。

这个步骤强制你厘清概念,避免后续出现 Article Tweet Message 混用的局面。

第二步:锁定命名规范 基于术语表,规定具体的命名风格。AI需要明确的规则。

## 命名规范
1.  数据库表名:复数蛇形命名法,如 `users`, `posts`。
2.  模型类名:单数大驼峰命名法,如 `User`, `Post`。
3.  函数/方法名:动词开头,小驼峰命名法,需明确意图,如 `getUserFeed()`, `createNewPost()`。
4.  布尔变量/函数:以 `is`, `has`, `can` 开头,如 `isPublished`, `hasLiked`。

你可以直接把这个规范发给AI:“所有生成的代码请严格遵守以上命名规范。”

第三步:描述实体关系与业务流程 用简单的句子或图表描述(可以用文字描述图表)系统如何运作。

## 关系
- 一个 User 可以拥有多个 Post (一对多)。
- 一个 User 可以关注多个其他 User,也可以被多个 User 关注 (多对多,通过 `follows` 表连接)。

## 发布流程
1.  User 在客户端输入内容,点击“发布”。
2.  客户端调用 `POST /api/posts`,传入 `{ content: “...” }`。
3.  后端验证用户身份,在 `posts` 表创建记录,`author_id` 为当前用户。
4.  后端异步任务将新 Post 推送到所有关注者的 Feed 缓存中。
5.  返回创建成功的 Post 数据给客户端。

第四步:主动邀请AI提问 这是关键一步。不要假设AI都懂。主动引导它:“基于以上信息,为了生成完整的用户认证模块代码,你需要向我提问哪些问题来澄清细节?请列出你的问题。” AI可能会问:

  • “用户密码是明文存储还是哈希存储?推荐使用什么哈希算法?”
  • “注册时需要邮箱验证吗?如果需要,邮件模板的大致内容是什么?”
  • “JWT token的过期时间设定为多长合适?”
  • “是否有‘记住我’的功能?其实现逻辑是什么?”

第五步:迭代精炼理解 逐一回答AI的问题。这个过程在帮你查漏补缺,外部化那些你认为“不言自明”的隐含知识。经过几轮问答后,你和AI就对系统有了高度一致的理解。

这时,你再发出指令:“现在,请基于我们讨论的所有细节,使用Python Flask框架和SQLAlchemy ORM,生成用户模型(User model)的完整代码,包含密码哈希逻辑、以及注册和登录的API端点。” 你得到的代码,其可用性会远超第一步就直接生成的结果。

3.2 核心心法:让AI“审问”你

这套方法的本质,是完成一个关键的思维转变: 不要命令AI去“建造”,而要邀请AI来“审问”你。 最有效的提示词(Prompt)可能是:“你现在是一个经验丰富的系统分析师。我将要构建一个[XX系统]。为了能让你为我生成准确可靠的代码,请你向我提出一系列问题,直到你认为已经完全理解了系统的所有核心细节、边界条件和业务规则。请开始提问。”

这模仿了软件开发中需求分析的核心环节。过去,这个环节发生在产品经理、架构师和开发者之间。现在,AI承担了大量“开发者”的即时工作,那么“需求分析师”的角色就必须由使用AI的人来强化。谁能清晰、结构化地定义问题,谁就能驾驭AI,否则就会被AI生成的混乱代码所淹没。

4. 实操指南:在日常工作流中嵌入精准协作

理论需要落地。以下是我将“精准定义”融入日常AI编程工作流的具体做法,主要围绕提示工程展开。

4.1 构建个人或团队的“上下文锚点”

对于重复性的项目类型(如新的微服务、管理后台CRUD),可以创建可复用的“上下文锚点”文档。

示例:启动一个新REST API服务的锚点文档

# 新REST API服务生成规范

## 技术栈
- 语言:Python 3.10+
- Web框架:FastAPI
- 数据库:PostgreSQL, 使用SQLAlchemy 2.0+ ORM
- 认证:JWT, 使用`python-jose`库

## 项目结构(参考)
service-name/
├── app/
│   ├── __init__.py
│   ├── main.py          # FastAPI app初始化
│   ├── core/            # 配置、安全依赖
│   ├── models/          # SQLAlchemy模型
│   ├── schemas/         # Pydantic模型(请求/响应)
│   ├── crud/            # 数据库操作层
│   ├── api/             # 路由端点
│   └── tests/           # 测试文件
├── alembic/             # 数据库迁移
├── requirements.txt
└── .env.example

## 通用规范
1.  所有API端点需有Pydantic模型进行输入输出验证。
2.  数据库模型需包含`id` (UUID)、`created_at`、`updated_at`字段。
3.  错误处理使用HTTP状态码,错误信息格式为 `{“detail”: “message”}`。
4.  所有函数和类需有Google风格docstring。

开始新项目时,直接将此文档发给AI:“请遵循以下规范,为我创建一个名为 bookstore 的API服务,它需要管理 Book Author 两个实体。” AI生成的脚手架代码会立即符合团队约定。

4.2 编写“结构化提示”,而非“对话式请求”

避免开放式的聊天。将你的需求组织成结构化的提示。

低效提示:

“帮我写个函数,处理用户上传的图片。”

高效提示(结构化):

任务 :生成一个图片处理函数。 上下文 :我们在一个Django项目中,使用Pillow库处理图片。 函数规格

  • 函数名 resize_and_compress_image
  • 输入
    1. image_file :一个Django InMemoryUploadedFile 对象。
    2. max_width :整数,默认值800。
    3. max_height :整数,默认值600。
    4. quality :整数(1-100),默认值85。
  • 处理逻辑
    1. 使用Pillow打开 image_file
    2. 保持原图宽高比,将图片缩放到不超过 max_width max_height
    3. 将图片转换为RGB模式(如果原是RGBA)。
    4. 以指定的 quality 将图片保存为JPEG格式。
    5. 将处理后的图片数据保存到Django的 ContentFile 中。
  • 输出 :返回一个新的 ContentFile 对象,包含处理后的图片数据。
  • 异常处理 :如果输入不是有效图片,抛出 ValueError 代码要求 :包含完整的函数定义、导入语句和简要的注释。

4.3 实施“测试驱动提示”

在让AI生成实现代码之前,先让它根据你的描述生成测试用例。这是验证你对需求描述是否清晰无歧义的绝佳方法。

操作流程:

  1. 你描述一个函数或模块的行为:“需要一个函数 calculate_discount(price, user_type) ,普通用户无折扣,VIP用户打9折,年费VIP用户打8折。价格需为正值。”
  2. 提示AI:“根据以上描述,请先为我用Pytest编写这个函数的测试用例,覆盖正常场景和边界条件。”
  3. AI生成的测试用例可能包括:
    def test_calculate_discount_regular_user():
        assert calculate_discount(100, “regular”) == 100
    
    def test_calculate_discount_vip_user():
        assert calculate_discount(100, “vip”) == 90
    
    def test_calculate_discount_annual_vip():
        assert calculate_discount(100, “annual_vip”) == 80
    
    def test_calculate_discount_negative_price():
        with pytest.raises(ValueError):
            calculate_discount(-10, “vip”)
    
    def test_calculate_discount_invalid_user_type():
        with pytest.raises(ValueError):
            calculate_discount(100, “unknown”)
    
  4. 审查这些测试用例 。它们是否完全符合你的预期?如果测试用例的逻辑与你脑中设想有出入,那说明你的原始描述存在二义性。此时修正描述,比生成错误代码后再回头调试要高效得多。
  5. 确认测试用例无误后,再让AI生成函数实现代码:“现在,请实现能通过上述所有测试的 calculate_discount 函数。”

5. 常见陷阱与排查清单

即便掌握了方法,实践中依然会踩坑。以下是我总结的常见问题及应对策略。

5.1 AI生成代码的典型“异味”及根源

当你发现AI生成的代码出现以下“异味”时,通常不是AI笨,而是你的提示不够清晰。

代码“异味” 可能的原因 修正策略
函数/变量名过于通用 提示中缺乏具体的命名规范或上下文。 在提示中明确命名要求,或提供示例。如:“函数名应体现具体操作,如 fetchUserProfileFromDatabase 而非 getData 。”
生成了你未要求的额外功能 AI基于其训练数据进行了“合理”推断,但不符合你的特定场景。 在提示中增加 边界声明 。如:“ 仅生成用户认证相关的模型和API,不要生成任何前端界面、邮件服务或管理后台代码。
逻辑复杂或绕弯 你对问题的描述可能包含了不必要的细节或顺序不清。 用更简单、分步骤的方式重新描述需求。先描述输入输出,再描述核心处理步骤。
使用了过时或不推荐的库 未指定技术栈版本或约束。 在提示开头明确技术栈和版本,如:“使用 Spring Boot 3.2+ Java 17 。”
缺少错误处理或输入验证 默认情况下,AI倾向于生成“快乐路径”的代码。 明确要求:“代码需包含完整的输入验证和错误处理,对非法输入抛出清晰的异常。”

5.2 提示工程失败的信号与即时调试

如果AI的输出持续不符合预期,可以按以下步骤进行“提示调试”:

  1. 拆解任务 :你是否让AI一步做了太多事?尝试将“构建一个用户管理系统”拆解成“1. 设计用户数据库模型”、“2. 创建注册登录API”、“3. 实现JWT令牌签发与验证”等多个独立提示。
  2. 提供示例 :AI非常擅长模仿。如果你想要某种特定风格的代码,直接给它看一个例子。“请按照下面这个 Product 模型的风格,创建一个 Order 模型...” 这比用文字描述“风格”有效得多。
  3. 切换“角色”指令 :有时改变AI的“人设”能获得更好的结果。从“你是一个有帮助的助手”变为“你是一个严谨的谷歌软件工程师,注重代码的可读性、可维护性和性能”,其输出倾向会发生变化。
  4. 迭代精炼,而非推倒重来 :不要完全废弃当前的对话上下文。指出当前输出中 具体 哪里不对,并给出修正方向。“这个函数没有处理网络超时的情况。请在此基础上增加超时重试逻辑,最多重试3次,每次间隔2秒。” AI能在原有基础上进行改进。
  5. 检查“思维链” :对于复杂逻辑,可以要求AI“逐步思考”。在提示中加入:“请一步步推理,并给出最终代码。” 许多高级AI工具会展示其推理过程,这能帮你发现它是如何误解你的描述的。

5.3 保持控制:AI是副驾驶,你仍是机长

最后,也是最关键的一点: 永远不要盲目信任AI生成的代码 。无论它看起来多么完美。

  • 代码审查是必须的 :像审查人类同事的代码一样审查AI的代码。检查逻辑、安全性(如SQL注入风险)、性能以及是否符合项目规范。
  • 运行测试 :生成代码后,立即运行你已有的测试套件,或者运行AI自己生成的测试(如果你采用了“测试驱动提示”法)。
  • 理解关键代码 :对于核心业务逻辑、安全相关的代码(如加密、认证),你必须确保自己完全理解其工作原理。不要将“黑盒”代码直接部署到生产环境。
  • 知识留存 :AI帮你解决了某个复杂问题后,花几分钟时间阅读并理解它提供的解决方案。这不仅是学习,也是为了未来维护。你不能在每次出问题时都去问AI“这段代码是干嘛的?”

Phil Karlton说得对,命名依然很难。但在AI编程时代,这项能力从一项“优秀工程师的素养”升级为了“有效开发者的核心生存技能”。AI没有消除软件工程的复杂性,它只是把复杂性从“敲键盘实现”转移到了“前期的清晰思考与定义”。最大的受益者,将不再是那些打字最快的程序员,而是那些能最清晰、最无歧义地描述问题、定义边界的人。这或许正是这个时代对我们所有人提出的一项新挑战,也是一次新的机遇。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐