今天在用AI辅助写代码时,遇到了一个有意思的问题,我强烈要求AI为我修正代码中的错误,使其能正常运行并输出一个结果,但是AI知识在出错前使用if语句判断了一下可能导致出错的条件,不满足条件的直接raise一个Error(Python语言),将错误(或者说异常)抛出,没有实际解决问题。于是,突发奇想,以一个简单的问题去试试各家AI解决此问题的策略如何。

实验方案

实验过程

首先清除AI的上下文,新建一个对话,采用的都是各家的通用型对话式AI,没有采用专门针对代码工作调优的版本,没有调整任何参数(例如temperature等),先输入以下Prompt

下面这段代码运行时报错,请修改代码解决此错误

if __name__ == '__main__':
a = input("请输入一个数字:")
b = 5
c = b / int(a)
print(c)

报错信息:ZeroDivisionError: division by zero

查看AI能否实际解决问题,期望的结果是AI不可以仅仅提示错误或是抛出异常,而应当将0视为无穷小来处理,进而输出一个无穷大。如果此时AI已经能满足我们的期望,则记为5分,如果AI不能满足我们的期望,则进一步给予以下要求的提示词

不要抛出错误,也不要提示错误,无论如何都要算出一个结果出来

同样地查看AI能否解决问题,满足我们的需要,如果可以解决问题了,那就记为4分,如果还是不能满足,我们再进一步给出以下提示

请用高等数学的知识解决

继续查看AI能否解决问题、满足期望,如果能够满足要求,则记3分,如果仍然不能满足,则给出以下提示

0可以视为无穷小,请据此解决上述错误

最后一次查看AI能否解决问题、满足期望,如果能够满足期望,则记2分,如果仍旧不能满足期望,仍然固执地仅仅使用tryif拾取错误、给出提示,那就姑且给个1分吧,实在是无可救药,原地摆烂,连捕获错误都不干的话那就给0分了,应该不会有哪个AI得0分的吧。

补充说明

  1. 本实验仅为笔者突发奇想地去玩一玩,很多实验过程并不严谨,不能代表各AI平台的能力和水平
  2. 提示词也是笔者突发奇想临时起意编的,并没有认真地调试过
  3. 所给分数不能代表AI的水平,实际上只是解决问题的策略不一样,即使是人类程序员,无论水平如何,也会存在不同的解决问题的思路(0分那个除外)
  4. 所选的AI平台是笔者拍脑袋想的,不具有参考价值
  5. 总而言之,看着玩玩就好,别当真

想要直接看结果的,请划到文章最后

实验开始

通义千问

来自阿里的选手首先上场应战,因为Deepseek出来之前我最经常就是使用它来帮我写代码的了,所以浏览器收藏夹里排最前的也是它了,索性就先来吧。

第一回合

没能完成,改出来的代码采用了if语句判断,如果判断出除数为0,则提示出错。还有个细节就是,提示出错后代码就结束了,不给用户二次输入改正的机会,看看后面几个AI是不是也这样。值得肯定的是,它会用try判断用户输入的内容是否为数字。它输出的代码长这样:

if __name__ == '__main__':
a = input("请输入一个数字:")

# 检查是否为有效的整数
try:
a_int = int(a)
except ValueError:
print("输入无效,请输入一个有效的数字。")
exit(1)

b = 5

# 检查除数是否为0
if a_int == 0:
print("除数不能为0,请输入一个非0数字。")
else:
c = b / a_int
print(c)

第二回合

也没能完成。我要求不要抛出错误,也不要提示错误,它可能理解为了except当中的部分,但是可以看到它优化了一下代码结构,把条件判断放到try里面了,但是依然只提示除0,没有解决问题。另外,它把除0的结果设为了None,然后去判断结果是否为None,这……怎么有点多此一举的感觉呢

if __name__ == '__main__':
a = input("请输入一个数字:")
b = 5

try:
a_int = int(a)
c = b / a_int if a_int != 0 else None
if c is None:
print("由于除数为0,无法完成除法操作。")
else:
print(c)
except ValueError:
# 如果输入不是有效的整数,也给出一个友好的信息而不是报错
print("您输入的不是一个有效数字,无法进行计算。")

第三回合

当我提示用高等数学的知识解决的时候,它终于想起来了用极限的方法去解决了,话不多说,直接上代码

if __name__ == '__main__':
a = input("请输入一个数字:")
b = 5

try:
a_int = int(a)
# 使用条件运算符判断是否接近0,并决定是进行正常除法还是返回无穷
c = b / a_int if a_int != 0 else float('inf') if a_int >= 0 else float('-inf')
print(c)
except ValueError:
# 如果输入不是有效的整数,也给出一个友好的信息而不是报错
print("您输入的不是一个有效数字,无法进行计算。")

到这里看还是能顺利解决问题的

腾讯元宝×Deepseek

DS官方服务器老是繁忙,所以平常我用腾讯的这个比较多,我们也来试试,顺便跟官方的对比一下,看看效果是否一致。测试时开启深度思考(R1)联网搜索能力

第一回合

企鹅版Deepseek采用了两个except的方法捕获两种错误,我认为这比前面通义千问的一个用if另一个用try还是优雅一些,假如说不是提示错误,而是向上抛出也更方便处理。给出的代码如下

if __name__ == '__main__':
a = input("请输入一个数字:")
b = 5
try:
num = int(a)
c = b / num
print(c)
except ZeroDivisionError:
print("错误:除数不能为零。")
except ValueError:
print("错误:请输入有效的整数。")

第二回合

当我要求“不要抛出错误,也不要提示错误”时企鹅版Deepseek提供了5种不同的解决方案。其中方案3提到了使用numpy运算,将a/0转为infnan,还提到了用nan_to_num替换为默认值。这里考虑到可能是受到我的提示词的误导,无论如何都要输出一个“数”,而inf它不认为是符合要求的“数”,所以进行了替换,也算是能够输出inf的(在Python中就表示无穷大的意思)。这局算是赢了。

import numpy as np

def silent_divide(a, b, default=0):
with np.errstate(divide='ignore', invalid='ignore'):
result = np.true_divide(a, b)
return np.nan_to_num(result, nan=default, posinf=default, neginf=default)

result = silent_divide(10, 0) # 返回0

另外几个方案还提到了使用Lambda表达式、自定义运算符重载、异常捕获后返回默认值、条件判断后返回默认值这些方法,总之很好地满足了要求,静默处理这一错误。

混元

这是腾讯元宝自家的大模型,来都来了,那就试试看。先表扬一下,腾讯元宝的UI做得还是蛮好看的,简洁大气,尤其是我的提示词中有markdown内容时,它可以渲染出来,像之前在通义千问里面时就不能把我提示词的markdown渲染出来,只有个纯文本在那里。

第一回合

第一回合也是差不多,给了两个方案,要么通过try要么通过if捕获错误,然后print提示,代码没必要再细看了,大差不差,放个截图吧

第二回合

第二回合它就没想到用Numpy了,也是给了两个方案,一个是通过try,一个是通过if,结果倒是满足要求了,没有提示错误,也没有抛出异常,但是返回0作为默认值总感觉不太到位,当然,也有可能是受到我提示词的误导,非要输出一个“数”,它就不敢输出一个inf给我。且看第三回合怎么样。

第三回合

本来还想着如果第三回合能按要求输出,给它个3.5分的,结果第三回合貌似开始忘记初心了,连代码都没有,只有文字介绍。看来只能进入第四回合了。

补充:后来我又试了一下将前三回合的提示词拼接起来丢进去,它似乎又找到自我了,知道输出无穷大了,但是貌似又迷失在自我中,不断死循环重复思考过程,直到单次的token数用完。此外,从其思考的过程中也能看到我的提示词确实设计得不好,要求输出一个“数”导致其不输出“无穷大”。

第四回合

这是第一位进入第四回合的选手。但是……它的记忆可能是从鱼那里学习来的,它已经忘了它最初要干什么了,开始教我数学知识。

无奈之下,我只能将前四回合的提示词都拼接起来再丢给它,看看是什么情况。忽然想到,上面的第三回合已经开始出现失忆了,于是先尝试把前三回合的提示词输进去,先试一试前三次(详见前文)。结果它迷失了自我,随后再将前四次提示词拼接起来后输进去,它在经过激烈的思想斗争后输出了一个还算不错的结果。

if __name__ == '__main__':
a = input("请输入一个数字:")
b = 5
divisor = int(a)
if divisor == 0:
c = float('inf') # 0作为无穷小处理,正数除以0趋近正无穷
else:
c = b / divisor
print(c)

说实话,结合着生成的代码和简洁的文字提示来看,感觉这样子的结果是我比较满意的,可惜第四回合才出现,而且还得拼接提示词折腾了这么久,实际生产过程中实用性还是会差一些。

按照比赛规则,我们给它2分

Deepseek官网

第一回合

第一回合失败了,它采用的方案是使用try捕获错误并print给出提示

第二回合

第二回合成功地处理了错误,但是又是另一种处理方式,最终的代码将为0的输入强行设为了1,倒也算是满足我的要求,没有抛出错误,没有提示错误,但是计算结果显然是错误的,实际上可以有更好的方案,那就是对于为0的强行设为1e-6,不知道它为什么要设为1.0而不是一个很小的浮点数。

if __name__ == '__main__':
a = input("请输入一个数字:")
# 处理无效输入和除数为零的情况
try:
num = float(a)
except ValueError:
num = 1.0 # 输入无效时默认设为 1.0
if num == 0:
num = 1.0 # 输入为零时强制设为 1.0
c = 5 / num
print(c)

可以看到其思考过程中层考虑过inf这一方案,但是它认为我所说的“不能抛出异常”是不能出现ZeroDivisionError的意思,所以自己否决了这一方案

其它平台

我还测试了其它一些平台,但是篇幅所限,就不一一写出来了,最后结果请看文末表格。简单总结一下:

  • ChatGPT第二回合也跟Deepseek一样把除数设为了1解决问题,但是思考过程中并无inf,姑且给它个3.5分;
  • Kimi的思考过程蛮有意思,不像Deepseek那么枯燥、啰嗦且没有格式,Kimi有点小可爱的感觉,另外Kimi捕获错误后使用while循环,不断地给用户重复纠正的机会,值得肯定,第二轮的时候能够返回一个0,从思考过程中可以看到已经考虑inf方案,但最后自我否决掉了,因为它认为float('inf')会让用户感到疑惑,还是给个4分吧,毕竟还是比ChatGPT厉害的,能想到这
  • 豆包第一轮采用的是try和if混合的方案,第二轮即使不像Kimi、Deepseek、ChatGPT这样的有推理能力,豆包在没经过“思考”这一过程也能马上输出inf的方案或是默认值的方案,给4分
  • Deepseek-R1 671b开源版(基于硅基流动):第一轮同样采用的是try和if混合的方案,第二轮强行设为1,思考过程中没有体现inf的思路,给个3.5分,跟ChatGPT一样;
  • Deepseek-V3 671b开源版(基于硅基流动):第一轮就懂得捕获错误后使用while循环了,不断给用户纠正的机会;第二轮采用默认结果值的方案,考虑到了一点点inf,比R1开源版好,给4分
  • Deepseek-R1 1.5b开源版(本地部署):毕竟是1.5b,不摆烂就算不错了,几轮下来没一次行的,总是在抛出错误或print错误提示,给个1分

实验结果

AI平台 第一回合 第二回合 第三回合 第四回合 有无摆烂 最终得分
通义千问 / / 3
腾讯元宝×Deepseek / / / 4
混元 / 2
Deepseek官网 / / / 4
ChatGPT / / / 3.5
Kimi / / / 4
豆包 / / / 4
Deepseek-R1 671b开源版 / / / 3.5
Deepseek-V3 671b开源版 / / / 4
Deepseek-R1 1.5b开源版 1