第二章可能出现的问题

第二章 ELIZA.py可能出现的问题 · 详细分析

分析对象code/chapter2/ELIZA.py(代码层)+ 第二章核心概念(概念层)

实验方法 :以 importlib 只读加载仓库中的 ELIZA.py不改动原文件 ),固定 random.seed() 保证可复现,逐条记录命中的规则 + 捕获内容 + 实际输出 。所有输出均为本机实测 ,不是推断。

结论先行 :ELIZA 原实现的 8 个缺陷全部可修 (修复版见 §四,已实测通过);但第 9 个缺陷------"它根本不懂语义" ------在符号主义路线内不可修这正是本章要论证的历史必然性:不是工程师不够努力,而是方法论到达了天花板。


一、速览:可复现缺陷清单

# 缺陷 一句话现象 严重度 可修?
D1 无关键词优先级 I am angry at my father 命中的是 I am 而不是 father 规则
D2 re.search 子串抢答 You know what I am saying? 在第 14 个字符处被 I am 规则截胡
D3 规则硬依赖标点 Why don't you listen to me(少个问号)→ 整条规则失效,掉到兜底
D4 反射与模板视角错位 I need youWhy do you need i?(宾语位置应为 me
D5 捕获未剥标点 I need help!...get help!?(双标点)
D6 强制小写化 I AM SAD → 捕获变 sad,大小写信息永久丢失
D7 死代码 respond() 末尾的兜底 return 永远执行不到
D8 无状态 + 不可复现 不记任何上下文;random.choice 让同句每次输出不同
D9 无语义理解 I am not happybeing not happy(不懂"not") 根本 方法论问题

⚠️ D9 是重点,但不要误以为它"只是又一条 bug" :D1--D8 修完,你得到的仍是一个不能理解"not"、不能理解时态、不能理解语序 的系统。这 8 条是工程债,第 9 条是范式边界------第二章整章就是在解释:为什么这条边界必须靠"从数据中学习"来突破。


二、缺陷逐条分析

D1 · 优先级被隐式交给 dict 插入顺序

现场

复制代码
输入: 'I am angry at my father'
实测: 命中 'I am (.*)'  捕获=('angry at my father',)
输出: 'How long have you been angry at your father?'
期望: 命中 '.* father .*'  → 'Tell me more about your father.'

根因respond()for pattern, responses in rules.items() 顺序扫描 ,首条命中即 return。Python 3.7+ 的 dict 保序 → 规则书写顺序 = 优先级 。而章节 §2.2.2 的算法第 1 步明确要求"关键词识别与排序(优先级) "------这一步在实现里被省略了

更隐蔽的连带效应I am sad because my father left 命中的是 I am (.*)整个 because 从句被吞进捕获组

复制代码
捕获 = ('sad because my father left',)
输出 = 'Did you come to me because you are sad because your father left?'   ← 双重 because

修复 :把规则改成显式带优先级的结构,按优先级降序扫描(优先级, 模式, 模板) 三元组),并把 family 类关键词排到 I am 之前:

python 复制代码
RULES = [(10, r"\bsorry\b", [...]), (6, r"\bmother\b", [...]), (5, r"\bi am\b\s*(.+)", [...]), ...]
for priority, pattern, templates in sorted(RULES, key=lambda r: -r[0]):

对应教材概念符号系统的脆弱性(Brittleness) ------规则之间的相互作用没有统一仲裁机制,只能靠"摆放顺序"这种隐式约定,加规则时任何一次挪动都可能静默改变全局行为。


D2 · re.search 让规则在句子中间"抢答"

现场

复制代码
输入: 'You know what I am saying?'
实测: re.search(r'I am (.*)', 输入) → span=(14, 26) 捕获='saying?'
输出: 'Did you come to me because you are saying??'

根因re.search = 句中任意位置 匹配(不是 re.match 的句首匹配,也不是全串匹配)。子串 I am 出现在句中也会激活规则。

一条输出里叠了三个缺陷

现象 根因
句中截胡 D2(re.search
being saying(语法错位) saying? 是现在分词,模板却是 you are {0}系统不认识词性 → D9
saying??(双问号) 捕获未剥标点 → D5

修复 :加词边界 \b,并(若要做原版 ELIZA 的效果)限定匹配位置:

python 复制代码
r"\bi am\b\s*(.+)"     # \b 保证 "I am" 是独立词,不会切进别的词里

📌 注意:\b 只能解决"词内误切",解决不了"句子中间合法出现" ------You know what I am saying? 里的 I am 本来就是独立词。要判断"这里该不该由 I am 规则接管",需要理解句子结构 → 又回到 D9。 这正是"工程修复"与"范式局限"的分界线。


D3 · 规则硬依赖标点

现场

复制代码
'Why don\'t you listen to me?'   → ✅ 命中 "Why don\\'t you (.*)\\?"
'Why don\'t you listen to me'    → ❌ 掉到兜底 '.*'  → 'Let\'s change focus a bit...'

根因 :模式里写死了 \?。用户少写一个问号、写成逗号、或者用中文问号 整条规则静默失效

修复 :把标点变成可选 ,并在捕获后统一剥离(见 D5 的 clean()):

python 复制代码
r"\bwhy don'?t you\b\s*(.+?)\s*[?.!]?$"

对应教材概念"一遇到规则之外的微小变化或新情况,系统便可能完全失灵" ------这就是 2.1.4 里 Brittleness 的最小可复现实例。真实用户永远不会按你的正则写标点。


D4 · 代词反射与模板"视角错位"(you → i 塞进了宾语空位)

现场

python 复制代码
swap_pronouns('you') = 'i'
'I need you' → 'Would it really help you to get i?'      # ❌ 病句,且是小写 i

⚠️ 先说一个容易骂错的地方 (我一开始也写错了,查资料后修正):

原版 ELIZA 的反射表同样把 you 反射成 I ------所以"映射本身写错了"这个说法不成立 。原版之所以不出现病句,是因为它把这件工作分成了两层

复制代码
① 反射层:把关键词之后的片段做人称转换   "I hate you"  →  "YOU hate I"
② 模板层:重组规则里【硬编码】治疗师视角的代词
   (MAD-SLIP 原版规则组形如 ((0 YOU 0 I 0) (DO YOU WISH TO 3 ME) ...),
     其中的 ME 是写死在模板里的,3 处填入反射后的动词短语)

真正的根因 :这份迷你实现只有反射这一层,却把反射结果直接填进需要宾语的位置 ------"Why do you need {0}?" 的空位是宾语,填入第一人称主语形式 i 就必然出病句。两层被压成了一层,视角错位就暴露了。

修法有两种(v2 用的是第 ① 种):

方案 做法 结果
① 改反射表 "you" → "me"(本 v2 采用) I need youWhy do you need me? ✅ 直接得到语法正确的英语
② 改模板 保持 you → I,把模板写成治疗师视角("DO YOU WISH TO 3 ME" 式) 更忠实原版 ELIZA,但每条模板都要人工斟酌视角

连带问题swap_pronouns 第一行 phrase.lower().split() 把整句强制小写 → 即使用对了映射,也会输出小写 i;且 split() 按空格分词,标点会粘在词尾(help!),导致查表失败。

修复:case-preserving + 拆分"前缀标点 / 词干 / 后缀标点"再查表:

python 复制代码
PRONOUN_SWAP = {"i": "you", "you": "me", "me": "you", "my": "your", ...}

def swap_pronouns(phrase):
    out = []
    for w in phrase.split():
        prefix = w[:len(w) - len(w.lstrip(".,!?;:\"'"))]
        suffix = w[len(w.rstrip(".,!?;:\"'")):]
        core = w[len(prefix):len(w) - len(suffix)]
        mapped = PRONOUN_SWAP.get(core.lower())
        if mapped:
            mapped = mapped.capitalize() if core[:1].isupper() else mapped
            out.append(f"{prefix}{mapped}{suffix}")
        else:
            out.append(w)
    return " ".join(out)

修复后实测:I need youWhy do you need me?


D5 · 捕获内容不剥标点 → 输出双标点

现场

复制代码
'I need help!'  → 'Would it really help you to get help!?'
'You know what I am saying?' → '...you are saying??'
'I am feeling sad today.'    → 'How do you feel about being feeling sad today.?'

根因:模板自带句号/问号,捕获内容又保留了原文标点,二者叠加。

修复:捕获后统一清洗:

python 复制代码
def clean(text):
    return text.strip().strip(".!?,;:").strip()

💡 顺带一提'I am feeling sad today.' 的输出还暴露了 D9 ------模板 being {0} 套上动名词短语 feeling sad today 得到 being feeling sad,语法上说不通。程序在符号层面完全"正确",在语义层面完全错误------这就是"符号操作 ≠ 理解"。


D6 · 强制小写化丢失大小写

现场

复制代码
'I AM SAD' → 捕获 'SAD' → swap_pronouns 小写化 → 'sad'
输出: 'Did you come to me because you are sad?'

影响 :专有名词(人名、地名)会被破坏------My mother loves Beijingyour mother loves beijing

修复:同 D4 的 case-preserving 版本(只对词干小写做查表,输出保留原大小写)。


D7 · 函数末尾的兜底 return 是死代码

现场

python 复制代码
re.search(r'.*', '')     → True      # 空串都能匹配
re.search(r'.*', 'xyz')  → True

根因rules 的最后一条是 r'.*',它能匹配任何 输入(包括空串)。因此 for 循环必然 在最后一条上命中并 return,函数末尾的

python 复制代码
return random.choice(rules[r'.*'])     # ← 永远执行不到

永远不会被执行 。这也是为什么 '我很难过'''' ' 都能拿到回应------它们是被循环内的 .* 规则接住的,不是被这个兜底接住的。

修复 :删掉死代码;或把 r'.*'rules 里移出,作为真正的 try/else 兜底,让"未命中任何规则"能被观测到(便于统计关键词覆盖率)。

📌 教学价值 :这条死代码恰好演示了"兜底规则的边界在哪"------.* 通配规则既是安全网,也让系统失去了"我不知道该说什么"的表达能力 。ELIZA 永远不会说"我不明白",它只会转移话题。LLM 的"我不知道"(拒答/不确定性表达)反而是它比规则系统更诚实的地方。


D8 · 无状态 + 输出不可复现

现场

python 复制代码
# 同一句输入连跑三次,得到三种输出(random.choice 生效)
'I am feeling sad today.' →
   'How do you feel about being feeling sad today.?'
   'Did you come to me because you are feeling sad today.?'
   'How do you feel about being feeling sad today.?'

两个子问题

子问题 后果 修复
无状态:不保存任何历史 无法做多轮连贯对话;用户说"我叫 Tom",下一句它就忘了 self.memory(见 §四)
不可复现random.choice 无种子 无法写断言、无法复现 bug、无法做回归测试 seed 参数(测试时固定)

对应教材概念"系统是无状态的(Stateless),每次回应仅基于当前单句输入" (章节 §2.2.3 原文)。这也是为什么第一章要用 prompt_history 维护对话历史------记忆不是可选功能,是序贯环境的基本要求


D9 · 无语义理解(不可修,方法论天花板)

现场

输入 输出 它"看不到"的东西
I am not happy How long have you been not happy? 否定not 只是普通词
I am feeling sad today. How do you feel about being feeling sad today.? 词性/时态feeling 是动名词
You know what I am saying? ...you are saying?? 从句结构what I am saying 是从句
That is what I am thinking How do you feel about being thinking? 同上
我很难过 Let's change focus a bit... 语言与语义:只认英文关键词

为什么修不掉 :这四条各自都能"打补丁"(加否定规则、加分词表、加从句识别......),但每打一个补丁,就新增一批需要维护的规则,并引入新的规则冲突 (补丁之间互相抢答,见 D1)。这就是组合爆炸(§五有数学说明)。

🔑 这一条是本章的灵魂 :ELIZA 并不是"做得不够好",而是这条路本身的上限就到这里 。魏泽鲍姆本人在 1976 年出版的《计算机能力与人类理性》中就对 AI 应用提出了强烈的伦理质疑------他是最早反思"机器看似理解实为操纵"的人之一,而 ELIZA 正是他用来证明这一点的实验装置。


三、概念层"可能出现的问题"(高频误区辨析)

这一节对应"你以为你懂了,其实记反了"的十个点。

# 常见误区 ❌ 正确理解 ✅
C1 "心智社会里的智能体 = 第一章说的智能体" 完全是两个概念 。心智社会的"智能体"是无心的简单心智过程 (如 GRASP 只负责抓握);第一章的智能体是能感知-决策-行动的完整实体 。明斯基的"智能体"更接近函数/模块(→ 现代叫 agent 的滥用源头就在这)
C2 PSSH 的充分性与必要性"说的是一回事" 二者互为逆命题 :充分性 = "符号系统 → 智能";必要性 = "智能 → 符号系统"。反驳前者用工程困境(知识获取瓶颈等),反驳后者用大脑/联结主义
C3 正向链 = 从目标出发(因为"正"听起来像"直奔结果") 反了 。正向链从已知事实 出发(数据驱动 );反向链从假设目标 出发(目标驱动 )。MYCIN 用的是反向链(先假设致病菌,再找证据)
C4 框架问题 = 规则太多导致组合爆炸 不是。框架问题是"动作发生后,如何高效判断哪些事物没变" (不变量的表示难题)。规则膨胀属于知识获取瓶颈 / 扩展性问题
C5 "专家系统失败是因为规则写错了" 失败源于方法论 :专家的内隐知识无法显式化成 IF-THEN (知识获取瓶颈),且真实世界充满例外(脆弱性)。规则写得再对,也覆盖不了开放世界
C6 Cyc 是深度学习项目 Cyc 是符号主义 的常识知识库工程(Lenat),手工编码常识 数十年,成果有限------它是"符号主义撞墙"的证据,不是联结主义的
C7 联结主义 = 深度学习 联结主义 1980s 就重新兴起了(PDP、反向传播);深度学习是它在算力+数据到位后的爆发形态(约 2012 年后)。中间隔了两次寒冬与三十年
C8 RL 就是"有奖励的监督学习" 本质不同:① 监督学习的数据预先标注、i.i.d. ;RL 的数据靠自己与环境交互产生 ,且决策之间强相关 ;② RL 优化累积回报 (可牺牲眼前),监督学习只拟合单步标签 ;③ RL 有探索-利用权衡,监督学习没有
C9 LLM 的推理能力是设计出来的 涌现能力 :规模跨过阈值后才出现、未被直接训练的能力(ICL、CoT)。⚠️ 注意学术争议 :有研究认为部分"涌现"是评测指标不连续 造成的假象(Schaeffer et al., 2023, Are Emergent Abilities of LLMs a Mirage? )------考试时按教材口径答,但心里要留这个问号
C10 神经符号 = 神经网络 + 知识图谱拼在一起 现代用法更精确:神经网络提供直觉与表示(系统 1),符号中间步骤(Thought / 计划 / 工具调用 JSON)提供可操作的推理接口(系统 2)。第一章的 Thought-Action-Observation 就是那个"符号接口"
C11 ELIZA 效应 = 通过了图灵测试 图灵测试是判定方法 (人类能否分辨);ELIZA 效应是心理现象 ------人明知 对方可能是程序,仍产生情感投射与信任。它说明人类的判断标准很容易被对话策略欺骗
C12 预训练解决了框架问题 只解决了知识获取瓶颈 (常识被压进权重)。框架问题(状态不变量的表示)并没有被消解------今天的智能体仍要为"记忆里什么该保留、什么该更新"设计策略(→ 图 2.10 的 Memory Update)

四、动手题:ELIZA v2 完整实现(修复 D1--D8,已实测通过)

对应习题 3。实测环境 :本机 Python 3,脚本以 importlib 回放固定对话,random.seed 固定,输出可复现。

4.1 v1 → v2 实测对照

输入 ELIZA 原版 ELIZA v2 修了哪条
My name is Tom. Let's change focus a bit... Nice to meet you, Tom. D8(记忆)
I am 30 years old. How long have you been 30 years old.? At 30, what matters most to you? D5/D1
I am not happy How long have you been not happy? Why do you think you are not happy? D9 的局部补丁
I need you Would it really help you to get i? Why do you need me? D4
I am angry at my father How long have you been angry at your father? Tell me more about your father. D1
You know what I am saying? How long have you been saying?? Tom, how long have you been saying? D2/D5 ✅
I need help! Would it really help you to get help!? Tom, would it really help you to get help? D5
My mother is not happy with my work. What was your relationship with your mother like? Tom, tell me more about your mother. D8(名字注入)
Why don't you listen to me Let's change focus a bit... Tom, can you elaborate on that? D3(不再因缺问号全盘失效)

4.2 完整代码(单文件可运行,无需任何 API Key)

python 复制代码
# -*- coding: utf-8 -*-
"""
ELIZA v2 ------ 针对原实现四处缺陷的修复版(习题 3 的动手题)
修:① 关键词优先级  ② 词边界+去标点  ③ 代词转换  ④ 否定处理  ⑤ 上下文记忆
"""
import re
import random

# ---- 规则表:(优先级, 模式, 响应模板)。优先级越大越优先,模仿原版 ELIZA 的 keyword rank ----
# 模式统一用单捕获组捕获「关键内容」,无捕获组的规则自己负责措辞
RULES = [
    (10, r"\bsorry\b",                 ["Please don't apologize.", "Apologies are not necessary."]),
    ( 8, r"\bmy name is\s+([A-Za-z]+)", ["Nice to meet you, {0}.", "Hello {0}, how are you feeling today?"]),
    ( 7, r"\bi (?:am|'m)\s+(\d+)\s*(?:years old)?\b",
                                       ["How does being {0} feel?", "At {0}, what matters most to you?"]),
    ( 6, r"\bmother\b",                ["Tell me more about your mother.",
                                        "How do you feel about your mother?"]),
    ( 6, r"\bfather\b",                ["Tell me more about your father.",
                                        "How did your father make you feel?"]),
    ( 5, r"\bi need\b\s*(.+)",         ["Why do you need {0}?", "Would it really help you to get {0}?"]),
    ( 5, r"\bi am\b\s*(.+)",           ["How long have you been {0}?", "How do you feel about being {0}?"]),
    ( 1, r".*",                        ["Please tell me more.", "Can you elaborate on that?"]),
]

# 否定感知:命中 "not/no/never/n't" 时改用这组模板,避免"being not happy"这类病句
NEG_RULES = [
    ( 5, r"\bi (?:am|'m)\s+not\s+(.+)", ["Why do you think you are not {0}?",
                                         "What makes you say you are not {0}?"]),
    ( 5, r"\bi (?:do not|don't)\s+(.+)", ["Tell me why you don't {0}."]),
]

# ---- 代词转换:case-preserving;并把 you→me / me→you,使 "I need you" → "Why do you need me?" ----
PRONOUN_SWAP = {
    "i": "you", "you": "me", "me": "you", "my": "your", "your": "my",
    "am": "are", "are": "am", "was": "were", "were": "was",
    "mine": "yours", "yours": "mine", "i'm": "you're", "you're": "i'm",
}

def swap_pronouns(phrase: str) -> str:
    """保留首字母大小写,且不再把整句粗暴小写化"""
    out = []
    for w in phrase.split():
        # 把词切成「前缀标点 / 词干 / 后缀标点」,只对词干做替换,标点原样保留
        prefix = w[:len(w) - len(w.lstrip(".,!?;:\"'"))]
        suffix = w[len(w.rstrip(".,!?;:\"'")):]
        core = w[len(prefix):len(w) - len(suffix)]
        mapped = PRONOUN_SWAP.get(core.lower())
        if mapped:
            mapped = mapped.capitalize() if core[:1].isupper() else mapped
            out.append(f"{prefix}{mapped}{suffix}")
        else:
            out.append(w)
    return " ".join(out)

def clean(text: str) -> str:
    """去掉捕获文本首尾的标点与空白 ------ 原版 'saying?' → 'being saying??' 的根因之一"""
    return text.strip().strip(".!?,;:").strip()

class Eliza:
    def __init__(self, seed=None):
        if seed is not None:
            random.seed(seed)
        self.memory = {}          # 上下文记忆:name / age

    def _remember(self, user_input: str):
        m = re.search(r"\bmy name is\s+([A-Za-z]+)", user_input, re.IGNORECASE)
        if m:
            self.memory["name"] = m.group(1).capitalize()
        m = re.search(r"\b(?:i am|i'm)\s+(\d+)\s*(?:years old)?\b", user_input, re.IGNORECASE)
        if m:
            self.memory["age"] = m.group(1)

    def respond(self, user_input: str) -> str:
        if not user_input.strip():
            return "Please tell me what's on your mind."
        self._remember(user_input)

        # ① 先扫否定规则(优先级最高),② 再按优先级降序扫主规则表
        for priority, pattern, templates in sorted(NEG_RULES + RULES, key=lambda r: -r[0]):
            m = re.search(pattern, user_input, re.IGNORECASE)
            if not m:
                continue
            captured = clean(m.group(1)) if m.groups() else ""
            reply = random.choice(templates).format(swap_pronouns(captured)) if m.groups() \
                    else random.choice(templates)
            # ⑤ 记忆注入:已知姓名时,把名字自然地带进回复
            name = self.memory.get("name")
            if name and random.random() < 0.6:
                reply = f"{name}, {reply[0].lower() + reply[1:]}"
            return reply
        return "Please tell me more."

def chat(script=None, seed=20260916):
    """script=None 走真实交互;传入列表走脚本化回放(便于测试)"""
    bot = Eliza(seed=seed)
    print("Therapist: Hello! How can I help you today?")
    lines = script if script is not None else _stdin_lines()
    for line in lines:
        print(f"You: {line}")
        if line.lower() in ["quit", "exit", "bye"]:
            print("Therapist: Goodbye. It was nice talking to you.")
            break
        print(f"Therapist: {bot.respond(line)}")

def _stdin_lines():
    """交互输入;EOF(Ctrl+Z/Ctrl+D)时优雅退出而不是抛 EOFError"""
    while True:
        try:
            yield input("You: ")
        except EOFError:
            return

if __name__ == "__main__":
    chat()

4.3 实测对话回放(含记忆注入)

复制代码
Therapist: Hello! How can I help you today?
You: My name is Tom.
Therapist: Nice to meet you, Tom.
You: I am 30 years old.
Therapist: How does being 30 feel?
You: My mother is not happy with my work.
Therapist: Tom, tell me more about your mother.
You: I need you
Therapist: Why do you need me?
You: I am angry at my father
Therapist: How did your father make you feel?
You: bye
Therapist: Goodbye. It was nice talking to you.

4.4 但请务必记住:v2 依然是符号主义

它修好了 修好(也不该指望)
优先级、词边界、标点、代词、记忆、否定模板 依然不懂 "为什么母亲不高兴"、"not happy" 到底什么情绪、我很难过 是什么意思
靠的是手工补规则 每加一条规则,就多一份冲突与维护成本(§五)
能通过脚本化回放做回归测试 换个领域(法律咨询、订机票)就要整库重写

🔑 与第三章的接口 :ChatGPT 在同样输入上的表现差异,不是"规则写得更好",而是"知识来源不同" ------它从万亿语料里学到的分布式语义表示 ,天然携带否定、时态、语序、常识。这就是"从符号到联结"的那一步跨越。


五、「组合爆炸」的数学说明(习题 3.4)

问题:为什么基于规则的方法在开放域对话中必然遇到组合爆炸、难以扩展维护?

(1)覆盖率视角------线性投入 vs 指数空间

设词表规模 V、句子长度上限 n,则可能的句子数为 V^n。取保守值 V = 10^4(常用英文词量级)、n = 5

复制代码
句子空间 ≈ (10^4)^5 = 10^20

而规则库规模 R 的增长受知识工程师人力 线性约束(每人每天写 k 条 → R ≈ k·tt 为工时):

复制代码
覆盖率 ≈ R / V^n = k·t / 10^20  →  t → ∞ 时仍 → 0

投入线性增长、需求指数增长 → 覆盖率恒趋于 0。这就是"无论多努力都追不上"的数学形态。

(2)组合视角------乘积式爆炸

更贴近工程的估计:要覆盖真实对话,规则数约等于各维度的笛卡尔积

复制代码
R ≈ |意图| × |句式| × |语境| × |说话人角色| × |情绪| × ...

即使每个维度只取 100 种,R ≈ 100^3 = 10^6 条规则 ------ 这已远超任何团队的手工维护能力(MYCIN 作为单一垂直领域 的专家系统,也只做了 600 条规则,而它处理的是结构化的医学问答,不是开放域闲聊)。

(3)交互成本------规则不是独立的

规则之间存在优先级冲突、捕获组互斥、顺序敏感 (实测见 D1:I am 抢走了 father 的关键词)。若必须两两检查一致性:

复制代码
冲突检测复杂度 = O(R²)       R = 10^6  →  10^12 次比较

规则库越大,加一条新规则的风险越高------这与软件工程里"全局状态的耦合"是同一种病。

(4)与学习范式的对照

符号主义 联结主义/预训练
能力来源 工程师逐条写 从数据中自动拟合
投入单位 每条规则(人的时间) 每个训练步(算力)
覆盖率增长 线性 / 指数需求 随参数与数据规模超线性提升
加新领域的边际成本 ≈ 重写整个规则库 微调/提示词即可迁移
失败的形态 静默失效 / 脆弱 幻觉 / 不精确

🔑 结论 :组合爆炸不是"工程没做好",而是**"知识必须由人显式写出"这一前提的必然代价**。第二章全部的历史,本质上就是人类逐步放弃这个前提的过程------先交出"感知"(联结主义),再交出"决策"(RL),最后交出"知识"(预训练)。


六、课外补充:本章之后发生了什么(时间线 + 两个协议)

以下不属于教材正文 ,是我为建立全局坐标补的,请自行核对后再引用

年份 事件 属于哪条思潮
1950 图灵发表《计算机器与智能》(图灵测试) 哲学前提
1956 达特茅斯会议,AI 学科诞生 ------
1966 ELIZA(魏泽鲍姆) 符号主义(规则对话)
1968--70 SHRDLU(威诺格拉德) 符号主义(集成闭环)
1969 框架问题(McCarthy & Hayes) 符号主义的困境
1970s MYCIN(斯坦福) 符号主义(专家系统巅峰)
1976 物理符号系统假说(Newell & Simon) 符号主义理论基石
1984 Cyc 常识知识库启动 符号主义(常识的攻坚战)
1986 《心智社会》 (明斯基)+ PDP/反向传播 分布式智能 + 联结主义复兴
1987--93 第二次 AI 寒冬(LISP 机市场崩溃) ------
1992 TD-Gammon(Tesauro,RL + 神经网络) 行为主义/RL
1997 深蓝击败卡斯帕罗夫 符号主义(搜索 + 评估)
2012 AlexNet 引爆深度学习 联结主义
2016 AlphaGo 击败李世石 RL + 深度学习
2017 Transformer 论文《Attention Is All You Need》 联结主义(架构基础)
2018 BERT / GPT-1;预训练-微调范式确立 预训练
2020 GPT-3(上下文学习能力显现) 预训练 + 涌现能力
2022 ChatGPT (RLHF 对齐);ReAct 论文(推理 + 行动交替) LLM 智能体元年
2024-11 MCP (Model Context Protocol,Anthropic 开源)------模型 ↔ 工具的纵向标准;同月 Letta 发布 AI Agent 技术栈图(即图 2.12) 智能体基础设施
2025-03 ACP(Agent Communication Protocol,IBM) 智能体间协议
2025-04 A2A(Agent2Agent Protocol,Google 发布)------智能体 ↔ 智能体的横向协作标准 智能体间协议
2025-06 Google 将 A2A 捐赠给 Linux Foundation(Microsoft、AWS、Salesforce、SAP 等 100+ 公司支持) 协议标准化
2025-08 IBM 的 ACP 并入 A2A,统一为智能体间协议 协议收敛
2025-12 Anthropic 将 MCP 捐赠给 Linux Foundation 下新成立的 Agentic AI Foundation(AAIF)(与 Block、OpenAI 共同发起) 协议治理中立化

一句话记住这两个协议的分工MCP 管"纵向"(智能体 ↔ 工具/数据),A2A 管"横向"(智能体 ↔ 智能体) ------它们都是本章 §2.3.3"智能体的社会性(通信语言、交互协议)"那个 1986 年构想的工程化落地

Sources:


七、快速诊断速查表

7.1 代码层:症状 → 真因 → 定位方法

症状 最可能的真因 定位方法
输出里有 being not XXX / not happy D9(无否定处理) 打印命中规则 → 确认命中的是 I am (.*)
输出里出现小写 i / help!? / saying?? D4 代词表 + D5 标点 单独调 swap_pronouns('you') 看返回值
明明有关键词却没命中(如"父亲"被"我是"抢走) D1 优先级靠 dict 顺序 打印命中的 patternspan
某句话永远掉到 Please tell me more. D3 标点不匹配 / 关键词不在表内 re.search 手工逐个模式试
同一句每次输出不同,无法复现 D8 random.choice 无种子 random.seed() 或注入固定 seed
感觉最后那句兜底 return 从没生效过 D7 死代码 re.search(r'.*', '') → True

7.2 概念层:快速自检

text 复制代码
□ 我能说清"充分性"与"必要性"分别被谁反驳吗?
□ 我说得出 MYCIN 用的是正向链还是反向链吗?(反向链 = 目标驱动)
□ 我知道"框架问题"问的不是"规则太多"吗?(问的是"什么没变")
□ 我能分清"知识获取瓶颈"(知识哪来)与"常识问题"(知识多广)吗?
□ 我明白明斯基的"智能体"和第一章的"智能体"不是一个东西吗?
□ 我能说出 RL 的"奖励"与监督学习的"标签"的本质差别吗?
□ 我记得"涌现能力"指 ICL 与 CoT,且它是有学术争议的吗?
□ 我能说出预训练解决的是"知识获取瓶颈",但**没有**解决框架问题吗?

7.3 总结

ELIZA.py 用 40 行代码,让你亲手复现了符号主义的全部成就与全部局限。

它能命中关键词、能转换人称、能随机应变------但它永远不知道你在说什么

这不是这个程序的失败,这是"手工编码知识"这条路的失败------而第二章剩下的全部内容,就是人类如何一步步放弃它。

相关推荐
XGeFei1 小时前
【Skills:SQL Assistant】
人工智能·langchain
y = xⁿ1 小时前
大模型基础概念
python
子非鱼eva1 小时前
昇腾开源仓Issue分析解答-mindspore精选(一)
人工智能·ai
SL_staff1 小时前
ERP排程总在纸上谈兵?JVS-APS如何用真实产能约束打通计划与执行闭环
java·人工智能·开源
jsl_jsl_jsl1 小时前
《Tauri 桌面端的 Vue 3 前端:瘦客户端 + SSE 流式消费的实现细节》
人工智能
ctlover1 小时前
排序与查找算法详解
开发语言·python
七牛云行业应用1 小时前
GPT-6 Sol突发曝光?将于本周发布,从 API 线索、三弹实测到 OpenAI 的 RSI 竞速
人工智能·ai编程
用户8356290780511 小时前
如何使用 Python 给 Word 文档添加水印
后端·python
袁俪2 小时前
多模态进工厂
人工智能