You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python Experta框架中按指定顺序执行专家系统提问?

解决Experta专家系统规则执行顺序问题

你的问题核心是让greet相关规则(姓名、地点提问+问候)先执行完毕,再触发info相关规则(号码、身高提问+信息输出),确实可以通过salience(规则优先级)来实现,也可以通过控制事实的触发时机来完成,以下是两种可行方案:

方案一:使用salience设置规则优先级

Experta中规则默认优先级为0,数值越高的规则会被优先匹配执行。给greet相关规则设置更高的salience值,让它们先完成执行,再处理info规则。

修改后的代码如下(标注了关键修改点):

from experta import *

class Greetings(KnowledgeEngine):
    @DefFacts()
    def _initial_action(self):
        yield Fact(action="greet")
        yield Fact(action="info")

    # 给greet相关规则设置高优先级salience=10
    @Rule(Fact(action='greet'), NOT(Fact(name=W())), salience=10)
    def ask_name(self):
        self.declare(Fact(name=input("What's your name? ")))

    @Rule(Fact(action='greet'), NOT(Fact(location=W())), salience=10)
    def ask_location(self):
        self.declare(Fact(location=input("Where are you? ")))

    @Rule(Fact(action='greet'), Fact(name=MATCH.name), Fact(location=MATCH.location), salience=10)
    def greet(self, name, location):
        print("Hi %s! How is the weather in %s?" % (name, location))

    # 给info相关规则设置较低优先级salience=5
    @Rule(Fact(action='info'), NOT(Fact(number=W())), salience=5)
    def ask_number(self):
        self.declare(Fact(number=input("What's your number? ")))

    # 修正原代码的输入提示错误
    @Rule(Fact(action='info'), NOT(Fact(height=W())), salience=5)
    def ask_height(self):
        self.declare(Fact(height=input("What's your height? ")))

    @Rule(Fact(action='info'), Fact(number=MATCH.number), Fact(height=MATCH.height), salience=5)
    def info(self, number, height):
        print("Your phone number is %s! Your height is %s." % (number, height))


if __name__ == "__main__":
    system = Greetings()
    while True:
        system.reset()
        system.run()
        print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
        print("Do you want to talk again?")
        if input().lower() == 'no':
            break

方案二:控制事实触发时机(不依赖salience)

不在初始事实中直接生成info的Fact,而是等greet流程完成后,在greet方法中主动声明info的事实,这样自然会先完成问候流程,再启动信息收集流程。

修改后的代码:

from experta import *

class Greetings(KnowledgeEngine):
    @DefFacts()
    def _initial_action(self):
        # 只初始化greet的事实
        yield Fact(action="greet")

    @Rule(Fact(action='greet'), NOT(Fact(name=W())))
    def ask_name(self):
        self.declare(Fact(name=input("What's your name? ")))

    @Rule(Fact(action='greet'), NOT(Fact(location=W())))
    def ask_location(self):
        self.declare(Fact(location=input("Where are you? ")))

    @Rule(Fact(action='greet'), Fact(name=MATCH.name), Fact(location=MATCH.location))
    def greet(self, name, location):
        print("Hi %s! How is the weather in %s?" % (name, location))
        # 问候完成后,声明info的事实,触发后续规则
        self.declare(Fact(action="info"))

    @Rule(Fact(action='info'), NOT(Fact(number=W())))
    def ask_number(self):
        self.declare(Fact(number=input("What's your number? ")))

    # 修正原代码的输入提示错误
    @Rule(Fact(action='info'), NOT(Fact(height=W())))
    def ask_height(self):
        self.declare(Fact(height=input("What's your height? ")))

    @Rule(Fact(action='info'), Fact(number=MATCH.number), Fact(height=MATCH.height))
    def info(self, number, height):
        print("Your phone number is %s! Your height is %s." % (number, height))


if __name__ == "__main__":
    system = Greetings()
    while True:
        system.reset()
        system.run()
        print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
        print("Do you want to talk again?")
        if input().lower() == 'no':
            break

注意:原代码中ask_height方法的输入提示写错成了"Where are you? ",两种方案中都已修正为正确的"What's your height? "。

内容的提问来源于stack exchange,提问作者Andy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 06:01:24