"""Keyword matching evaluation rule.""" from agenteval.evaluation.rules.base import EvalRule, RuleResult, register_rule from agenteval.models import Case, Turn from agenteval.utils.llm import extract_reply_text @register_rule class KeywordMatchRule(EvalRule): """Check whether the reply contains required keywords and excludes forbidden ones.""" name = "keyword_match" async def evaluate(self, case: Case, dialog: list[Turn]) -> RuleResult: if not dialog: return RuleResult(passed=False, reason="无回复记录") last_turn = dialog[-1] text = extract_reply_text(last_turn.reply).lower() params = self.params include = [k.lower() for k in params.get("keywords", [])] exclude = [k.lower() for k in params.get("exclude_keywords", [])] missing = [k for k in include if k not in text] found_excluded = [k for k in exclude if k in text] if missing or found_excluded: reasons = [] if missing: reasons.append(f"缺少关键词: {missing}") if found_excluded: reasons.append(f"包含禁用词: {found_excluded}") return RuleResult(passed=False, reason="; ".join(reasons)) match_count = sum(1 for k in include if k in text) score = 1.0 if not include else match_count / len(include) return RuleResult(passed=True, score=score, reason="关键词匹配通过")