目录

一、概述

1、什么是规则匹配引擎?

2、适用场景

3、核心优势

二、核心概念

1. 规则定义 (RuleDefinition)

2. 匹配逻辑

3. 意图结果 (IntentResult)

三、架构设计

1、系统架构图

2、数据流

四、核心类详解

1. RuleDefinition (规则定义类)

2. GenericIntentRuleEngine (规则引擎核心)

3. GenericIntentUtil (工具类)

五、JSON规则配置

1、基础格式

六、使用指南

1. 基础使用

2. 在Activity中使用

3. 批量测试

4. 动态管理人名

七、高级特性

1. 带人名的意图识别

2. 规则热加载

3. 性能监控

4. 自定义匹配策略

八、性能优化

1. 缓存优化

2. 线程池配置

3. 规则索引优化

4. 内存优化

九、常见问题

Q1: 如何添加新规则

Q2: 规则匹配顺序是怎样的?

Q3: 如何提高匹配准确率?

Q4: 7x24小时运行会内存泄漏吗?

Q6: 支持正则表达式吗?

Q7: 如何处理同义词?

十、总结

1、核心要点

2、最佳实践

3、扩展方向


一、概述

1、什么是规则匹配引擎?

规则匹配引擎是一种基于预定义规则进行意图识别的系统。它通过关键词匹配、排除词过滤等机制,从用户输入中识别出用户意图。

2、适用场景

  • 智能语音助手

  • 聊天机器人

  • 命令控制系统

  • 用户意图识别

  • 医疗健康监测

3、核心优势

  • 配置灵活:通过JSON文件管理规则,无需修改代码

  • 高性能:支持缓存和并发处理

  • 可扩展:支持动态添加/删除规则

  • 易维护:规则集中管理

二、核心概念

1. 规则定义 (RuleDefinition)

规则是最基本的匹配单元,包含以下要素:

字段 类型 说明 示例
ruleName String 规则名称 "血压测量"
intent String 意图标识 "血压监测"
requiredKeywords List<String> 必需关键词 ["血压"]
actionKeywords List<String> 动作关键词 ["测", "量", "看"]
excludePatterns List<String> 排除词 ["学习", "了解"]

2. 匹配逻辑

用户输入 → 排除词检查 → 必需关键词检查 → 动作关键词检查 → 返回意图

3. 意图结果 (IntentResult)

public class IntentResult {
    private String intent;      // 识别到的意图
    private String userName;    // 提取的人名
    private boolean hasUserName;// 是否包含人名
}

三、架构设计

1、系统架构图

┌─────────────────────────────────────────────────────────┐
│                     应用层 (Application)                  │
├─────────────────────────────────────────────────────────┤
│              GenericIntentUtil (工具类)                   │
│  ┌──────────────────────────────────────────────────┐  │
│  │  • 初始化加载规则                                   │  │
│  │  • 同步/异步识别                                    │  │
│  │  • 缓存管理                                        │  │
│  │  • 人名提取                                        │  │
│  └──────────────────────────────────────────────────┘  │
├─────────────────────────────────────────────────────────┤
│          GenericIntentRuleEngine (规则引擎)              │
│  ┌──────────────────────────────────────────────────┐  │
│  │  • 规则加载                                        │  │
│  │  • 意图匹配                                        │  │
│  │  • 结果返回                                        │  │
│  └──────────────────────────────────────────────────┘  │
├─────────────────────────────────────────────────────────┤
│              Easy Rules (基础框架)                       │
│  ┌──────────────────────────────────────────────────┐  │
│  │  • RulesEngine                                    │  │
│  │  • Rule                                           │  │
│  │  • Facts                                          │  │
│  └──────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────┘

2、数据流

JSON文件 → 加载规则 → 规则引擎 → 用户输入 → 匹配 → 返回结果
                ↓
            缓存存储 ← 结果缓存

四、核心类详解

  导入包

    // EasyRule 规则引擎
    api 'org.jeasy:easy-rules-core:4.1.0'
    api 'org.jeasy:easy-rules-mvel:4.1.0' // 可选,MVEL 表达式支持

1. RuleDefinition (规则定义类)

package csu.xiaoya.robotApp.ui.pagemanage.airule;

import java.util.ArrayList;
import java.util.List;

/**
 * 规则定义类
 */
public class RuleDefinition {
    private String ruleName;              // 规则名称
    private String intent;                // 意图
    private List<String> requiredKeywords; // 必需关键词
    private List<String> actionKeywords;   // 动作关键词
    private List<String> excludePatterns;  // 排除模式

    public RuleDefinition() {
        this.requiredKeywords = new ArrayList<>();
        this.actionKeywords = new ArrayList<>();
        this.excludePatterns = new ArrayList<>();
    }

    public RuleDefinition(String ruleName, String intent,
                          List<String> requiredKeywords,
                          List<String> actionKeywords,
                          List<String> excludePatterns) {
        this.ruleName = ruleName;
        this.intent = intent;
        this.requiredKeywords = requiredKeywords;
        this.actionKeywords = actionKeywords;
        this.excludePatterns = excludePatterns;
    }

    // Getters and Setters
    public String getRuleName() { return ruleName; }
    public void setRuleName(String ruleName) { this.ruleName = ruleName; }
    
    public String getIntent() { return intent; }
    public void setIntent(String intent) { this.intent = intent; }
    
    public List<String> getRequiredKeywords() { return requiredKeywords; }
    public void setRequiredKeywords(List<String> requiredKeywords) { 
        this.requiredKeywords = requiredKeywords; 
    }
    
    public List<String> getActionKeywords() { return actionKeywords; }
    public void setActionKeywords(List<String> actionKeywords) { 
        this.actionKeywords = actionKeywords; 
    }
    
    public List<String> getExcludePatterns() { return excludePatterns; }
    public void setExcludePatterns(List<String> excludePatterns) { 
        this.excludePatterns = excludePatterns; 
    }
}

2. GenericIntentRuleEngine (规则引擎核心)

package csu.xiaoya.robotApp.ui.pagemanage.airule;

import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rule;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngine;
import org.jeasy.rules.api.RulesEngineParameters;
import org.jeasy.rules.core.DefaultRulesEngine;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 通用意图规则引擎
 */
public class GenericIntentRuleEngine {
    private static volatile GenericIntentRuleEngine instance;
    private RulesEngine rulesEngine;
    private Rules rules;
    private final Map<String, String> resultCache = new ConcurrentHashMap<>();
    private List<RuleDefinition> loadedRules = new ArrayList<>();

    private GenericIntentRuleEngine() {
        initEngine();
    }

    public static GenericIntentRuleEngine getInstance() {
        if (instance == null) {
            synchronized (GenericIntentRuleEngine.class) {
                if (instance == null) {
                    instance = new GenericIntentRuleEngine();
                }
            }
        }
        return instance;
    }

    private void initEngine() {
        RulesEngineParameters parameters = new RulesEngineParameters()
                .priorityThreshold(Integer.MAX_VALUE)
                .skipOnFirstAppliedRule(true);
        rulesEngine = new DefaultRulesEngine(parameters);
        rules = new Rules();
    }

    /**
     * 加载规则
     */
    public void loadRules(List<RuleDefinition> ruleDefinitions) {
        this.loadedRules = ruleDefinitions;
        for (RuleDefinition def : ruleDefinitions) {
            try {
                rules.register(new GenericRule(def));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 识别意图
     */
    public String recognizeIntent(String input) {
        if (input == null || input.trim().isEmpty()) {
            return "unknown";
        }

        String cached = resultCache.get(input);
        if (cached != null) {
            return cached;
        }

        try {
            for (RuleDefinition rule : loadedRules) {
                if (matchRule(input, rule)) {
                    resultCache.put(input, rule.getIntent());
                    return rule.getIntent();
                }
            }
            return "unknown";
        } catch (Exception e) {
            e.printStackTrace();
            return "unknown";
        }
    }

    /**
     * 规则匹配逻辑
     */
    private boolean matchRule(String input, RuleDefinition rule) {
        if (input == null || input.isEmpty()) return false;
        String lowerInput = input.toLowerCase();

        // 1. 检查排除词
        for (String exclude : rule.getExcludePatterns()) {
            if (lowerInput.contains(exclude.toLowerCase())) {
                return false;
            }
        }

        // 2. 检查必需关键词
        boolean hasRequired = false;
        for (String keyword : rule.getRequiredKeywords()) {
            if (lowerInput.contains(keyword.toLowerCase())) {
                hasRequired = true;
                break;
            }
        }
        if (!hasRequired) return false;

        // 3. 检查动作关键词
        for (String action : rule.getActionKeywords()) {
            if (lowerInput.contains(action.toLowerCase())) {
                return true;
            }
        }
        return false;
    }

    public void clearCache() { resultCache.clear(); }
    public int getRuleCount() { return loadedRules.size(); }

    private static class GenericRule implements Rule {
        private final RuleDefinition definition;
        
        public GenericRule(RuleDefinition definition) {
            this.definition = definition;
        }
        
        @Override
        public String getName() { return definition.getRuleName(); }
        @Override
        public String getDescription() { return definition.getIntent(); }
        @Override
        public int getPriority() { return 1; }
        @Override
        public boolean evaluate(Facts facts) { return true; }
        @Override
        public void execute(Facts facts) throws Exception {}
        @Override
        public int compareTo(Rule o) { 
            return Integer.compare(this.getPriority(), o.getPriority()); 
        }
    }
}

3. GenericIntentUtil (工具类)

package csu.xiaoya.robotApp.ui.pagemanage.airule;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import com.google.gson.Gson;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 意图识别工具类
 */
public class GenericIntentUtil {
    private static final String TAG = "GenericIntentUtil";
    private static final String RULES_FILE = "aicmd/ai_cmd_rules.json";
    private static final String UNKNOWN = "unknown";
    
    private static GenericIntentRuleEngine ruleEngine;
    private static boolean isInitialized = false;
    private static ExecutorService executorService = Executors.newSingleThreadExecutor();
    private static Handler mainHandler = new Handler(Looper.getMainLooper());

    /**
     * 初始化
     */
    public static void init(Context context) {
        if (isInitialized) return;
        
        ruleEngine = GenericIntentRuleEngine.getInstance();
        List<RuleDefinition> rules = loadRulesFromJson(context);
        
        if (rules.isEmpty()) {
            Log.e(TAG, "警告: 没有加载到任何规则");
        } else {
            ruleEngine.loadRules(rules);
            isInitialized = true;
            Log.i(TAG, "规则引擎初始化成功,共加载 " + rules.size() + " 条规则");
        }
    }

    /**
     * 从JSON加载规则
     */
    private static List<RuleDefinition> loadRulesFromJson(Context context) {
        List<RuleDefinition> rules = new ArrayList<>();
        try {
            InputStream is = context.getAssets().open(RULES_FILE);
            InputStreamReader reader = new InputStreamReader(is, "UTF-8");
            Gson gson = new Gson();
            RuleDefinition[] ruleArray = gson.fromJson(reader, RuleDefinition[].class);
            if (ruleArray != null && ruleArray.length > 0) {
                rules.addAll(Arrays.asList(ruleArray));
            }
            reader.close();
            is.close();
        } catch (Exception e) {
            Log.e(TAG, "加载规则文件失败: " + e.getMessage());
        }
        return rules;
    }

    /**
     * 同步识别
     */
    public static String recognizeIntent(String text) {
        if (TextUtils.isEmpty(text)) return UNKNOWN;
        if (!isInitialized) return UNKNOWN;
        return ruleEngine.recognizeIntent(text);
    }

    /**
     * 异步识别
     */
    public static void recognizeIntent(String text, IntentCallback callback) {
        if (TextUtils.isEmpty(text)) {
            mainHandler.post(() -> callback.onResult(UNKNOWN));
            return;
        }
        
        executorService.execute(() -> {
            String result = ruleEngine.recognizeIntent(text);
            mainHandler.post(() -> callback.onResult(result));
        });
    }

    /**
     * 清除缓存
     */
    public static void clearCache() {
        if (isInitialized) ruleEngine.clearCache();
    }

    /**
     * 获取规则数量
     */
    public static int getRuleCount() {
        return isInitialized ? ruleEngine.getRuleCount() : 0;
    }

    /**
     * 回调接口
     */
    public interface IntentCallback {
        void onResult(String intent);
    }
}

五、JSON规则配置

1、基础格式

[
  {
    "ruleName": "规则名称",
    "intent": "意图标识",
    "requiredKeywords": ["必需词1", "必需词2"],
    "actionKeywords": ["动作词1", "动作词2"],
    "excludePatterns": ["排除词1", "排除词2"]
  }
]

六、使用指南

1. 基础使用

// 1. 在Application中初始化
public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        GenericIntentUtil.init(this);
    }
}

// 2. 同步识别
String intent = GenericIntentUtil.recognizeIntent("我要测血压");
Log.d("结果", intent); // 输出: 血压监测

// 3. 异步识别
GenericIntentUtil.recognizeIntent("量体温", new GenericIntentUtil.IntentCallback() {
    @Override
    public void onResult(String intent) {
        Log.d("结果", intent); // 输出: 体温监测
    }
});

2. 在Activity中使用

public class MainActivity extends AppCompatActivity {
    private EditText inputEditText;
    private TextView resultTextView;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        inputEditText = findViewById(R.id.input);
        resultTextView = findViewById(R.id.result);
        
        Button recognizeButton = findViewById(R.id.recognize);
        recognizeButton.setOnClickListener(v -> {
            String input = inputEditText.getText().toString().trim();
            if (!input.isEmpty()) {
                // 异步识别
                GenericIntentUtil.recognizeIntent(input, intent -> {
                    resultTextView.setText("识别结果: " + intent);
                });
            }
        });
    }
}

3. 批量测试

public void batchTest() {
    String[] testCases = {
        "帮我测下血压",
        "我想量体温",
        "测血糖",
        "称体重",
        "看看心率",
        "学习血压知识"
    };
    
    for (String test : testCases) {
        String intent = GenericIntentUtil.recognizeIntent(test);
        Log.d("测试", test + " -> " + intent);
    }
}

4. 动态管理人名

// 添加人名
GenericIntentUtil.addUserName("刘丹");
GenericIntentUtil.addUserName("王小明");

// 删除人名
GenericIntentUtil.removeUserName("李四");

// 批量更新
List<String> users = Arrays.asList("张三", "李四", "王五");
GenericIntentUtil.setUserNames(users);

// 获取人名列表
List<String> names = GenericIntentUtil.getUserNameList();

七、高级特性

1. 带人名的意图识别

// JSON配置人名识别规则
{
    "ruleName": "人名识别",
    "intent": "人名识别",
    "requiredKeywords": [],
    "actionKeywords": ["张三", "李四", "王五"],
    "excludePatterns": []
}

// 使用
IntentResult result = GenericIntentUtil.recognizeIntent("给张三测血压");
String intent = result.getIntent();   // "血压监测"
String userName = result.getUserName(); // "张三"

2. 规则热加载

// 重新加载规则(修改JSON后调用)
GenericIntentUtil.reloadRules(context);

// 清除缓存
GenericIntentUtil.clearCache();

3. 性能监控

// 获取线程池状态
String status = GenericIntentUtil.getThreadPoolStatus();

// 获取统计信息
String stats = GenericIntentUtil.getStats();

// 获取规则数量
int count = GenericIntentUtil.getRuleCount();

4. 自定义匹配策略

// 扩展匹配逻辑(需要修改matchRule方法)
private boolean matchRule(String input, RuleDefinition rule) {
    // 1. 支持正则表达式
    if (Pattern.matches(rule.getRegexPattern(), input)) {
        return true;
    }
    
    // 2. 支持模糊匹配
    if (StringUtils.similarity(input, rule.getKeyword()) > 0.8) {
        return true;
    }
    
    // 3. 原始匹配逻辑
    // ...
}

八、性能优化

1. 缓存优化

// LRU缓存,自动淘汰旧数据
private static final int MAX_CACHE_SIZE = 10000;
private static final LinkedHashMap<String, IntentResult> resultCache = 
    new LinkedHashMap<String, IntentResult>(MAX_CACHE_SIZE, 0.75f, true) {
        @Override
        protected boolean removeEldestEntry(Map.Entry<String, IntentResult> eldest) {
            return size() > MAX_CACHE_SIZE;
        }
    };

2. 线程池配置

// 适合7x24小时运行的线程池配置
private static ExecutorService executorService = new ThreadPoolExecutor(
    2,                          // 核心线程数
    4,                          // 最大线程数
    60,                         // 空闲线程存活时间
    TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(5000),  // 队列大小
    r -> {
        Thread t = new Thread(r, "IntentRecognition");
        t.setDaemon(true);      // 守护线程
        return t;
    },
    new ThreadPoolExecutor.DiscardPolicy()  // 丢弃策略
);

3. 规则索引优化

// 建立关键词索引
private static Map<String, List<RuleDefinition>> keywordIndex = new HashMap<>();

private void buildIndex(List<RuleDefinition> rules) {
    for (RuleDefinition rule : rules) {
        for (String keyword : rule.getRequiredKeywords()) {
            keywordIndex.computeIfAbsent(keyword, k -> new ArrayList<>())
                        .add(rule);
        }
    }
}

// 快速查找
private List<RuleDefinition> findCandidateRules(String input) {
    List<RuleDefinition> candidates = new ArrayList<>();
    for (String keyword : keywordIndex.keySet()) {
        if (input.contains(keyword)) {
            candidates.addAll(keywordIndex.get(keyword));
        }
    }
    return candidates;
}

4. 内存优化

// 使用StringBuilder避免字符串拼接
StringBuilder result = new StringBuilder();
result.append("意图: ").append(intent);
if (userName != null) {
    result.append(", 用户: ").append(userName);
}
return result.toString();

// 及时释放资源
public static void clearCache() {
    synchronized (cacheLock) {
        resultCache.clear();
    }
}

九、常见问题

Q1: 如何添加新规则

A: 只需修改 ai_cmd_rules.json 文件,添加新的规则对象即可,无需修改代码。

{
    "ruleName": "新规则",
    "intent": "新意图",
    "requiredKeywords": ["关键词"],
    "actionKeywords": ["动作词"],
    "excludePatterns": []
}

Q2: 规则匹配顺序是怎样的?

A: 规则按JSON文件中的顺序匹配,匹配到第一个规则就返回。建议将最常用的规则放在前面。

Q3: 如何提高匹配准确率?

A:

  1. 使用更精确的关键词

  2. 添加排除词过滤干扰项

  3. 使用同义词扩展

  4. 调整规则顺序

Q4: 7x24小时运行会内存泄漏吗?

A: 不会。我们做了以下优化:

  • 使用LRU缓存自动清理

  • 线程池使用守护线程

  • 使用有界队列防止堆积

  • 定期清理缓存

Q6: 支持正则表达式吗?

A: 基础版不支持,但可以扩展。在 matchRule 方法中添加正则匹配逻辑即可。

Q7: 如何处理同义词?

A: 在 actionKeywords 中添加同义词即可。

"actionKeywords": ["测", "量", "看", "查", "检查", "检测", "验", "测试", "测量"]

十、总结

1、核心要点

  1. 规则驱动:所有识别逻辑通过JSON配置

  2. 高性能:缓存 + 线程池优化

  3. 易扩展:添加规则无需修改代码

  4. 稳定运行:支持7x24小时运行

  5. 灵活使用:同步/异步多种调用方式

2、最佳实践

  • 规则JSON文件放在 assets 目录

  • 定期清理缓存避免内存过大

  • 使用异步识别避免阻塞UI线程

  • 规则按优先级排列

  • 添加排除词过滤干扰项

3、扩展方向

  • 添加正则表达式支持

  • 集成机器学习模型

  • 支持多语言识别

  • 添加规则优先级

  • 实现动态规则更新


Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐