别再怪 AI 犯低级错误!命名不一致才是数据“消失”的元凶

122 阅读5分钟

一、前言:从“命名”这个老笑话说起

计算机领域流传着一个著名的调侃:计算机科学有三大难题——缓存失效、命名,以及差一错误。

这个说法听起来像玩笑,但每一个写过工程代码的人都清楚,其中的“命名”并不轻松。一旦命名出现偏差,误解就会在系统中被放大、传播,并长期存在。

在传统软件工程中,命名不当往往只会导致人类开发者的误用或维护成本上升。然而,当系统的使用者从人变成 AI 时,这个问题被进一步放大了。当类名、接口名或概念划分本身存在歧义或误导时,AI 并不是“犯了低级错误”,而是忠实地执行了一个错误的语义线索

二、背景

一个小的查询功能,用 ES 按条件查询三类数据(告警 Alert、事件 Incident、指标 Metric),返回聚合后的列表。由于这是一个非常简单的功能,我就想试试用 AI 命令行工具直接生成实现,看看它能不能一次搞定。

三、整体交互

序号 输入内容 AI 完成工作 发现的问题
1 输入基本的需求(这里有要求用 ES 查询 基本完成了所有的功能点
  • 指标数据查询方式错误: 查询走了 MySQL
  • 代码可重构: 代码中存在一些重复的代码,可以抽取为公共方法
2 输入第一步发现的问题点 抽取了公共方法,但由于还是没发现指标数据的索引,因此查询方式依旧没变
  • 指标数据查询方式错误: 还是没发现其 ES 索引。
3 提示指标 ES 索引位置 成功写出指标的 ES 查询
4 最后人工优化代码,主要优化点:注释风格、参数校验逻辑、枚举的使用

四、思考

4.1 AI 误判原因

问题:为什么 AI 会找不到指标 Metric 的 ES 索引,但能找到告警 Alert 和事件 Incident 的 ES 索引?

这里可以看下 AI 的思考过程:

AI:
让我查看ES相关的Dao:

glob(**/AlertElasticSearchDao.java)
- Found 1 files

AI:
让我查看指标和事件的ES Dao:

glob(**/MetricElasticSearchDao.java)
- Found 0 files

glob(**/IncidentElasticSearchDao.java)
- Found 1 files

AI:
现在让我查看ES的实体类

glob(**/IncidentElasticSearchDoc.java)
- Found 1 files

glob(**/MetricElasticSearchDoc.java)
- Found 0 files

AI:
让我查看所有ES实体:

glob(**/*ElasticSearchDoc.java)
- Found 2 files

AI:
现在我需要查看指标相关类的结构,看看是否有ES相关的查询:

glob(**/MetricDao.java)
- Found 1 files

发现问题:看完 AI 的思考过程,不难发现原因其实就是 AI 在搜索代码时没发现 MetricElasticSearchDoc 这个类,因为实际的类名叫 MetricEsSearchDoc。因此 AI 认为指标没有 ES 索引,也就导致他最终走了 MySQL 的查询方式。

这里我们可以猜测一下 AI 的思路是怎么样的:

  1. 先看告警 ES:找到 AlertElasticSearchDao/Doc,推断项目统一命名规则为 *ElasticSearchDao/Doc
  2. 套模板找指标 ES:按规则搜 MetricElasticSearchDao/Doc,结果没找到。
  3. 再横向确认:用 *ElasticSearchDao、*ElasticSearchDoc 扫一遍,发现只有 Alert、Incident,没有 Metric。
  4. 得出错误的结论:指标 Metric 没有 ES 实现。
  5. 止损走可跑方案:为了交付功能,转去看 MetricDao,发现里面是 MySQL 查询,就顺着写了。

透过现象看本质

  • 现象:AI 没有遵循我们的设定使用 ES 查询,而是走了 MySQL。
  • 本质:AI 并不是在理解整个业务或架构,而是在用可观察到的命名模式来近似整个系统结构

4.2 如何规避这类问题

其实这个问题算是一个上下文问题,即 AI 没有充足的上下文来实现代码。这里列举一些通用的解决方案:

  1. 提前喂好相关类:主动给出需求涉及到的类(例如我的第三步交互),防止 AI 找不到代码,这也是最简单的方法。
  2. 构建仓库级知识库:维护一份轻量的仓库级索引,明确某类能力在哪、入口是什么、命名规范是什么。
  3. Agent Skill:可以考虑使用最近比较火的 Agent Skill 技术,让 AI 知道 ES 能力有哪些类。
  4. 指定规则:在 System Prompt 中提前告诉 AI,如果实现不了不要乱实现(例如应该用 ES 查询但最终用了 MySQL 查询)

因此,问题不在于 AI 偶尔犯错,而在于我们的工程环境是否让它“有线索可循”,为 AI 提供友好的运行环境尤为重要。

五、总结

AI 优点 AI 缺点
  • 功能基本正确: 代码实现的功能都是符合预期的。
  • 注释清晰: 生成的代码通常自带解释,阅读成本低,对后续维护友好。
  • 自我检查: 在写完代码后会用 maven compile 来检查能否编译通过, 如果不通过还能自我纠错(比如 checkstyle 问题)。
  • 上下文不够时,会“顺着能跑的路走”: 当它无法确认已有实现是否存在时,就会退而求其次沿用它能找到的方式实现—— 不是因为它“偷懒”,而是因为它只能基于“能找到的证据”做决策。
  • 容易被命名模式误导: 它在用命名规律推断系统能力边界, 一旦命名不一致,系统里真实存在的能力就会在它眼里“隐身”。

总体来说,以前命名不一致,更多是让人读代码痛苦一点、维护成本高一点,但在 AI 参与开发之后,它的影响升级了:

  • 对人:命名不一致 = 阅读/维护成本上升
  • 对 AI:命名不一致 = 系统结构不可观测(进而推导出错误架构结论)

因此:AI 并没有让命名变得不重要,相反,它让命名第一次变成了“架构是否存在”的证据