From dd82962937a3225a24a99d93feb6a77662f2b68e Mon Sep 17 00:00:00 2001 From: seehi <6580@pm.me> Date: Tue, 20 Feb 2024 12:04:59 +0800 Subject: [PATCH] reflection for checking methods --- metagpt/rag/factory.py | 2 ++ metagpt/rag/retrievers/base.py | 6 ++++-- metagpt/rag/schema.py | 1 + metagpt/utils/reflection.py | 20 ++++++++++++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 metagpt/utils/reflection.py diff --git a/metagpt/rag/factory.py b/metagpt/rag/factory.py index 4076e43c4..475acc476 100644 --- a/metagpt/rag/factory.py +++ b/metagpt/rag/factory.py @@ -53,6 +53,7 @@ class BaseFactory: class RetrieverFactory(BaseFactory): def __init__(self): + # Dynamically add configuration and corresponding instance implementation. creators = { FAISSRetrieverConfig: self._create_faiss_retriever, BM25RetrieverConfig: self._create_bm25_retriever, @@ -88,6 +89,7 @@ class RetrieverFactory(BaseFactory): class RankerFactory(BaseFactory): def __init__(self): + # Dynamically add configuration and corresponding instance implementation. creators = { LLMRankerConfig: self._create_llm_ranker, } diff --git a/metagpt/rag/retrievers/base.py b/metagpt/rag/retrievers/base.py index 5d509f0e2..f89a078ca 100644 --- a/metagpt/rag/retrievers/base.py +++ b/metagpt/rag/retrievers/base.py @@ -6,6 +6,8 @@ from abc import abstractmethod from llama_index.retrievers import BaseRetriever from llama_index.schema import BaseNode, NodeWithScore, QueryType +from metagpt.utils.reflection import check_methods + class RAGRetriever(BaseRetriever): """Inherit from llama_index""" @@ -23,8 +25,8 @@ class ModifiableRAGRetriever(RAGRetriever): @classmethod def __subclasshook__(cls, C): - if any("add_nodes" in B.__dict__ for B in C.__mro__): - return True + if cls is ModifiableRAGRetriever: + return check_methods(C, "add_nodes") return NotImplemented @abstractmethod diff --git a/metagpt/rag/schema.py b/metagpt/rag/schema.py index 9eb76d43d..d1cbf31bf 100644 --- a/metagpt/rag/schema.py +++ b/metagpt/rag/schema.py @@ -25,5 +25,6 @@ class LLMRankerConfig(RankerConfig): ... +# If add new config, it is necessary to add the corresponding instance implementation in rag.factory RetrieverConfigType = Union[FAISSRetrieverConfig, BM25RetrieverConfig] RankerConfigType = LLMRankerConfig diff --git a/metagpt/utils/reflection.py b/metagpt/utils/reflection.py new file mode 100644 index 000000000..887cdf299 --- /dev/null +++ b/metagpt/utils/reflection.py @@ -0,0 +1,20 @@ +""" +class tools, including method inspection, class attributes, inheritance relationships, etc. +""" + + +def check_methods(C, *methods): + """ + Check if the class has methods. borrow from _collections_abc. + Useful when implementing implicit interfaces, such as defining an abstract class, isinstance can be used for determination without inheritance. + """ + mro = C.__mro__ + for method in methods: + for B in mro: + if method in B.__dict__: + if B.__dict__[method] is None: + return NotImplemented + break + else: + return NotImplemented + return True