用户请求限制规则配置
本文档介绍如何使用 LiteFlow 规则引擎配置用户请求的敏感词过滤、风控规则等限制策略,帮助您更好地管理 AI 大模型调用流程。
处理流程概览
下图展示了用户调用大模型时的完整处理流程,包括敏感词过滤、风控检测、聊天类型选择等环节:
graph LR
A[用户输入] --> B{敏感词过滤<br/>SensitiveWordsRule}
B -->|触发敏感词| C[流程结束]
B -->|未触发| D{是否白名单用户<br/>IsNoLimitRule}
D -->|是白名单用户| E[跳过风控<br/>NoLimitRule]
D -->|非白名单用户| F{是否内部调用<br/>IsInnerChatRule}
F -->|是内部调用| G[用户维度风控<br/>UserRiskControlRule]
F -->|外部调用| H[IP维度风控<br/>IPRiskControlRule]
G --> I[Token风控检查<br/>TokensRiskControlRule]
H --> I
I -->|触发风控| C
I -->|通过风控| J{聊天类型选择<br/>ChatTypeSelectRule}
E --> J
J -->|vectorChat| K[向量知识库聊天<br/>VectorChatRule]
J -->|simpleChat| L[简单对话<br/>SimpleChatRule]
J -->|databaseChat| M[Chat2SQL<br/>DatabaseChatRule]
J -->|functionChat| N[函数调用<br/>FunctionChatRule]
J -->|mcpChat| O[MCP调用<br/>McpChatRule]
J -->|jsonChat| P[JSON结构化<br/>JsonChatRule]
J -->|reasonChat| Q[深度推理<br/>ReasonChatRule]
J -->|text2MarkMapChat| R[文本转脑图<br/>Text2MarkMapChatRule]
J -->|infographicChatRule| S[信息图生成<br/>InfographicChatRule]
K --> T[计入账单]
L --> T
M --> T
N --> T
O --> T
P --> T
Q --> T
R --> T
S --> T
T --> U[返回结果]
业务背景
随着大模型应用场景的复杂化,传统的 if-else 判断已无法满足敏感词过滤、风控检测等多维度的判断需求。为此,PIGX 引入了 LiteFlow 规则引擎来规范化大模型调用流程,实现:
- 流程可视化:通过 XML 配置文件定义规则执行顺序和条件分支
- 高可维护性:规则逻辑解耦,易于扩展和调整
- 灵活配置:支持动态调整敏感词和风控策略
配置参数
在 application.yml 或 Nacos 配置中心添加以下配置:
pig:
ai:
risk-control: # 风控配置
sensitive-word: false # 是否开启敏感词过滤
enabled: false # 是否启用风控规则
times: 20 # 单账户每天最多调用次数
no-limit-usernames: # 不受风控限制的账号列表
- admin
配置说明:
| 参数 | 类型 | 默认值 | 说明 |
|---|
sensitive-word | Boolean | false | 是否开启敏感词过滤 |
enabled | Boolean | false | 是否启用风控规则检查 |
times | Integer | 20 | 单个用户每天最多调用次数 |
no-limit-usernames | Array | [] | 白名单用户列表,不受风控限制 |
⚠生产环境配置
生产环境建议开启敏感词过滤(sensitive-word: true)和风控规则(enabled: true),以保障系统安全和资源合理使用。
核心规则说明
PIGX AI 模块实现了完整的规则体系,涵盖风控检测、类型路由和聊天执行三个层次:
风控规则层
| 规则类 | 说明 | 触发条件 |
|---|
| SensitiveWordsRule | 敏感词过滤规则 | 用户输入包含敏感词汇 |
| IsNoLimitRule | 白名单用户判断 | 检查用户是否在白名单中 |
| NoLimitRule | 跳过风控处理 | 白名单用户直接放行 |
| IsInnerChatRule | 内外部调用判断 | 区分内部系统调用和外部用户调用 |
| UserRiskControlRule | 用户维度风控 | 基于用户名统计调用次数,超过限制则拦截 |
| IPRiskControlRule | IP维度风控 | 基于IP地址统计调用次数,防止单IP恶意调用 |
| TokensRiskControlRule | Token使用量风控 | 控制Token消耗配额(预留功能) |
聊天类型路由
| 规则类 | 说明 |
|---|
| ChatTypeSelectRule | 根据 datasetId 动态选择聊天类型,路由到对应的执行规则 |
聊天执行规则
| 规则类 | 聊天类型 | 功能说明 |
|---|
| VectorChatRule | vectorChat | 向量知识库检索(RAG),支持标准问答和语义检索 |
| SimpleChatRule | simpleChat | 简单对话,支持文本、图片理解、文件问答、网络搜索 |
| DatabaseChatRule | databaseChat | Chat2SQL,将自然语言转换为SQL查询并执行 |
| FunctionChatRule | functionChat | 函数调用,通过语义匹配自动选择并执行函数 |
| McpChatRule | mcpChat | MCP协议调用,支持外部工具集成 |
| JsonChatRule | jsonChat | JSON结构化输出,基于Schema生成结构化数据 |
| ReasonChatRule | reasonChat | 深度推理,使用推理模型处理复杂问题 |
| Text2MarkMapChatRule | text2MarkMapChat | 文本转思维导图,生成MarkMap格式 |
| InfographicChatRule | infographicChatRule | 信息图生成,输出AntV Infographic语法 |
💡规则扩展
所有规则类位于 pigx-knowledge/src/main/java/com/pig4cloud/pigx/knowledge/support/rule/ 目录下,您可以参考现有实现创建自定义规则。
规则引擎实现
PIGX 通过 LiteFlow 实现了灵活的规则配置和执行机制。
实际 LiteFlow 配置
系统使用的实际配置文件位于 pigx-knowledge/src/main/resources/rules/chat-rule.xml:
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chat">
THEN(
// 敏感词判断,触发直接退出流程
sensitive,
// 判断是否执行风控规则,触发直接退出流程
// 内部调用按用户名+总量控制,外部调用按IP+总量控制
IF(isNoLimit, noLimit, IF(isInner, WHEN(user,tokens), WHEN(ip,tokens)))
);
</chain>
</flow>
配置说明:
sensitive:敏感词过滤节点
isNoLimit:判断是否为白名单用户
noLimit:白名单用户的空处理节点
isInner:判断是否为内部调用
user:用户维度风控(内部调用时使用)
ip:IP维度风控(外部调用时使用)
tokens:Token使用量风控(预留)
规则实现示例
1. 敏感词过滤规则
// 敏感词过滤规则
@Slf4j
@Component("sensitive")
@RequiredArgsConstructor
public class SensitiveWordsRule extends NodeComponent {
private final AiChatRecordMapper aiChatRecordMapper;
private final AiKnowledgeProperties aiKnowledgeProperties;
@Override
public void process() {
ChatMessageContext messageContext = this.getContextBean(ChatMessageContext.class);
AiDatasetEntity aiDataset = messageContext.getAiDataset();
// 判断是否开启了敏感词过滤
if (YesNoEnum.NO.getCode().equals(aiDataset.getSensitiveFlag())) {
return;
}
// 敏感词过滤
SensitiveWordBs sensitiveWordBs = SpringUtil.getBean(SensitiveWordBs.class);
if (sensitiveWordBs.contains(messageContext.getChatMessageDTO().getContent())) {
Long messageKey = messageContext.getChatMessageDTO().getMessageKey();
AiChatRecordEntity aiChatRecordEntity = new AiChatRecordEntity();
messageContext.setErrorMessage(aiDataset.getSensitiveMsg());
setIsEnd(true); // 设置错误消息并终止流程
}
}
}
2. 用户维度风控规则
// 用户维度风控规则
@Slf4j
@Component("user")
@RequiredArgsConstructor
public class UserRiskControlRule extends NodeComponent {
private final AiKnowledgeProperties aiKnowledgeProperties;
private final AiBillService aiBillService;
@Override
public void process() {
ChatMessageContext messageContext = this.getContextBean(ChatMessageContext.class);
String risked = riskControl(messageContext.getUsername());
if (StrUtil.isNotBlank(risked)) {
messageContext.setErrorMessage(risked);
setIsEnd(true);
}
}
private String riskControl(String username) {
// 统计用户从昨天到现在的调用次数
long count = aiBillService.count(Wrappers.<AiBillEntity>lambdaQuery()
.eq(StrUtil.isNotBlank(username), AiBillEntity::getCreateBy, username)
.ge(AiBillEntity::getCreateTime, DateUtil.yesterday()));
log.info("username:{}, count:{}", username, count);
if (count > riskControl.getTimes()) {
return riskControl.getErrorMsg();
}
return null;
}
}
3. 布尔判断规则(白名单)
// 白名单判断规则
@Slf4j
@Component("isNoLimit")
@RequiredArgsConstructor
public class IsNoLimitRule extends NodeBooleanComponent {
private final AiKnowledgeProperties aiKnowledgeProperties;
@Override
public boolean processBoolean() throws Exception {
// 如果白名单为空,所有用户都需要风控
if (CollUtil.isEmpty(aiKnowledgeProperties.getRiskControl().getNoLimitUsernames())) {
return false;
}
String username = SecurityUtils.getUser().getUsername();
return aiKnowledgeProperties.getRiskControl().getNoLimitUsernames().contains(username);
}
}
💡规则类型说明
- NodeComponent:普通处理节点,可以通过
setIsEnd(true) 终止流程
- NodeBooleanComponent:布尔判断节点,返回 true/false 用于条件分支
- NodeSwitchComponent:选择节点,返回字符串用于多路分支
4. 聊天类型选择规则
// 聊天类型选择规则
@Slf4j
@Component("selectChatType")
public class ChatTypeSelectRule extends NodeSwitchComponent {
@Override
public String processSwitch() throws Exception {
ChatMessageContext messageContext = this.getContextBean(ChatMessageContext.class);
ChatMessageDTO lastUserMessage = messageContext.getChatMessageDTO();
// 根据数据集ID选择对应的聊天类型
ChatTypeEnums chatTypeEnums = ChatTypeEnums.fromCode(lastUserMessage.getDatasetId());
return Objects.requireNonNullElse(chatTypeEnums, ChatTypeEnums.VECTOR_CHAT).getType();
}
}
扩展指南
添加自定义风控规则
当您需要新增自定义风控规则时,可以按照以下步骤进行扩展。
步骤 1:创建规则实现类
在 pigx-knowledge/src/main/java/com/pig4cloud/pigx/knowledge/support/rule/ 目录下创建新的规则类:
// 自定义内容质量风控规则
@Slf4j
@Component("contentQuality")
@RequiredArgsConstructor
public class ContentQualityRule extends NodeComponent {
private final YourCustomService customService;
@Override
public void process() {
ChatMessageContext messageContext = this.getContextBean(ChatMessageContext.class);
String content = messageContext.getChatMessageDTO().getContent();
boolean isLowQuality = checkContentQuality(content);
if (isLowQuality) {
log.warn("内容质量不达标,用户:{}", messageContext.getUsername());
messageContext.setErrorMessage("输入内容质量不符合要求,请重新输入");
setIsEnd(true);
}
}
private boolean checkContentQuality(String content) {
// 自定义质量检查逻辑
if (content.length() < 5) {
return true;
}
return customService.scoreContent(content) < 0.6;
}
}
步骤 2:更新 LiteFlow 配置
修改 pigx-knowledge/src/main/resources/rules/chat-rule.xml,将新规则加入流程:
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chat">
THEN(
// 敏感词判断
sensitive,
// 新增:内容质量检查
contentQuality,
// 风控规则判断
IF(isNoLimit, noLimit, IF(isInner, WHEN(user,tokens), WHEN(ip,tokens)))
);
</chain>
</flow>
并行执行优化:
如果需要并行执行多个风控规则,可以使用 WHEN 语法:
WHEN(user, ip, contentQuality, tokens)
这样多个规则会并行执行,提高性能。
添加新的聊天类型
如果需要添加新的聊天类型(如 customChat),需要完成以下步骤:
1. 创建 ChatRule 实现
// 自定义聊天规则实现
@Slf4j
@Component("customChat")
@RequiredArgsConstructor
public class CustomChatRule implements ChatRule {
private final ModelProvider modelProvider;
@Override
public Flux<AiMessageResultDTO> process(ChatMessageDTO chatMessageDTO) {
AiStreamAssistantService streamAssistantService = modelProvider
.getAiStreamAssistant(chatMessageDTO.getModelName())
.getValue();
return streamAssistantService
.chat(chatMessageDTO.getConversationId(), chatMessageDTO.getContent())
.map(AiMessageResultDTO::new);
}
}
2. 添加聊天类型枚举
在 ChatTypeEnums 中添加新的类型:
public enum ChatTypeEnums {
VECTOR_CHAT("vectorChat", "向量聊天"),
SIMPLE_CHAT("simpleChat", "简单聊天"),
CUSTOM_CHAT("customChat", "自定义聊天"), // 新增
// ... 其他类型
}
3. 更新路由逻辑
确保 ChatTypeSelectRule 能够正确识别并路由到新的聊天类型。
如何调试规则执行流程?
LiteFlow 提供了详细的执行日志,可以通过以下配置开启:
liteflow:
print-execution-log: true # 打印执行日志
enable-log: true # 启用日志
log-level: debug # 日志级别
开启后,控制台会输出类似以下的日志:
[LiteFlow] 执行链路: chat
[LiteFlow] 执行节点: sensitive
[LiteFlow] 节点 sensitive 执行完成,耗时: 5ms
[LiteFlow] 执行节点: isNoLimit
[LiteFlow] 节点 isNoLimit 返回: false
...