diff --git a/gfa_core/extension_stage_lightweight/nl_intent.py b/gfa_core/extension_stage_lightweight/nl_intent.py index 5026f1562..964b237f5 100644 --- a/gfa_core/extension_stage_lightweight/nl_intent.py +++ b/gfa_core/extension_stage_lightweight/nl_intent.py @@ -25,6 +25,7 @@ MAX_JOB_FILE_HINTS = 200 _ENGLISH_STOPWORDS = {"analysis", "data", "file", "run", "input", "output", "files", "using", "tool"} _CHINESE_STOPWORDS = {"分析", "序列", "文件", "数据", "蛋白", "拓展", "扩展", "工具", "进行", "搜索"} +_STRONG_TRIGGER_TOKENS = ("拓展分析", "扩展分析", "extension") _RESPONSE_SYSTEM_PROMPT = ( "你是植物基因组分析平台的自然语言意图解析器。" @@ -139,22 +140,28 @@ def _record_keyword_sources(record: Mapping[str, Any]) -> list[str]: def _rough_candidates(message: str, records: list[dict]) -> list[str]: """按关键词粗筛可能命中的记录 id;不含 LLM 调用。 - 返回按命中关键词数降序排列(同分按 id 排序);「拓展分析/扩展分析/extension」 - 这类不含功能线索的强触发词才允许全部候选进目录,其余消息只返回命中子集。 + union 策略:先剔除强触发词(拓展分析/扩展分析/extension)后按关键词源 + 匹配子集,命中数降序(同分按 id 排序);除强触发词外没有任何关键词命中 + (纯「拓展分析」)时才返回全量候选兜底,否则返回 []。 """ text = str(message or "").lower() - if any(token in text for token in ("拓展分析", "扩展分析", "extension")): - return [str(record.get("extension_id")) for record in records if record.get("extension_id")] + stripped = text + for token in _STRONG_TRIGGER_TOKENS: + stripped = stripped.replace(token, " ") scored: list[tuple[int, str]] = [] for record in records: extension_id = str(record.get("extension_id") or "").strip() if not extension_id: continue - hits = sum(1 for keyword in _record_keyword_sources(record) if keyword and keyword in text) + hits = sum(1 for keyword in _record_keyword_sources(record) if keyword and keyword in stripped) if hits: scored.append((hits, extension_id)) - scored.sort(key=lambda item: (-item[0], item[1])) - return [extension_id for _, extension_id in scored] + if scored: + scored.sort(key=lambda item: (-item[0], item[1])) + return [extension_id for _, extension_id in scored] + if any(token in text for token in _STRONG_TRIGGER_TOKENS): + return [str(record.get("extension_id")) for record in records if record.get("extension_id")] + return [] def compact_extension_name(extension_id: str) -> str: