声明
本文编辑中(基于一次Miro的重构)
本文内容主要基于一次针对 MiroFish 项目的深度改造
本文中提及的代码、问题,如无特别指出,均基于 MiroFish 2026.4.2 提交 分析
本文并非对 MiroFish 项目的批评与指责,而是以这个代表性的项目为基础,指出当前 AI 代码面临的问题,以及应采取的办法
背景介绍
- MiroFish 背景介绍(融资)
- 改造背景与计划
代码问题与影响
代码规范不统一
日志规范不统一
【问题】
- 有时使用日志,有时直接
print - 有时使用国际化统一语言输出,有时字符串直接格式化输出
【影响】
- 影响较小,通常可忽略,可能造成日志文件中找不到对应的输出,影响出问题时的排查效率
传参、默认值设定、环境变量读取逻辑混乱
【问题】
- 参数在多个函数层级传递使用的默认值不一致
- 配置参数的使用有时通过环境变量读取,有时通过多个层级传递,并提供不一致的默认值。
- 将在功能修改、参数、配置及传递涉及变更时带来级联的影响,每次修改都将涉及整个链路的代码
【维护】
- 古法:人工修改、问题排查时,将面临较大的代码阅读成本、链路追查成本,增加重构难度
- AI:AI修改时,涉及的影响预计将持续加大,在相关的改动中形成“包袱”,导致 Token 消耗加剧(这里指:针对单一模块的改动,设计的影响量持续增加,对整个项目的迭代而言,Token 的增量是非线性的,而是类似指数级的增长。下文将使用“包袱”代指这一现象)
【AI特征】
- 此问题大量重复出现时,可视为 AI 代码特征
【对策】
- 重新设计,如统一的配置管理器,管理非必要的传参与配置,对该配置影响的全部代码层级进行彻查与替换,成本适中
存储设计不统一
【问题】
- 图数据库除外(这种根本的设计肯定是人工主导的),大部分存储使用了文件进行存储,并设计了复杂的资源竞态、查询与关联相关处理,实现了一种基于
json文件的伪数据库实现 - 在发帖功能的设计上使用了 SQLite 存储
【影响】
- 在核心功能上使用文件存储(或写死的单文件数据库依赖)时,将在分布式服务上带来严重功能缺陷
- 对古法:修改、排查时,无论问题大小可能都面临着整个逻辑链路逻辑的分析,极大增加修改、排查、重构难度
- 对AI:出错概率高,持续迭代将进一步加剧风险和“包袱”
【AI特征】
- 推测原因为:AI对数据库工具使用的支持不如文件,AI可能倾向于将各种信息都以文件的方式存储;
- 当在一个或多个明显的独立实体上,仍然采用文件存储并在使用上做了过度复杂的设计(加锁、原子性处理、甚至查询缓存、伪外键逻辑)时,可视为 AI 代码特征。
【对策】
- 底层存储设计必须在AI开始编写代码前明确,过程中需及时发现并干预
- 项目成型后解决此问题大概率需要彻底重构,成本极大
导入规范不统一
【问题】
- 在 Python 代码中,导入并不统一出现在顶部,而是函数内、代码块中随处可见
- 有时甚至为常规的导入语句包装一层
try-except,而except语句块中只是提示如何需要安装它
【影响】
- 通常不影响功能,除非刻意为之(如处理循环依赖)
- 加剧代码混乱程度
【AI特征】
- 在函数内、语句块中,出现没必要的、重复的导入语句可视为 AI 代码特征
- 为
import语句包装try-except存在 AI 代码嫌疑
Dead Code(不可达代码)
- 无效传参
废弃代码
【问题】
- 看似煞有介事,层层追溯后缺发现根本没有入口的代码
- 实现多套然后只使用了一套的代码(比如同步代码、异步代码)
- 迭代过程被AI忘记清理的代码
【影响】
- 通常对功能无影响
- 对古法:对代码阅读、问题排查、迭代造成极大干扰,增加时间成本
- 对AI:逐渐增加“包袱”成本
【AI特征】
- 古法编程中,习惯不是特别好时,也容易造成遗留代码的问题,但人工操作通常会注释这些代码、标记为弃用、更好一些的会删除它们。通过调用链路追溯得到的 Dead Code 量特别大时,可认为有AI代码嫌疑
【对策】
- 使用 AI 进行大规模修改时,需进行人工干预
重复实现、冗余代码
重复造轮子
【问题】
- 明显无需重新实现的功能被重新编码了一遍
- 比如
to_json的功能被反复通过字符串拼接重写 - 重试的逻辑被反复编写、反复封装
- 比如
- 同样或高度相似的代码被反复编写,没有考虑整理、复用的趋势
- 标记了弃用的代码但仍保留调用
【影响】
- 对古法:修改、排查时,重复代码将造成较大误导,极大增加修改、排查、重构难度
- 对AI:增加出错概率,持续迭代将进一步加剧风险和“包袱”
【AI特征】
- CSS 代码在多个文件中大量重复,代码量占比特别巨大时,可视为 AI 代码特征(样式库除外)
- 重复或相似的大量代码反复出现的现象在项目中普遍存在时,可视为 AI 代码嫌疑
- 针对所有或大量接口的处理出现模式完全一样的异常处理、json、重试处理,而不是全局封装时,可视为 AI 代码嫌疑
【对策】
- 引导AI更多使用导入而不是重新实现,尽量在上下文中包含导入信息(或项目的依赖列表)
- 重构
无意义注释、过度注释
分步注释
该问题通常无需关注,除非对 AI 代码有要求时
【AI特征】
废话较多的分步注释在古法代码中并不常见,尤其是代码已足够清晰或日志已经描述了功能时。但在 AI 代码较常见,比如:
# ========== 步骤1: 生成时间配置 ==========
# ...
# ========== 步骤2: 生成事件配置 ==========
# ...
# ========== 步骤3-N: 分批生成Agent配置 ==========
# ...
# ========== 为初始帖子分配发布者 Agent ==========
logger.info("为初始帖子分配合适的发布者 Agent...")
# ...
# ========== 最后一步,构建最终参数 ==========
# ...
logger.info(f"模拟配置生成完成: {len(params.agent_configs)} 个Agent配置")
这种方式在古法编程中可能被认为是良好的编程习惯,但真正这么注释的情况并不多。
古法中有一种极客追求叫“代码即注释”,认为良好的设计下,代码本身甚至能契合自然语言的语法,进而解释代码本身含义。
而过时的、不能及时维护的注释会成为错误信息。注释不会影响功能,容易遗漏,而这些遗漏将对后续的工作造成误导。
AI 编程通常会同时对注释进行操作,可能不受这个问题影响,但此类注释可能被识别为 AI 代码嫌疑。
过度设计、无效设计
过度的“防御性编程”
【问题】
- 相同的校验判断,在传递链路上被多次、反复校验(且校验依据有时并不统一)
- 过度的 fallback 处理,对一个简单的校验臆想了过多的情况,并分别进行处理,尽管它们存在包含
【影响】
- 通常不影响功能
- 降低代码可读性、可维护性
- 其中的不一致问题将为后续的维护工作造成困扰
- 对古法:这种代码在没能彻底理解整个链路的逻辑前,通常不敢动,导致形成“屎山代码”
- 对AI:在缺乏完整的测试时,增加出错概率
【AI特征】
- 防御性编程适用于系统间交互、模块间交互、底层能力编写时,当大量出现重复的、无意义的校验时,可视为AI代码特征
【对策】
- 引导AI更多使用导入而不是重新实现,尽量在上下文中包含导入信息(或项目的依赖列表)
- 重构
过度的函数封装
【问题】
- 为了回调、线程的使用编写过多的内部函数、闭包
- 拆分为多层级的、无意义的函数调用链路,甚至有的函数只是原样转发了一下参数
【影响】
- 存在内存风险:闭包在多线程、协程上的使用,如果不去有意识地控制上下文、作用域,将带来内存泄漏风险
- 过度使用内部函数、无意义调用层级时,对代码理解造成阻碍
【AI特征】
- 当滥用仅有一行代码的无意义函数封装,可视为AI代码嫌疑
【对策】
- 在AI处理多线程时需格外谨慎并 Review
代码逻辑错误
代码耦合
模板与代码耦合
【问题】
- 提示词模板直接编写在代码中,且模板的占位符逻辑不一致
- SQL 硬编码在代码里
【影响】
- 影响较小,仅影响代码阅读、理解效率,变更模板更麻烦
- 极大增加单个代码文件的篇幅
- 模板是分散的,无法通过集中的模板快速理解项目有关的设计
【AI特征】
- 小范围的使用并不能认为是AI代码
- 大量重复出现且无准备重构的迹象时(比如有意识的集中管理它们),可视为 AI 代码嫌疑
AI 生成项目的建议
这里指项目的整个编码过程全部或绝大部分由 AI 生成的项目
新项目
当前 AI 项目不能在企业级项目中使用,仅推荐中小型项目,并在非分布式服务、小范围可控用户、快速原型等场景使用。
AI SOLO 得到的项目代码,当前阶段仍然仅适合作为古法的辅助(除非项目足够简单),对独立功能模块、简单功能、代码补全等场景提效明显;对文档解读(多语言)、技术选型建议、报错解读与建议等场景提供有效帮助。
维护二手项目
不具有可维护性,排查问题涉及的改动通常较大,项目中的各种错误、设计、误导将加剧问题的排查与修改
AI代码比古法代码更难解读,可能需要1.5~2倍甚至以上的时间来理解,如果有持续迭代需要,则需要重构
迭代二手项目
当前阶段,不建议接手这种项目来迭代(小型项目通常涉及的迭代很少、成本不高,不做讨论)
同等的迭代对比古法项目,预计需要2倍及以上的时间
- 古法迭代在AI项目稍复杂的迭代中必然会面临需要该模块的重构困境
- AI迭代则面临越来越大的“包袱”
在 MiroFish 的项目的同等规模下,重构成本大致与重写成本相当。
锐评当前AI编程VS古法编程
https://mori.plus/archives/cr-ai-ancient-programming
Comments