📘 第1章 人工智能的过去、现在和未来
📄 一句话概括

「人工智能」这个词 1956 年才被造出来,比第一台电子计算机晚十年, 可它想描述的东西——会思考的机器——在神话里已经活了几千年。 这一节把三件事分开: 名字怎么来的、判据怎么定的、以及为什么做成了的事就不再叫人工智能。 最后用一副井字棋把这三件事量一遍。

📝 本节和前面几节的关系

这是全书第一节,前面没有别的课要接。 往后看,第 2 章讲规则系统,第 3 到 6 章讲搜索和概率,第 7 到 9 章讲机器学习与深度学习, 第 10 到 14 章讲感知、语言、知识和算力。 这一节只干一件事:把「人工智能」从形容词变回一个可以数的问题。

一、名字比能力早到了七十年

1956 年夏天,十个人在美国新罕布什尔州的达特茅斯学院开了一个为期两个月的研讨会。 会议的名字里第一次出现「人工智能」这个说法,组织者是麦卡锡、明斯基、香农和罗切斯特。 他们当时提的命题是:学习的每一个方面、智能的每一个特征, 原则上都能被精确描述到让机器模拟的程度。这句话放在 1956 年是狂想,放在今天仍然没有被证明, 也没有被推翻。 麻烦在于「智能」本身没有定义。教材把常见的定义分成四路,两条轴:像人还是讲理性,想还是做。

轴 像人一样 讲理性
想 像人一样思考(认知模型) 理性思考(逻辑推理)
做 像人一样行动(图灵测试) 理性行动(智能体)
四格都有人走。这门课走的是右下角那一格:不问机器像不像人,只问它在一个任务上做得好不好。

二、图灵测试:测的不是智能,是「分不出来」

1950 年,图灵在《心智》杂志上发了一篇《计算机器与智能》,开头第一句是「我打算考虑一个问题: 机器能思考吗」。然后他立刻说,这个问题太含糊,没法答。 他换了个问法。一间屋子里有一个人和一台机器,测试者在另一个房间,只能通过打字对话。 测试者要判断哪边是人。如果机器骗过了足够多的测试者,就认为它有智能。这就是「模仿游戏」。 这个换法的漂亮之处在于:它不定义智能,只定义一个可操作的判据。你不用回答「什么是思考」, 只需要回答「分不分得出来」。 图灵当时的预言是:五十年内,机器能让 30% 的测试者在五分钟内判断错误。 2000 年前后确实有程序达到了这个数,2014 年一个叫 Eugene Goostman 的聊天程序据说骗过了 33% 的评委。 但它的做法是扮演一个十三岁的乌克兰男孩,靠拼写错误和回避问题过关。这不是智能的胜利, 是「人设」的胜利。测试本身的软肋也在这里:它测的是「像不像人」,不是「会不会想」。

三、中文屋子:会答题不等于懂

1980 年,哲学家塞尔提出了一个反驳。 一个人被关在屋里,手边有一本极厚的规则手册,写着「看到这种形状的字符,就照抄那种形状的字符出去」。 屋外递进来中文问题,他按手册对出中文答案。 屋外的人分不出来,可屋里的人一个中文字也不认识。 塞尔想说的是:符号按规则搬运,不产生理解。这直接把 AI 分成两派。

立场 主张 工程上的意思
强 AI 恰当编程的机器真的有心智 要解释意识从哪来
弱 AI 机器只是模拟智能行为 只管任务做得好不好
这门课、以及这套笔记里的所有代码,站的都是弱 AI 这一边。不是因为强 AI 不重要,
是因为它到今天还没有一个能写成程序的版本。
顺带说一句:中文屋子这个反驳本身也有争议。
反对意见大体是「你只看了屋里的那个人,没看整个系统」——手册加人加屋子合起来,也许就是懂中文的。
这场争论四十年没结论,但它逼着每个做 AI 的人想清楚自己在做什么。

四、AI 效果:做成了就不叫 AI 了

1979 年,科学史家 McCorduck 给这个现象起了个名字:AI 效果。 意思是,一旦某个能力被做出来、变得寻常,人们就不再管它叫人工智能。 光字符识别是这样,路径导航是这样,搜索排序、垃圾邮件过滤、语音输入、手写识别,全都这样。 它们当年都是论文标题里的「人工智能」,现在是手机里的一个开关。 这个现象不是谦虚,它有实际后果: 每一代人都觉得「真正的 AI 还没来」,因为已经来的那些都被重新归类成「普通程序」了。 拿井字棋算一下就明白为什么。这副棋盘从空盘出发,一共走得出 18753 个不同的局面。 把这个表整个存下来,每个局面记一个「该下哪」,146 KB 就够了——一部手机能存几百万份。 所以没人管井字棋叫人工智能。它太小了,小到能背下来。 「智能」这个词,实际上是留给那些背不下来的问题的。这一节剩下的部分,就是把这句感觉变成一张表。

五、这本书怎么走

全书 14 章,我按「能干什么」切成四块。每块给一句它自己的话。

块 章 一句话
一 1~2 从图灵测试到规则系统:先把名字和判据立住,再看 IF-THEN 能撑多远
二 3~6 搜索、最优解与概率:机器开始在解空间里找路,并且学会说「我不确定」
三 7~9 从机器学习到深度学习:不再写规则,改成给例子
四 10~14 感知、语言、知识与算力:把前面那些东西接到真实世界的输入上
这四块不是四种技术,是同一个问题的四次换刀:怎么让机器在一件事上做得比写死的程序更好。
如果你读过本仓库的 41 课图解深度学习,会发现第三块和它重叠。
那本是把第三块竖着钻到底,这本是横着铺开,让每一块都露一面。两本对着看,
竖线上的每个「为什么」,在这本里都能找到它的「从哪来」。

六、动手 Demo:同一副井字棋,四种「智能」,谁输谁赢

四种策略,没有一条是「学」出来的,全是人写死的。差别只在「决策依据」是什么:不看对手、 看自己的台阶、看对手的威胁、还是把后面所有分支都算一遍。 棋盘用 9 个格子的列表表示,0 空、1 先手、2 后手。两两对战各 200 局,先手各占一半, 避免先手优势污染结果。

WIN = ((0,1,2),(3,4,5),(6,7,8),(0,3,6),(1,4,7),(2,5,8),(0,4,8),(2,4,6))
ORDER = (4,0,2,6,8,1,3,5,7)            # 中心 → 四角 → 四边

def winner(b):
    for a,c,d in WIN:
        if b[a] and b[a]==b[c]==b[d]:
            return b[a]
    return 0

def mv_order(b, me, rg):               # 位次规则:见空就按优先级下
    for i in ORDER:
        if b[i]==0:
            return i

def _two(b, p):                        # 找「占了两格、第三格空着」的那条线
    for a,c,d in WIN:
        cells=(a,c,d)
        if sum(1 for x in cells if b[x]==p)==2:
            for x in cells:
                if b[x]==0:
                    return x
    return None

def mv_block(b, me, rg):               # 赢堵规则:能赢就赢,要输就堵
    k = _two(b, me) or _two(b, 3-me)
    return k if k is not None else mv_order(b, me, rg)

def _mini(b, me, cnt):                 # 完全搜索:把后面所有走法算一遍
    cnt[0] += 1
    w = winner(b)
    if w:
        return 1 if w==me else -1
    e = [i for i in range(9) if b[i]==0]
    if not e:
        return 0
    return max(-_mini(tuple(b[:i]+(me,)+b[i+1:]), 3-me, cnt) for i in e)

实跑输出:

--------------------------------------------------------------------
同一个井字棋,四种「智能」
--------------------------------------------------------------------

==============================================================



[1] 四种策略,只看「决策依据」



    随机      无                  从空格里随便挑一个

    位次规则  1 条优先级链        中心 → 四角 → 四边,见空就下

    赢堵规则  2 条判断 + 1 条链   能赢就赢,对方要赢就堵,否则走位次

    完全搜索  胜负递归            把后面所有走法算一遍,挑不败的一手



  四条路,没有一条是「学会」的——全部是人写死的。



[2] 两两对战 200 局(先手各一半),看谁输



    先手      后手      胜-平-负    每局毫秒  结论

    随机      位次规则  53-6-141    0.02      互有胜负

    随机      赢堵规则  2-15-183    0.05      互有胜负

    随机      完全搜索  0-17-183    0.12      只平不赢

    位次规则  随机      141-11-48   0.03      互有胜负

    位次规则  赢堵规则  0-0-200     0.04      全败

    位次规则  完全搜索  0-0-200     0.04      全败

    赢堵规则  随机      176-21-3    0.05      互有胜负

    赢堵规则  位次规则  200-0-0     0.05      全胜

    赢堵规则  完全搜索  0-200-0     0.08      一局没输

    完全搜索  随机      182-18-0    0.04      一局没输

    完全搜索  位次规则  200-0-0     0.04      全胜

    完全搜索  赢堵规则  0-200-0     0.08      一局没输



  三条结论都在这张表里:

  1. 完全搜索出场的六场里一局没输过——它算的是「所有分支」,不是「经验」。

  2. 位次规则对赢堵、对搜索都是 0 胜 0 平 200 负——

     它只顺着自己的台阶走,从头到尾没看过对手一眼。

  3. 赢堵规则只多两条判断,对搜索就是 200 局全平,一局没输。

     在井字棋这个尺寸上,「能赢就赢、要输就堵」几乎等于完全搜索。



[3] 完全搜索到底翻了多少张牌

    纯 minimax        节点 549946   758.8 毫秒

    带 alpha-beta     节点 18297    27.3 毫秒

    剪枝省掉 96.7%,答案一样(0 对 0)



[4] 但真要把这张表背下来呢

    从空盘出发走得到的不同局面:18753 个

    如果不管合法性,九个格子全排列:362880 种

    比例 5.2%——绝大多数排列在井字棋里根本走不出来。



    把「到这里该下哪」全存成表,一共 18753 条。

    按每条 8 字节算,146.5 KB——一部手机能存几百万份。



  这就是「AI 效果」最朴素的一版:

  同一件事,用 18753 条的表能做完,就没人管它叫人工智能;

  换成 5 行规则的链,也没人叫;

  只有当你写不出规则、只能让机器去搜的时候,它才像「智能」。

  事情本身的难度没变,变的是「我们会不会」。



[5] 换成 4 乘 4 棋盘,两条路一起断掉

    棋盘      分支因子    最坏手数    不剪枝叶子数上界

    3 乘 3    9           9           3.6 乘 10 的 5 次方

    4 乘 4    16          16          2.1 乘 10 的 13 次方

    5 乘 5    25          25          1.6 乘 10 的 25 次方



  井字棋 9 手就到底,穷举可行;4 乘 4 要 16 手,上界跳到万亿量级。

  「规则」和「搜索」在棋盘变大时同时失效——

  第三条路不是更聪明的规则,是换个角度:不再枚举走法,而是估一个值。

第一段那张表先看「决策依据」这一列。随机策略没有依据;位次规则只有一条优先级链; 赢堵规则多了两条判断;完全搜索一行递归。四者的代码量差不到二十行,战绩差得很远。 第二段的对战表里,最干净的两行是「位次规则对赢堵」和「位次规则对搜索」, 都是 0 胜 0 平 200 负。位次规则并不笨——它对随机对手能赢 141 局。 它的问题是只看自己的台阶,从头到尾没看过对手一眼。 井字棋里这足够致命:对手摆出两连,它照样去占下一个空角。 第三行是赢堵规则对完全搜索,200 局全平。多了两条判断——「我能赢吗」「对方要赢吗」—— 就把搜索的战绩追平了。这是这一节最该记住的一句话:在这副棋盘上,一条好规则等于一次完全搜索。 第三段量搜索本身。纯 minimax 从空盘算起要访问 549946 个节点,748 毫秒; 加上 alpha-beta 剪枝只剩 18297 个节点,26 毫秒,省掉 96.7%,答案一个不差。 剪枝不改变结果,只是把明显没用的分支提前掐掉。 第四段把「背下来」这条路走完。从空盘出发走得到的局面是 18753 个, 而九个格子的全排列是 362880 种,前者只占 5.2%——绝大多数排列在井字棋里根本走不出来, 因为下到第四手就已经分出胜负了。 第五段换成 4 乘 4。不剪枝的叶子数上界从 3.6 乘 10 的 5 次方跳到 2.1 乘 10 的 13 次方, 再跳到 5 乘 5 的 1.6 乘 10 的 25 次方。算力涨得再快,也追不上这个指数。 所以真正的问题不是「怎么搜得更快」,是「怎么不搜」。后面十三个章节,讲的都是这件事的不同答法。

30 秒实验

  1. 把 mv_block 里的两句顺序调过来——先堵再赢——重跑第二段。 对搜索的战绩会从 200 平掉到输几局,因为有一手能赢的时候它去堵了,错过就再也追不回来。
  2. 把 N 从 200 改成 20,看「每局毫秒」那一列怎么抖。样本一小,这一列就不再是性能,是噪声。
  3. 把第 [5] 段的 (3, 4, 5) 换成 (3, 4),重跑。 5 乘 5 那一行的指数会跳到 25 次方以上, 然后你就能体会为什么 1997 年深蓝要靠专门的硬件和剪枝才下得动国际象棋。

常见误区

  1. 以为「AI 效果」是外行人的误解。恰恰相反,它是内行的默认态度。 每一代研究者都把上一代做出来的东西当成「只是程序」,因为只有还没做出来的那部分才值得写论文。
  2. 以为图灵测试通过就等于有智能。它测的是「在五分钟的文字对话里分不出来」。 Eugene Goostman 靠扮演十三岁男孩通过,这跟靠演技拿奖是一个道理——骗过的是评委,不是题目。
  3. 以为井字棋太小,没有代表性。它恰恰是最好的标尺:小到能穷举、能背表、能写规则、能搜索, 四条路都能走通,于是你能在同一条起跑线上看它们各自的样子。 换个大问题,你就分不清是方法不行还是算力不够了。
  4. 以为「能背下来就不算智能」是技术判断。它是社会判断。 18753 条的表和 5 行规则,在数学上都能完美下完这盘棋; 我们说后者「更聪明」,是因为它更短、更能解释、更能搬到别的棋盘上。
自测三问(点开对答案) 1. 图灵为什么要把「机器能思考吗」换成「模仿游戏」? —— 因为前一个问题没有可操作的判据——「思考」没有公认定义,问下去只能吵架。 换成模仿游戏之后,问题变成「测试者在五分钟里能不能分辨」,这是一个可以设计实验、 可以数比例的问题。**代价是判据变窄了:它测的是像不像人,不是会不会想。** 2. 中文屋子想反驳的是什么?它反驳成功了吗? —— 它反驳的是「按规则搬运符号就等于理解」。 屋里的人对答如流却一个字不懂,说明符号操作和理解是两件事。 **它没有彻底成功**,主流反驳是「你只看了屋里的人,没看整个系统」——手册、人、 屋子合起来也许就是懂中文的。这场争论到今天没有结论,但工程上大家默认站弱 AI。 3. 为什么说「能背下来」是井字棋不算 AI 的原因? —— 因为 18753 个局面、146 KB 就能存完,而且存下来的表和完全搜索给出的答案一模一样。 **当一件事小到能整张背下来时,它就不再需要「学」,只需要「查」。**我们说一个任务需要智能, 说的其实是它大到背不下来、又小到有规律可循。

名字和判据都有了,接下来该看第一批真的跑起来的程序。 它们不学任何东西,只把人的知识写成 IF-THEN——下一节从 1956 年的乐观讲起。

相关笔记