diff --git a/framework/fel/python/plugins/fel_llama_selector_tools/callable_registers.py b/framework/fel/python/plugins/fel_llama_selector_tools/callable_registers.py deleted file mode 100644 index 0cde3122..00000000 --- a/framework/fel/python/plugins/fel_llama_selector_tools/callable_registers.py +++ /dev/null @@ -1,29 +0,0 @@ -# -- encoding: utf-8 -- -# Copyright (c) 2024 Huawei Technologies Co., Ltd. All Rights Reserved. -# This file is a part of the ModelEngine Project. -# Licensed under the MIT License. See License.txt in the project root for license information. -# ====================================================================================================================== -import functools -from inspect import signature -from typing import Callable, Any, Tuple, List - -from fitframework import fit_logger -from fitframework.core.repo.fitable_register import register_fitable - - -def __invoke_tool(input_args: dict, tool_func: Callable[..., Any], **kwargs) -> Any: - return tool_func(**input_args, **kwargs) - - -def register_callable_tool(tool: Tuple[Callable[..., Any], List[str], str], module: str, generic_id: str): - func = tool[0] - fitable_id = f"{func.__name__}" - - tool_invoke = functools.partial(__invoke_tool, tool_func=func) - tool_invoke.__module__ = module - tool_invoke.__annotations__ = { - 'input_args': dict, - 'return': signature(func).return_annotation - } - register_fitable(generic_id, fitable_id, False, [], tool_invoke) - fit_logger.info("register: generic_id = %s, fitable_id = %s", generic_id, fitable_id, stacklevel=2) diff --git a/framework/fel/python/plugins/fel_llama_selector_tools/llama_selector.py b/framework/fel/python/plugins/fel_llama_selector_tools/llama_selector.py index 32d57516..fb35b9a8 100644 --- a/framework/fel/python/plugins/fel_llama_selector_tools/llama_selector.py +++ b/framework/fel/python/plugins/fel_llama_selector_tools/llama_selector.py @@ -4,23 +4,24 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # ====================================================================================================================== import traceback -from typing import Tuple, List, Any, Callable +from typing import List -from fitframework import fit_logger +from fitframework import fit_logger, fitable from llama_index.core.base.base_selector import SingleSelection from llama_index.core.selectors import EmbeddingSingleSelector from llama_index.embeddings.openai import OpenAIEmbedding -from .callable_registers import register_callable_tool +from .types.embedding_choice_selector import EmbeddingChoiceSelectorOptions -def embedding_choice_selector(choice: List[str], query_str: str, **kwargs) -> List[SingleSelection]: +@fitable("llama.tools.embedding_choice_selector", "default") +def embedding_choice_selector(choice: List[str], query_str: str , options:EmbeddingChoiceSelectorOptions) -> List[SingleSelection]: """ Embedding selector that chooses one out of many options.""" if len(choice) == 0: return [] - api_key = kwargs.get("api_key") or "EMPTY" - model_name = kwargs.get("model_name") or "bge-large-zh" - api_base = kwargs.get("api_base") or None + api_key = options.api_key + model_name = options.model_name + api_base = options.api_base embed_model = OpenAIEmbedding(model_name=model_name, api_base=api_base, api_key=api_key) selector = EmbeddingSingleSelector.from_defaults(embed_model=embed_model) @@ -30,19 +31,3 @@ def embedding_choice_selector(choice: List[str], query_str: str, **kwargs) -> Li fit_logger.error("Invoke embedding choice selector failed.") traceback.print_exc() return [] - - -# Tuple 结构: (tool_func, config_args, return_description) -selector_toolkit: List[Tuple[Callable[..., Any], List[str], str]] = [ - (embedding_choice_selector, ["model_name", "api_key", "api_base", "prompt", "mode"], "The selected choice."), -] - -for tool in selector_toolkit: - register_callable_tool(tool, embedding_choice_selector.__module__, "llama_index.rag.toolkit") - -if __name__ == '__main__': - import time - from .llama_schema_helper import dump_llama_schema - - current_timestamp = time.strftime('%Y%m%d%H%M%S') - dump_llama_schema(selector_toolkit, f"./llama_tool_schema-{str(current_timestamp)}.json") diff --git a/framework/fel/python/plugins/fel_llama_selector_tools/tools.json b/framework/fel/python/plugins/fel_llama_selector_tools/tools.json index df2b6f70..7c945ae0 100644 --- a/framework/fel/python/plugins/fel_llama_selector_tools/tools.json +++ b/framework/fel/python/plugins/fel_llama_selector_tools/tools.json @@ -1,91 +1,156 @@ { - "tools": [ - { - "tags": [ - "LlamaIndex" - ], - "runnables": { - "LlamaIndex": { - "genericableId": "llama_index.rag.toolkit", - "fitableId": "embedding_choice_selector" - } - }, - "schema": { - "name": "embedding_choice_selector", - "description": " Embedding selector that chooses one out of many options.", - "parameters": { - "type": "object", - "properties": { - "choice": { - "title": "Choice", - "type": "array", - "items": { - "type": "string" - } - }, - "query_str": { - "title": "Query Str", - "type": "string" - }, - "model_name": { - "type": "string", - "description": "model_name" - }, - "api_key": { - "type": "string", - "description": "api_key" - }, - "api_base": { - "type": "string", - "description": "api_base" + "version" : "1.0.0", + "definitionGroups" : [ { + "name" : "llm_selector_tools", + "summary" : "LLM选择器工具组", + "description" : "基于嵌入相似度的智能选择器工具,用于从多个选项中选择与查询最相关的选项。支持配置不同的嵌入模型和API端点。", + "extensions" : { }, + "definitions" : [ { + "schema" : { + "name" : "EmbeddingChoiceSelectorTool", + "description" : "嵌入选择器,从多个选项中选择一个。输入选项列表和查询字符串,返回选择结果列表。", + "parameters" : { + "type" : "object", + "properties" : { + "choice" : { + "defaultValue" : "", + "description" : "可选项列表", + "name" : "choice", + "type" : "array", + "items" : { + "type" : "string" + }, + "example" : "" }, - "prompt": { - "type": "string", - "description": "prompt" + "query_str" : { + "defaultValue" : "", + "description" : "查询字符串", + "name" : "query_str", + "type" : "string", + "example" : "" }, - "mode": { - "type": "string", - "description": "mode" + "options" : { + "defaultValue" : "", + "description" : "嵌入选择器配置", + "name" : "options", + "type" : "object", + "properties" : { + "api_key" : { + "type" : "string" + }, + "model_name" : { + "type" : "string" + }, + "api_base" : { + "type" : "string" + } + }, + "example" : "", + "required" : [ "api_key", "model_name", "api_base" ] } }, - "required": [ - "choice", - "query_str" - ] + "required" : [ "choice", "query_str", "options" ] }, - "return": { - "title": "The Selected Choice.", - "type": "array", - "items": { - "title": "SingleSelection", - "description": "A single selection of a choice.", - "type": "object", - "properties": { - "index": { - "title": "Index", - "type": "integer" + "order" : [ "choice", "query_str", "options" ], + "return" : { + "type" : "array", + "items" : { + "type" : "object", + "properties" : { + "content" : { + "type" : "string" }, - "reason": { - "title": "Reason", - "type": "string" + "score" : { + "type" : "number" + } + } + }, + "convertor" : "" + } + } + } ] + } ], + "toolGroups" : [ { + "name" : "default", + "summary" : "默认工具组", + "description" : "包含嵌入选择器工具的默认工具组,提供基于语义相似度的智能选择功能。", + "extensions" : { }, + "definitionGroupName" : "llm_selector_tools", + "tools" : [ { + "namespace" : "embedding_choice_selector", + "schema" : { + "name" : "EmbeddingChoiceSelectorTool", + "description" : "基于嵌入相似度的智能选择器,通过计算查询字符串与选项列表的语义相似度,返回最相关的选项及其相似度分数。", + "parameters" : { + "type" : "object", + "properties" : { + "choice" : { + "name" : "choice", + "description" : "待选择的选项列表,工具将计算每个选项与查询字符串的语义相似度", + "type" : "array", + "items" : { + "type" : "string" } }, - "required": [ - "index", - "reason" - ] - } + "query_str" : { + "name" : "query_str", + "description" : "查询字符串,用于与选项列表进行语义相似度匹配", + "type" : "string" + }, + "options" : { + "name" : "options", + "description" : "嵌入模型配置参数,包括API密钥、模型名称和API基础URL", + "type" : "object", + "properties" : { + "api_key" : { + "description" : "用于访问嵌入模型的API密钥", + "type" : "string" + }, + "model_name" : { + "description" : "要使用的嵌入模型名称", + "type" : "string" + }, + "api_base" : { + "description" : "嵌入模型API的基础URL地址", + "type" : "string" + } + }, + "required" : [ "api_key", "model_name", "api_base" ] + } + }, + "required" : [ ] }, - "parameterExtensions": { - "config": [ - "model_name", - "api_key", - "api_base", - "prompt", - "mode" - ] + "order" : [ "choice", "query_str", "options" ], + "return" : { + "name" : "selection_results", + "description" : "返回选择结果列表,包含每个选项的内容和对应的相似度分数,按相似度降序排列", + "type" : "array", + "items" : { + "type" : "object", + "properties" : { + "content" : { + "description" : "选项的文本内容", + "type" : "string" + }, + "score" : { + "description" : "该选项与查询字符串的语义相似度分数(0-1之间,分数越高表示越相似)", + "type" : "number" + } + } + }, + "convertor" : "" } - } - } - ] + }, + "runnables" : { + "FIT" : { + "genericableId" : "llama.tools.embedding_choice_selector", + "fitableId" : "default" + } + }, + "extensions" : { + "tags" : [ "llama" ] + }, + "definitionName" : "EmbeddingChoiceSelectorTool" + } ] + } ] } \ No newline at end of file diff --git a/framework/fel/python/plugins/fel_llama_selector_tools/types/__init__.py b/framework/fel/python/plugins/fel_llama_selector_tools/types/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/framework/fel/python/plugins/fel_llama_selector_tools/types/embedding_choice_selector.py b/framework/fel/python/plugins/fel_llama_selector_tools/types/embedding_choice_selector.py new file mode 100644 index 00000000..f4571647 --- /dev/null +++ b/framework/fel/python/plugins/fel_llama_selector_tools/types/embedding_choice_selector.py @@ -0,0 +1,21 @@ +# -- encoding: utf-8 -- +# Copyright (c) 2025 Huawei Technologies Co., Ltd. All Rights Reserved. +# This file is a part of the ModelEngine Project. +# Licensed under the MIT License. See License.txt in the project root for license information. +# ====================================================================================================================== +class EmbeddingChoiceSelectorOptions(object): + def __init__(self , model_name : str , api_key : str , api_base : str): + self.model_name = model_name + self.api_key = api_key + self.api_base = api_base + + def __eq__(self, other): + if not isinstance(other, self.__class__): + return False + return self.__dict__ == other.__dict__ + + def __hash__(self): + return hash(tuple(self.__dict__.values())) + + def __repr__(self): + return str((self.__dict__.values())) \ No newline at end of file