fix: 目录层匹配增强(技能名拆分)+fallback(匹配不到按scope列出),兼容Hermes的trigger_conditions格式

This commit is contained in:
yumoqing 2026-08-16 15:44:26 +08:00
parent 9be706d99b
commit 69184cb4a5

View File

@ -25,6 +25,7 @@ pipeline-core: Skill Loader — 六级可插拔技能隔离
import logging import logging
import os import os
import re
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import Dict, List, Optional from typing import Dict, List, Optional
@ -280,18 +281,29 @@ class SkillLoader:
role: str = "", project_id: str = "", role: str = "", project_id: str = "",
org_id: str = "", user_id: str = "", org_id: str = "", user_id: str = "",
max_skills: int = 5) -> List[Skill]: max_skills: int = 5) -> List[Skill]:
"""根据用户输入匹配相关技能(trigger_keywords + scope 加权)""" """根据用户输入匹配相关技能(trigger_keywords + 技能名拆分 + scope 加权)。
兼容 Hermes 技能格式:多数 Hermes 技能只有 trigger_conditions(自然语言)而无
trigger_keywords,因此额外用技能名拆分匹配(module-development-spec → module/development/spec)
兜底,保证英文技能名也能被中文输入触达。
"""
all_skills = list(self.get_merged(pipeline_id, role, project_id, org_id, user_id).values()) all_skills = list(self.get_merged(pipeline_id, role, project_id, org_id, user_id).values())
scored = [] scored = []
user_lower = user_input.lower() user_lower = user_input.lower()
for skill in all_skills: for skill in all_skills:
score = 0 score = 0
# 1. 显式 trigger_keywords(中文/英文关键词)
for kw in skill.trigger_keywords: for kw in skill.trigger_keywords:
if kw.lower() in user_lower: if kw.lower() in user_lower:
score += 1 score += 3
# 2. 技能名整体匹配
if skill.name.lower() in user_lower: if skill.name.lower() in user_lower:
score += 2 score += 2
# scope 优先级加权 # 3. 技能名拆分匹配(module-development-spec → module/development/spec)
for part in re.split(r'[-_]+', skill.name.lower()):
if len(part) >= 3 and part in user_lower:
score += 1
# 4. scope 优先级加权
score += SCOPE_PRIORITY.get(skill.scope, 0) score += SCOPE_PRIORITY.get(skill.scope, 0)
if score > 0: if score > 0:
scored.append((score, skill)) scored.append((score, skill))
@ -322,10 +334,16 @@ class SkillLoader:
if user_input: if user_input:
skills = self.get_by_trigger(user_input, pipeline_id, role, skills = self.get_by_trigger(user_input, pipeline_id, role,
project_id, org_id, user_id, max_skills) project_id, org_id, user_id, max_skills)
if not skills:
# 匹配不到时兜底:按 scope 优先级 + 名字稳定排序,避免目录层为空
merged = self.get_merged(pipeline_id, role, project_id, org_id, user_id)
skills = sorted(merged.values(),
key=lambda s: (SCOPE_PRIORITY.get(s.scope, 9), s.name))
skills = skills[:max_skills]
else: else:
merged = self.get_merged(pipeline_id, role, project_id, org_id, user_id) merged = self.get_merged(pipeline_id, role, project_id, org_id, user_id)
skills = sorted(merged.values(), skills = sorted(merged.values(),
key=lambda s: SCOPE_PRIORITY.get(s.scope, 9)) key=lambda s: (SCOPE_PRIORITY.get(s.scope, 9), s.name))
skills = skills[:max_skills] skills = skills[:max_skills]
if not skills: if not skills: