Add compact identifier method for fuzzy matching in AIClient
Introduced a static method to compact identifiers for improved fuzzy matching of tool names, allowing for more flexible user input. Updated the tool name extraction logic to support matching without underscores or dots, enhancing the tool invocation capabilities. Added a corresponding test to validate the new functionality.
This commit is contained in:
@@ -493,6 +493,11 @@ class AIClient:
|
|||||||
return None
|
return None
|
||||||
return min(limit, 5000)
|
return min(limit, 5000)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _compact_identifier(text: str) -> str:
|
||||||
|
"""Compact identifier for fuzzy matching (e.g. humanizer_zh -> humanizerzh)."""
|
||||||
|
return re.sub(r"[^a-z0-9]+", "", (text or "").lower())
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _extract_forced_tool_name(
|
def _extract_forced_tool_name(
|
||||||
user_message: str, available_tool_names: List[str]
|
user_message: str, available_tool_names: List[str]
|
||||||
@@ -500,7 +505,16 @@ class AIClient:
|
|||||||
if not user_message or not available_tool_names:
|
if not user_message or not available_tool_names:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
triggers = ["调用工具", "使用工具", "只调用", "务必调用", "必须调用", "tool"]
|
triggers = [
|
||||||
|
"调用工具",
|
||||||
|
"使用工具",
|
||||||
|
"只调用",
|
||||||
|
"务必调用",
|
||||||
|
"必须调用",
|
||||||
|
"调用",
|
||||||
|
"使用",
|
||||||
|
"tool",
|
||||||
|
]
|
||||||
if not any(trigger in user_message for trigger in triggers):
|
if not any(trigger in user_message for trigger in triggers):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -537,6 +551,38 @@ class AIClient:
|
|||||||
if len(prefix_tools) == 1:
|
if len(prefix_tools) == 1:
|
||||||
return prefix_tools[0]
|
return prefix_tools[0]
|
||||||
|
|
||||||
|
# 模糊匹配:支持省略下划线/点号的写法(如 humanizerzh)。
|
||||||
|
compact_message = AIClient._compact_identifier(user_message)
|
||||||
|
if compact_message:
|
||||||
|
compact_full_matches = []
|
||||||
|
for tool_name in available_tool_names:
|
||||||
|
compact_tool_name = AIClient._compact_identifier(tool_name)
|
||||||
|
if compact_tool_name and compact_tool_name in compact_message:
|
||||||
|
compact_full_matches.append(tool_name)
|
||||||
|
|
||||||
|
if len(compact_full_matches) == 1:
|
||||||
|
return compact_full_matches[0]
|
||||||
|
if len(compact_full_matches) > 1:
|
||||||
|
return None
|
||||||
|
|
||||||
|
compact_prefix_map: Dict[str, List[str]] = {}
|
||||||
|
for tool_name in available_tool_names:
|
||||||
|
prefix = tool_name.split(".", 1)[0]
|
||||||
|
compact_prefix = AIClient._compact_identifier(prefix)
|
||||||
|
if not compact_prefix:
|
||||||
|
continue
|
||||||
|
compact_prefix_map.setdefault(compact_prefix, []).append(tool_name)
|
||||||
|
|
||||||
|
compact_prefix_matches = [
|
||||||
|
compact_prefix
|
||||||
|
for compact_prefix in compact_prefix_map
|
||||||
|
if compact_prefix in compact_message
|
||||||
|
]
|
||||||
|
if len(compact_prefix_matches) == 1:
|
||||||
|
matched_tools = compact_prefix_map[compact_prefix_matches[0]]
|
||||||
|
if len(matched_tools) == 1:
|
||||||
|
return matched_tools[0]
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def set_personality(self, personality_name: str) -> bool:
|
def set_personality(self, personality_name: str) -> bool:
|
||||||
|
|||||||
@@ -27,6 +27,18 @@ def test_extract_forced_tool_name_unique_prefix():
|
|||||||
assert forced == "humanizer_zh.read_skill_doc"
|
assert forced == "humanizer_zh.read_skill_doc"
|
||||||
|
|
||||||
|
|
||||||
|
def test_extract_forced_tool_name_compact_prefix_without_underscore():
|
||||||
|
tools = [
|
||||||
|
"humanizer_zh.read_skill_doc",
|
||||||
|
"skills_creator.create_skill",
|
||||||
|
]
|
||||||
|
message = "调用humanizerzh人性化处理以下文本"
|
||||||
|
|
||||||
|
forced = AIClient._extract_forced_tool_name(message, tools)
|
||||||
|
|
||||||
|
assert forced == "humanizer_zh.read_skill_doc"
|
||||||
|
|
||||||
|
|
||||||
def test_extract_forced_tool_name_ambiguous_prefix_returns_none():
|
def test_extract_forced_tool_name_ambiguous_prefix_returns_none():
|
||||||
tools = [
|
tools = [
|
||||||
"skills_creator.create_skill",
|
"skills_creator.create_skill",
|
||||||
|
|||||||
Reference in New Issue
Block a user