AI 写的代码怎么人工复核:用最小示例讲清用法与边界

编程狮(w3cschool.cn) 2026-09-28 10:40:55 浏览数 (23)
反馈

AI 写出能跑的代码不难,难的是判断这段代码能不能进你的项目。本文用一段典型的 AI 生成 Python 代码做样本,给出可照做的三步人工复核法:先让它跑通边界输入,再查依赖与异常处理,最后看命名和重复。核心结论是,复核顺序按「会不会出错 → 出错后能不能定位 → 以后好不好改」排列,把时间花在前面两步的回报最高,风格类问题可以放到最后。下面每个判断点都给出可对照的代码片段和判定标准,并附上复核清单与常见失败。先确认 Python 版本与依赖环境,再决定在哪里停下检查。

AI 写的代码人工复核三步法示意图

一、先看结论:AI 生成代码的复核顺序

下面这张表给出人工复核的优先级,从高到低依次检查。前两档决定代码能不能上线,后两档决定以后好不好维护,想省时间就只看前两档。

检查档 具体看什么 不通过的后果
第一档:边界 空值、超长输入、极端值会不会崩 线上直接报错或返回错误结果
第二档:异常 except 是否过宽、错误信息是否可读 出问题无法定位,只能靠猜
第三档:依赖 第三方库是否必要、版本是否锁死 换机器装不上,或版本升级就坏
第四档:可读性 命名是否表意、有无大段重复 三个月后自己看不懂

复核优先级与不通过后果对照图

这个顺序的依据是修复成本:边界问题在测试阶段就能发现,改动量最小;风格问题拖到后期返工,牵连面反而最大。需要提醒的是,AI 生成的代码常见的问题是「能跑通样例,但扛不住异常输入」,所以第一档永远放在最前面。想在线对比同一段代码的不同写法,可用 在线代码实例 验证实际结果。

二、环境确认与最小示例

复核前先固定环境,否则同样的代码在不同版本下结论不一样。以下示例基于 Python 3.10 与标准库,不涉及第三方依赖;如果你用的是 3.8 或更早版本,类型注解写法需要调整。Python 版本差异主要影响类型提示语法,对下面三档检查的结论没有影响。

下面给一段 AI 通常会写出来、但存在三处问题的代码,后面的复核步骤都围绕它展开。以下为预期结果说明,未在本机执行,按 Python 官方文档推断。

# 先确认 Python 版本,再执行下面的脚本
python --version

# AI 生成的一段示例:按逗号分割字符串并统计长度
def split_and_count(text):
    parts = text.split(",")
    result = []
    for p in parts:
        result.append(len(p))
    return result

# 调用示例
print(split_and_count("ab,abc,abcd"))

这段代码在样例输入下能正常输出,但把它拿去做人工复核,正好能命中后面三档问题。先把样例跑通是复核的起点,而不是终点。

三、第一档:边界输入会不会崩

边界是 AI 生成代码最容易漏掉的一层。直接把上面那段代码传给空字符串或 None,结果就不一样了:传空字符串会返回空列表,逻辑上勉强说得过去;传 None 则会在 text.split 这一步直接抛属性错误。这类失败在生产环境里表现为偶发报错,难复现、难定位。

# 第一档检查:把边界输入直接喂给函数,看是否会崩
# 边界一:空字符串,split 后得到空列表,不崩但返回值可能不符合预期
print(split_and_count(""))

# 边界二:None,split 需要字符串对象,传入 None 会抛属性错误
# 修复方向:在函数入口加一层类型判断,把 None 转成空字符串
def split_and_count_safe(text):
    if not text:
        return []
    parts = text.split(",")
    return [len(p) for p in parts]

上面这段修复只加了一行判断,就把最常见的两种输入挡在了函数外。这就是第一档检查的标准动作:先想清楚「最坏的输入是什么」,再决定在函数入口还是调用方拦。判断依据是是否需要区分「空」和「未传」,需要区分就在入口拦,不需要就交给调用方处理。

四、第二档:异常处理是否过宽

AI 生成的 except 语句常见形态是捕获一切。宽捕获本身不是错误,问题在于它把真正的失败也吞掉了:调用方拿不到错误,只能看到默认值。判定标准很简单,看 except 后面跟的是具体异常类型还是裸 Exception。

# 反例:宽捕获把两类完全不同的失败混在一起,调用方无法区分
try:
    print(split_and_count(None))
except Exception as e:
    print("出错了")

# 修复方向:只捕获真正会发生的异常,并把原始异常带上,便于定位
try:
    print(split_and_count(None))
except AttributeError as e:
    # AttributeError 指向类型不对,属于调用方问题
    print(f"传入的不是字符串:{e}")
except Exception as e:
    # 兜底保留,但记录完整异常,避免后续无法追溯
    print(f"未预期的错误:{type(e).__name__}: {e}")

二分之后的代码有个额外好处:错误分类本身就是文档,读代码的人一眼能看出这个函数可能遇到哪些失败。修复这类问题的方向不是「不捕获」,而是「捕获后仍然让调用方知道出了问题」。

五、第三档与第四档:依赖、命名与重复

第三档看依赖。AI 常引入并不必要的第三方库,也会在代码里写死版本号。判定标准是先问一句「标准库能不能做」,能就用标准库;确需第三方库时,把版本约束写进依赖文件。第四档看可读性和重复,最典型的表现是同一段逻辑在文件里出现三四遍。

# 反例:同一段转换逻辑写了三遍,改一处要改三处
a = [len(x) for x in text1.split(",")]
b = [len(x) for x in text2.split(",")]
c = [len(x) for x in text3.split(",")]

# 修复方向:抽成一个函数,三处调用同一份实现
def lengths_of(text):
    return [len(part) for part in text.split(",")]

a = lengths_of(text1)
b = lengths_of(text2)
c = lengths_of(text3)

重复代码的判定标准不是「长得像不像」,而是「改的时候要不要同时改几处」。命中这个条件就抽函数,不命中就保持原样,避免过度抽象。想把人工复核做成固定流程,可以把它写成一份检查清单放进仓库说明,用 Python 教程 补齐语法细节。这里要强调一句,复核的对象始终是代码本身,而不是 AI 给出的解释;解释听起来合理并不代表实现正确,只有跑通边界输入的那份实现才算过关。

总结

AI 写的代码怎么人工复核,答案就是按固定顺序过一遍:第一档查边界输入,看空值、超长、极端值会不会崩;第二档查异常处理,看捕获范围是否过宽、失败后是否还能定位;第三档查依赖,看第三方库是否必要、版本是否约束;第四档查可读性和重复,看命名是否表意、同一逻辑是否重复出现。复核顺序按修复成本从低到高排列,把时间花在前两档回报最高。判断标准都可以一句话说清:能不能复现失败、能不能分类错误、改一处要不要动几处。按这个顺序过一遍,大多数 AI 生成代码就能安全进项目。

延伸学习

想在编程狮系统学 AI 编程,可以顺着下面三篇深入:

常见问题

Q:AI 写的代码能直接提交吗?

A:不建议直接提交。AI 生成的代码往往能在样例输入下跑通,但边界输入和异常路径常常缺失,上线后表现为偶发报错。稳妥的做法是先跑一遍边界输入,确认空值、超长、极端值三种情况都不崩,再提交。

Q:复核时间不够,只看一档行不行?

A:可以看第一档,也就是边界输入。这一档的判定最快,改动量也最小,能把最致命的问题挡住。时间宽裕时再补第二档异常处理,这两档覆盖了线上故障的绝大多数来源。

Q:怎么判断 except 是不是过宽?

A:看它捕获的是具体异常类型还是裸 Exception。宽捕获本身不违规,问题在于把不同原因的失败混成一种结果。修复方向是细分具体异常类型,并在兜底分支里保留完整错误信息,让调用方仍能区分失败类型。

Q:AI 生成的重复代码一定要抽函数吗?

A:看「改的时候要不要同时改几处」。如果同一段逻辑出现多次且未来可能调整,就抽成函数;如果只是恰好写法相似、语义各不相同,抽函数反而增加理解成本,保持原样更好。

0 人点赞