你是不是觉得对话机器人都得靠复杂的大模型?其实不然!在很多简单场景(比如固定问答、业务引导)里,规则驱动的对话系统反而更稳定、更易控------就像给机器人写一本"应答手册",让它严格按你的剧本说话。 今天就用 Python 的两个神器------内置的re库和第三方pyknow库,手把手教你从零搭建规则引擎。
一、先搞懂:什么是"规则引擎"?
规则引擎的核心是 "如果A,就做B" 的硬编码逻辑。比如:
-
(1)用户说"你好"→ 回复"你好呀!"
-
(2)用户说"查天气"→ 回复"今天晴天"
二、工具1:re库------简单关键词匹配
re是Python内置库(不用额外安装),专门用来在字符串里"找关键词"。 就像你在一篇文章里用"Ctrl+F"搜索单词一样。
1.先认识核心函数:re.search()
这是re库最常用的函数,作用是:在一段文字里,找有没有符合"模板"的内容。
函数格式:
python
re.search(模板, 要搜索的文字, [其他设置]
其中:
(1)模板:用"正则表达式"写的搜索规则(后面详细讲)。
(2)要搜索的文字:用户输入的话(比如"你好呀!")。
(3)其他设置(可选):比如忽略大小写(re.IGNORECASE)。
返回值:
(1)如果找到:返回一个"匹配对象"(可以理解为"找到了"的标记)。
(2)如果没找到:返回None(可以理解为"没找到"的标记)。
2.正则表达式:模板(字符作用详解)
"模板"就是告诉电脑"我要找什么样的词",用正则表达式写。下面是新手必知的字符:
| 字符/符号 | 作用(零基础版) | 例子 |
|---|---|---|
| r'内容' | 告诉Python"里面的内容是原始字符串"(避免特殊符号被误解),必须加r和引号。 |
r'你好'→ 搜索"你好"这个词 |
| ` | ` | 表示"或者",匹配多个关键词中的一个。 |
() |
分组,把要提取的部分括起来(比如提取订单号)。 | r'订单(\d+)'→ 提取"订单"后的数字 |
\d |
匹配任意数字(0-9),等价于[0123456789]。 |
\d{5}→ 匹配5位数字(如12345) |
{n,} |
前面的字符至少出现n次({5,}表示至少5次)。 |
\d{5,}→ 匹配5位以上数字(如123456) |
. |
匹配任意单个字符(除了换行符),如果想匹配".",要写成\.。 |
r'天气.'→ 匹配"天气"+任意1个字符 |
**3.**python实例代码(问候+天气机器人)
下面写一个简单机器人:用户说"你好""嗨""hello"就回复问候,说"天气""气温"就回复天气
python
import re # ① 导入re库(必须写,否则用不了re的函数)
def rule_bot(user_input): # ② 定义一个函数,参数是用户输入的话 # ③ 把输入转为小写(避免"Hello"和"hello"匹配不到)
text = user_input.lower() # lower()是字符串自带函数,转小写 # ④ 规则1:用re.search()找问候关键词(你好|嗨|hello|您好)
if re.search(r'你好|嗨|hello|您好', text): # ⑤ 模板是r'你好|嗨|hello|您好'
return "你好!我是规则机器人,很高兴为你服务~" # ⑥ 找到就返回这句话
# ⑦ 规则2:用re.search()找天气关键词(天气|气温|下雨吗|温度)
elif re.search(r'天气|气温|下雨吗|温度', text):
return "【模拟天气】今天晴,20-28℃,微风~" # 找到就返回天气 # ⑧ 规则3:没找到任何关键词,返回默认回复
else:
return "抱歉,我只懂问候、天气哦~换个说法试试?"
# ⑨ 测试函数:输入不同的话,看返回结果
print(rule_bot("你好呀!")) # 输入"你好呀!"→ 匹配规则1 → 输出问候
print(rule_bot("今天会下雨吗?")) # 输入"今天会下雨吗?"→ 匹配规则2 → 输出天气
print(rule_bot("你是谁?")) # 没匹配 → 输出默认回复
逐行解释
① import re: 必须写!告诉Python"我要用re库里的函数"。
② def rule_bot(user_input)::定义一个叫rule_bot的函数,user_input是参数(用户输入的话)。
③ text = user_input.lower():user_input是用户输入的字符串,lower()是字符串方法,把字符串转成小写(比如"Hello"→"hello")。
④ if re.search(...):re.search(模板, 文字)在text里找模板内容。如果找到(返回非None),就执行下面的return。
⑤ 模板r'你好|嗨|hello|您好':r''表示原始字符串,|是"或者",所以匹配"你好""嗨""hello""您好"中的任意一个。
⑥ return "...": 函数返回这句话(作为机器人的回复)。
⑦ elif re.search(...): elif 是"否则如果",如果规则1没匹配,就试规则2。
⑧ else:如果所有规则都没匹配,执行else里的return。
⑨ print(rule_bot("...")):调用函数,传入测试输入,打印返回结果。
三、工具2:pyknow库------复杂规则推理
如果规则复杂(比如"用户说头疼+发烧>38.5℃→建议就医"),re库就不够用了。这时用pyknow库------一个"推理引擎",能像人一样"多条件判断"。
pyknow是第三方库,必须先安装才能用:
打开电脑的"命令提示符"(Windows)或"终端"(Mac/Linux),
输入:
bash
pip install pyknow # 回车,等安装完成
2.核心概念:Fact(事实)+ Rule(规则)+ 引擎
pyknow的工作逻辑像"自动核对机":
Fact(事实):记录用户输入的信息(比如"症状=头疼,严重程度=轻微"),像一张"信息卡片"。
Rule(规则):写"如果...就..."的纸条(比如"如果有头疼+轻微症状,就建议休息")。
引擎(KnowledgeEngine):把"信息卡片"和"规则纸条"放进去,自动核对,触发符合条件的规则。
3.核心函数/字符详解
① class Fact:------ 定义"信息卡片"
用类(class)定义一个"事实",比如记录症状:
python
class Symptom(Fact): # Symptom是自定义的名字,继承Fact
pass
# 空着就行,pyknow会自动处理字段
之后可以用Symptom(症状名=..., 严重程度=...)创建"信息卡片"。
② @Rule------ 定义"如果...就..."规则
用装饰器@Rule写规则,格式:
python
@Rule(条件) # 条件是"信息卡片"的组合def 规则名(self):
# 函数名随便起,self是固定参数
print("要执行的操作") # 比如回复建议
③ 条件写法:多条件组合
(1)&:表示"并且"(同时满足)。
(2)P(lambda 变量: 条件):处理数值条件(比如体温>38.5℃)。
(3)MATCH.变量名:在规则中引用"信息卡片"的字段。
(4)engine = 引擎类():创建一个引擎实例(比如engine = MedicalAdvisor())。
(5)engine.reset():清空引擎里的旧信息(每次新对话前必须调用)。
(6)engine.declare(事实):把"信息卡片"放进引擎(比如()engine.declare(Symptom(症状=...)))。
(7)engine.run():启动引擎,自动核对规则和事实,触发符合条件的回复。
4.实例代码逐行讲解(症状咨询机器人)
写一个机器人:用户说"头疼+轻微"→建议休息;说"头疼+严重+发烧>38.5℃"→建议就医。
python
from pyknow import * # ① 导入pyknow库所有内容
# ② 定义"事实":记录症状(信息卡片)
classSymptom(Fact):pass
# 空类,pyknow会自动识别字段# ③ 定义"引擎"(规则处理器)classMedicalAdvisor(KnowledgeEngine): # 继承KnowledgeEngine# ④ 规则1:单一症状(头疼+轻微)→ 建议休息
@Rule(Symptom(symptom="头疼", severity="轻微")) # 条件:症状=头疼,严重程度=轻微
defadvise_headache_mild(self): # 规则函数,self是固定参数
print("建议:多休息,避免强光,可热敷缓解~") # 触发后执行的操作# ⑤ 规则2:多条件组合(头疼+严重 且 发烧>38.5℃)→ 建议就医
# 条件1:头疼+严重(&是"并且")
@Rule(Symptom(symptom="头疼", severity="严重")&Symptom(symptom="发烧",temperature=P(lambda t: t > 38.5))
# 条件2:发烧+体温>38.5℃)
defadvise_emergency(self):print(" 警告:症状较严重,建议立即测血压/体温,不适随诊!") # ⑥ 规则3:默认规则(没匹配到任何症状时触发)
@Rule() # 无条件,就是"兜底的"defdefault_advice(self):print("抱歉,暂不支持该症状咨询,请咨询专业医生~")
# ⑦ 运行机器人:输入症状,引擎自动匹配规则
defrun_symptom_bot():engine=MedicalAdvisor() # 创建引擎实例
engine.reset() # 清空旧信息(必须!)# 模拟用户输入(实际中可从对话获取,这里简化)# 例1:用户输入"头疼,轻微"→ 症状=头疼,严重程度=轻微
engine.declare(Symptom(symptom="头疼", severity="轻微")) # 声明事实(放信息卡片) engine.run() # 启动引擎,触发规则1 → 输出建议休息# 例2:用户输入"头疼,严重"+"发烧,39℃"→ 两个条件都满足
engine.reset() # 先清空
engine.declare(Symptom(symptom="头疼", severity="严重"))
# 卡片1:头疼+严重 engine.declare(Symptom(symptom="发烧", temperature=39.0)) # 卡片2:发烧+39℃
engine.run() # 触发规则2 → 输出警告# ⑧ 测试运行
run_symptom_bot()
逐行解释:
① from pyknow import *:导入pyknow所有功能(Fact、Rule、KnowledgeEngine等)。
② class Symptom(Fact): pass:定义"症状事实",用来存症状名、严重程度、体温等。
③ class MedicalAdvisor(KnowledgeEngine):定义引擎类,继承KnowledgeEngine(pyknow的核心引擎)。
④ @Rule(Symptom(...)):规则1的条件------当引擎里有"症状=头疼,严重程度=轻微"的事实时,触发下面的函数
⑤ &和P(lambda t: t > 38.5):规则2的条件------"头疼+严重"并且"发烧+体温>38.5℃"。P(lambda t: t>38.5)是pyknow的数值判断工具,t代表体温值。
⑥ @Rule():默认规则,没有任何条件,当其他规则都不匹配时触发。
⑦ engine.declare(Symptom(...)):把"症状事实"放进引擎(相当于给引擎一张信息卡片)。⑧ engine.run():启动引擎,自动检查所有规则,触发符合条件的回复。
四、动手试试!从"抄代码"到"改代码"
-
re库练习 :把实例1的问候关键词改成
r'早上好|早安|hi',测试输入"早安!"看是否回复。 -
pyknow库练习 :在症状机器人里加一条规则"如果症状是'咳嗽'+'无痰',建议多喝水",用
@Rule(Symptom(symptom="咳嗽", phlegm="无"))实现。