聊天机器人 本节摘要:ELIZA 用模式匹配作答,DialogFlow 映射意图,GPT 从权重答,Claude 跑工具并验证——每个时代都解决了上一个时代最显眼的失败。用户说「我想改签航班」,系统得弄清他要什么、缺什么信息、怎么补、怎么完成动作;然后用户又说「等等,我要是直接取消呢?」,系统得记住上下文、切换任务、保留状态。对话对机器学习系统很难:输入开放、输出要在多轮间连贯、可能要对世界产生动作(改签、扣款),每一步错都摆在用户眼前。聊天机器人架构循环过四种范式,每一种都是因为上一种失败得太显眼才被引入:脚本化的半个世纪(ELIZA、AIML、DialogFlow)、检索式 FAQ、神经 seq2seq 生成、LLM 智能体。
本节摘要:ELIZA 用模式匹配作答,DialogFlow 映射意图,GPT 从权重答,Claude 跑工具并验证——每个时代都解决了上一个时代最显眼的失败。用户说「我想改签航班」,系统得弄清他要什么、缺什么信息、怎么补、怎么完成动作;然后用户又说「等等,我要是直接取消呢?」,系统得记住上下文、切换任务、保留状态。对话对机器学习系统很难:输入开放、输出要在多轮间连贯、可能要对世界产生动作(改签、扣款),每一步错都摆在用户眼前。聊天机器人架构循环过四种范式,每一种都是因为上一种失败得太显眼才被引入:脚本化的半个世纪(ELIZA、AIML、DialogFlow)、检索式 FAQ、神经 seq2seq 生成、LLM 智能体。本节按顺序走一遍,并指出 2026 生产环境里这四者并非顺序替代,而是混合路由:鉴权与破坏性动作走规则,FAQ 走检索,自然措辞走神经生成,模糊开放查询走 LLM 智能体。
对应原课程:Phase 5 · Lesson 17 ·
chatbots-rule-to-neural(原英文phases/05-nlp-foundations-to-advanced/17-chatbots-rule-to-neural/docs/en.md)。前置依赖:第 13 节(问答系统)、第 14 节(信息检索)。
阅读完本节,你应当能够:
用户说「我想改签航班」。系统得弄清他要什么、缺什么信息、怎么补、怎么完成动作。然后用户又说「等等,我要是直接取消呢?」,系统得记住上下文、切换任务、保留状态。
对话对机器学习系统很难。输入开放、输出要在多轮间连贯、可能要对世界产生动作(改签、扣款),每一步错都摆在用户眼前。聊天机器人架构循环过四种范式,每一种都是因为上一种失败得太显眼才被引入。2026 的生产格局是后两者的混合。
第一种范式没撑五年——它撑了五十年。了解它的弧线很重要,因为这里面的每一台系统都是同一台机器——匹配输入、吐出罐头回应、更新一点状态——而五十年往这台机器上加规则,从未产出过通用情形。这道天花板正是第二到第四种范式存在的原因。
1950。 Turing 用一个操作性替代绕开了「机器能不能思考」:如果审问者在电传打字机上分辨不出机器与人,这个哲学问题就作废。对话在本领域有名字之前就成了它的基准。
1956。 名字来了——达特茅斯夏季研讨会上,「人工智能」一词在「智能的每个特征原则上都能被精确描述、从而让机器模拟之」的猜想中被提出。提案给实质性进展预算了两个月。
1966。 ELIZA 发布了你在第 1 步要搭的那个反射把戏:分解规则从输入里抽片段,重组规则把它们当成问题回弹。约 200 条模式、零状态、零理解——用户却照样向它倾吐。Weizenbaum 余下职业生涯都在震惊:这么少的机器就够了。
1972。 PARRY 在斯坦福建出来模拟偏执狂,补上了 ELIZA 缺的那块:内部状态。恐惧、愤怒、猜疑的数值变量每轮更新,门控下一段脚本,于是相同输入会因对话历史给出不同回应。盲测里,精神科医生分辨 PARRY 与人类患者的能力与瞎猜无异。它是人格调节的直接祖先——一个用三个浮点数实现的系统提示。同年,两个机器人在 ARPANET 上被对在一起:治疗师脚本采访偏执状态机,这是网络上第一次机器对机器的对话。
1995。 ALICE 用 AIML(一种模式-模板对的 XML 方言)把 ELIZA 配方规模化。约四万条手写类别,三次 Loebner 奖。它证明了规则系统的扩展律:更多规则买到的是覆盖,从不是通用。每条规则都是一笔要人维护的负债。
2001。 SmarterChild 把这配方摆到三千万即时通讯用户面前,加上了后端查询——天气、股票、电影时刻——再拼进模板。眯眼看,这就是穿着 2001 外衣的工具调用:解析意图、调服务、把结果渲染进回复。
五十年,一种机制,规则数节节攀升。这范式终结不是因为谁证伪了它,而是因为手写状态机的维护成本随覆盖线性增长,而用户期望随他们上周见过的东西增长。
💡 这四种范式并非顺序替代。一个 2026 生产聊天机器人会同时路由经过全部四种:鉴权与破坏性动作走规则,FAQ 走检索,自然措辞走神经生成,模糊开放查询走 LLM 智能体。
import re class RulePattern: def __init__(self, pattern, response_template): self.regex = re.compile(pattern, re.IGNORECASE) self.template = response_template PATTERNS = [ RulePattern(r"my name is (\w+)", "Nice to meet you, {0}."), RulePattern(r"i (need|want) (.+)", "Why do you {0} {1}?"), RulePattern(r"i feel (.+)", "Why do you feel {0}?"), RulePattern(r"(.*)", "Tell me more about that."), ] def rule_based_respond(user_input): for pattern in PATTERNS: m = pattern.regex.match(user_input.strip()) if m: return pattern.template.format(*m.groups()) return "I don't understand."
20 行的 ELIZA。反射把戏(「我很难过」→「你为什么觉得难过」)是 Weizenbaum 1966 的经典心理治疗师演示,至今仍有教益。
from sentence_transformers import SentenceTransformer import numpy as np FAQ = [ ("how do i reset my password", "Go to Settings > Security > Reset Password."), ("how do i cancel my order", "Go to Orders, find the order, click Cancel."), ("what is your return policy", "30-day returns on unused items, original packaging."), ] encoder = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2") faq_questions = [q for q, _ in FAQ] faq_embeddings = encoder.encode(faq_questions, normalize_embeddings=True) def faq_respond(user_input, threshold=0.5): q_emb = encoder.encode([user_input], normalize_embeddings=True)[0] sims = faq_embeddings @ q_emb best = int(np.argmax(sims)) if sims[best] < threshold: return None return FAQ[best][1]
基于阈值的拒答是关键设计选择。最佳匹配不够近,就返回 None 让系统升级处理。
用一个小型指令微调的编码器-解码器(FLAN-T5)或微调过的对话模型。2026 单独用在生产里不可用(矛盾、跑题、事实胡说),但作为混合系统里的自然措辞部件发布。DialoGPT 之类的纯解码器模型需要显式轮次分隔符与 EOS 处理才能产出连贯回应;FLAN-T5 的 text2text 流水线对教学示例开箱即用。
from transformers import pipeline chatbot = pipeline("text2text-generation", model="google/flan-t5-small") response = chatbot("Respond politely to: Hi there!", max_new_tokens=40) print(response[0]["generated_text"])
2026 生产形态:
def agent_loop(user_message, tools, llm, max_steps=5): history = [{"role": "user", "content": user_message}] for _ in range(max_steps): response = llm(history, tools=tools) tool_call = response.get("tool_call") if tool_call: tool_name = tool_call.get("name") args = tool_call.get("arguments") if not isinstance(tool_name, str) or tool_name not in tools: history.append({"role": "assistant", "tool_call": tool_call}) history.append({"role": "tool", "name": str(tool_name), "content": f"error: unknown tool {tool_name!r}"}) continue if not isinstance(args, dict): history.append({"role": "assistant", "tool_call": tool_call}) history.append({"role": "tool", "name": tool_name, "content": f"error: arguments must be a dict, got {type(args).__name__}"}) continue fn = tools[tool_name] result = fn(**args) history.append({"role": "assistant", "tool_call": tool_call}) history.append({"role": "tool", "name": tool_name, "content": result}) else: return response["content"] return "I could not complete the task in the step budget."
三件事要点名。工具是 LLM 能调用的可调用函数;循环在 LLM 返回最终答案而非工具调用时终止;步数预算在模糊任务上防无限循环。注意上面这些类型与「未知工具」检查不是装饰——它们是循环在恶意或畸形工具调用下不崩溃的护栏。
真正的生产还要加:检索优先接地(每次 LLM 调用前注入相关文档)、护栏(无确认就拒破坏性动作)、可观测性(记每一步)、评估(自动检查智能体行为合不合规范)。
def hybrid_chat(user_input): if is_destructive_action(user_input): return structured_flow(user_input) faq_answer = faq_respond(user_input, threshold=0.6) if faq_answer: return faq_answer return agent_loop(user_input, tools, llm) def is_destructive_action(text): danger_words = ["delete", "cancel", "charge", "refund", "transfer"] return any(w in text.lower() for w in danger_words)
模式:破坏性的事走确定性规则,罐头 FAQ 走检索,其余全走 LLM 智能体。这就是 2026 客服系统的发布形态。
2026 的栈:
| 用例 | 架构 |
|---|---|
| 预订、支付、鉴权 | 规则状态机 + 槽位填充 |
| 客服 FAQ | 在策展答案上检索 |
| 开放式帮助聊天 | LLM 智能体配 RAG + 工具调用 |
| 内部工具 / IDE 助手 | LLM 智能体配工具调用(搜索、读、写) |
| 陪伴 / 角色聊天机器人 | 微调 LLM 配人格系统提示、知识上检索 |
生产里总用混合路由。没有单一架构能处理好每种请求,路由层本身通常是个小型意图分类器。
自信编造:LLM 智能体声称完成了一个它没做的动作。缓解:验证结果、记录工具调用、不让 LLM 在没有成功工具返回的情况下声称做了某事。
提示注入:用户插入覆盖系统提示的文本。在 OWASP LLM 应用 Top 10 2025 里排 LLM01。两种 flavor:直接注入(贴进聊天)与间接注入(藏在文档、邮件或智能体读取的工具输出里)。
攻击成功率随场景而异。在前沿模型的一般工具使用与编程基准上,测得的成功率约 0.5~8.5%;特定高风险设置(针对 AI 编程智能体的自适应攻击、脆弱编排)曾达到约 84%。生产 CVE 包括 EchoLeak(CVE-2025-32711,CVSS 9.3)——Microsoft 365 Copilot 里一个由攻击者控制邮件触发的零点击数据外泄漏洞。
缓解:整个循环里把用户输入当不可信;工具调用前消毒;把工具输出与主提示隔离;用 Plan-Verify-Execute(PVE)模式——智能体先规划,再针对该计划验证每个动作后才执行(这能挡住工具结果注入新的未规划动作);破坏性动作要求用户确认;对工具作用域施最小权限。再多的提示工程也不能完全消除此风险,需要外部运行时防御层(LLM Guard、白名单校验、语义异常检测)。
范围蔓延:智能体因某次工具调用返回了擦边的相关信息而跑题。缓解:收窄工具契约、保持系统提示聚焦、加上跑题率评估。
无限循环:智能体反复调用同一工具。缓解:步数预算、工具调用去重、用 LLM 评判「我们在前进吗」。
上下文窗口耗尽:长对话把最早的轮次挤出上下文。缓解:总结老轮次、按相似检索相关历史轮次、或用长上下文模型。
保存为 outputs/skill-chatbot-architect.md:
--- name: chatbot-architect description: Design a chatbot stack for a given use case. version: 1.0.0 phase: 5 lesson: 17 tags: [nlp, agents, chatbot] --- Given a product context (user need, compliance constraints, available tools, data volume), output: 1. Architecture. Rule-based, retrieval, neural, LLM agent, or hybrid (specify which paths go where). 2. LLM choice if applicable. Name the model family (Claude, GPT-4, Llama-3.1, Mixtral). Match to tool-use quality and cost. 3. Grounding strategy. RAG sources, retrieval method (see lesson 14), tool contracts. 4. Evaluation plan. Task success rate, tool-call correctness, off-task rate, hallucination rate on held-out dialogs. Refuse to recommend a pure-LLM agent for any destructive action (payments, account deletion, data modification) without a structured confirmation flow. Refuse to skip the prompt-injection audit if the agent has write access to anything.
下一节,我们把视角放大到跨语言——进入「多语言 NLP」,看从逐语言建模到多语言嵌入再到 LLM 的原生存储,系统如何处理超越单一语种的世界。