diff --git a/.gitignore b/.gitignore index 1e5ee4374..d15bc2576 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,8 @@ share/python-wheels/ .installed.cfg *.egg MANIFEST +metagpt/tools/schemas/ +examples/data/search_kb/*.json # PyInstaller # Usually these files are written by a python scripts from a template diff --git a/metagpt/document_store/chromadb_store.py b/metagpt/document_store/chromadb_store.py index d7344d41b..1d3a014ee 100644 --- a/metagpt/document_store/chromadb_store.py +++ b/metagpt/document_store/chromadb_store.py @@ -11,9 +11,9 @@ import chromadb class ChromaStore: """If inherited from BaseStore, or importing other modules from metagpt, a Python exception occurs, which is strange.""" - def __init__(self, name): + def __init__(self, name: str, get_or_create: bool = False): client = chromadb.Client() - collection = client.create_collection(name) + collection = client.create_collection(name, get_or_create=get_or_create) self.client = client self.collection = collection diff --git a/metagpt/rag/engines/simple.py b/metagpt/rag/engines/simple.py index 22351d8fd..469acbacf 100644 --- a/metagpt/rag/engines/simple.py +++ b/metagpt/rag/engines/simple.py @@ -171,6 +171,6 @@ class SimpleEngine(RetrieverQueryEngine): def _try_reconstruct_obj(nodes: list[NodeWithScore]): """If node is object, then dynamically reconstruct object, and save object to node.metadata["obj"].""" for node in nodes: - if node.metadata.get("is_obj"): + if node.metadata.get("is_obj", False): obj_cls = import_class(node.metadata["obj_cls_name"], node.metadata["obj_mod_name"]) node.metadata["obj"] = obj_cls(**node.metadata["obj_dict"]) diff --git a/tests/data/rsp_cache.json b/tests/data/rsp_cache.json index 9ebe50a3c..ac2e94bc4 100644 --- a/tests/data/rsp_cache.json +++ b/tests/data/rsp_cache.json @@ -261,5 +261,6 @@ "Evaluate if given numbers can reach 24 (sure/likely/impossible)\n10 14\n10 + 14 = 24\nsure\n11 12\n11 + 12 = 23\n12 - 11 = 1\n11 * 12 = 132\n11 / 12 = 0.91\nimpossible\n4 4 10\n4 + 4 + 10 = 8 + 10 = 18\n4 * 10 - 4 = 40 - 4 = 36\n(10 - 4) * 4 = 6 * 4 = 24\nsure\n4 9 11\n9 + 11 + 4 = 20 + 4 = 24\nsure\n5 7 8\n5 + 7 + 8 = 12 + 8 = 20\n(8 - 5) * 7 = 3 * 7 = 21\nI cannot obtain 24 now, but numbers are within a reasonable range\nlikely\n5 6 6\n5 + 6 + 6 = 17\n(6 - 5) * 6 = 1 * 6 = 6\nI cannot obtain 24 now, but numbers are within a reasonable range\nlikely\n10 10 11\n10 + 10 + 11 = 31\n(11 - 10) * 10 = 10\n10 10 10 are all too big\nimpossible\n1 3 3\n1 * 3 * 3 = 9\n(1 + 3) * 3 = 12\n1 3 3 are all too small\nimpossible\n10 12\n": "It seems like you have evaluated the combinations correctly. Based on the evaluations you provided, the combinations that can reach 24 are:\n\n- 10 14 (sure)\n- 4 4 10 (sure)\n- 4 9 11 (sure)\n- 5 7 8 (likely)\n- 5 6 6 (likely)\n\nThe combinations that cannot reach 24 are:\n\n- 11 12 (impossible)\n- 10 10 11 (impossible)\n- 1 3 3 (impossible)\n\nAs for the combination \"10 12,\" it seems like it was cut off. If you provide the complete expression, I can help evaluate it for you.", "Evaluate if given numbers can reach 24 (sure/likely/impossible)\n10 14\n10 + 14 = 24\nsure\n11 12\n11 + 12 = 23\n12 - 11 = 1\n11 * 12 = 132\n11 / 12 = 0.91\nimpossible\n4 4 10\n4 + 4 + 10 = 8 + 10 = 18\n4 * 10 - 4 = 40 - 4 = 36\n(10 - 4) * 4 = 6 * 4 = 24\nsure\n4 9 11\n9 + 11 + 4 = 20 + 4 = 24\nsure\n5 7 8\n5 + 7 + 8 = 12 + 8 = 20\n(8 - 5) * 7 = 3 * 7 = 21\nI cannot obtain 24 now, but numbers are within a reasonable range\nlikely\n5 6 6\n5 + 6 + 6 = 17\n(6 - 5) * 6 = 1 * 6 = 6\nI cannot obtain 24 now, but numbers are within a reasonable range\nlikely\n10 10 11\n10 + 10 + 11 = 31\n(11 - 10) * 10 = 10\n10 10 10 are all too big\nimpossible\n1 3 3\n1 * 3 * 3 = 9\n(1 + 3) * 3 = 12\n1 3 3 are all too small\nimpossible\n150\n": "It seems like you have evaluated the given numbers correctly. Here are the results:\n\n10 14: Sure\n11 12: Impossible\n4 4 10: Sure\n4 9 11: Sure\n5 7 8: Likely\n5 6 6: Likely\n10 10 11: Impossible\n1 3 3: Impossible\n\nAs for the number 150, it is not clear what operation or combination of numbers it is associated with. If you have a specific question or context for the number 150, please provide more details so that I can assist you further.", "Evaluate if given numbers can reach 24 (sure/likely/impossible)\n10 14\n10 + 14 = 24\nsure\n11 12\n11 + 12 = 23\n12 - 11 = 1\n11 * 12 = 132\n11 / 12 = 0.91\nimpossible\n4 4 10\n4 + 4 + 10 = 8 + 10 = 18\n4 * 10 - 4 = 40 - 4 = 36\n(10 - 4) * 4 = 6 * 4 = 24\nsure\n4 9 11\n9 + 11 + 4 = 20 + 4 = 24\nsure\n5 7 8\n5 + 7 + 8 = 12 + 8 = 20\n(8 - 5) * 7 = 3 * 7 = 21\nI cannot obtain 24 now, but numbers are within a reasonable range\nlikely\n5 6 6\n5 + 6 + 6 = 17\n(6 - 5) * 6 = 1 * 6 = 6\nI cannot obtain 24 now, but numbers are within a reasonable range\nlikely\n10 10 11\n10 + 10 + 11 = 31\n(11 - 10) * 10 = 10\n10 10 10 are all too big\nimpossible\n1 3 3\n1 * 3 * 3 = 9\n(1 + 3) * 3 = 12\n1 3 3 are all too small\nimpossible\n5\n": "The numbers 10 and 14 can reach 24, so that is sure. The numbers 11 and 12 cannot reach 24, so that is impossible. The numbers 4, 4, and 10 can reach 24, so that is sure. The numbers 4, 9, and 11 can reach 24, so that is sure. The numbers 5, 7, and 8 cannot reach 24, but they are within a reasonable range, so that is likely. The numbers 5, 6, and 6 cannot reach 24, but they are within a reasonable range, so that is likely. The numbers 10, 10, and 11 cannot reach 24, so that is impossible. The numbers 1, 3, and 3 cannot reach 24, so that is impossible. The number 5 by itself cannot reach 24.", - "Evaluate if given numbers can reach 24 (sure/likely/impossible)\n10 14\n10 + 14 = 24\nsure\n11 12\n11 + 12 = 23\n12 - 11 = 1\n11 * 12 = 132\n11 / 12 = 0.91\nimpossible\n4 4 10\n4 + 4 + 10 = 8 + 10 = 18\n4 * 10 - 4 = 40 - 4 = 36\n(10 - 4) * 4 = 6 * 4 = 24\nsure\n4 9 11\n9 + 11 + 4 = 20 + 4 = 24\nsure\n5 7 8\n5 + 7 + 8 = 12 + 8 = 20\n(8 - 5) * 7 = 3 * 7 = 21\nI cannot obtain 24 now, but numbers are within a reasonable range\nlikely\n5 6 6\n5 + 6 + 6 = 17\n(6 - 5) * 6 = 1 * 6 = 6\nI cannot obtain 24 now, but numbers are within a reasonable range\nlikely\n10 10 11\n10 + 10 + 11 = 31\n(11 - 10) * 10 = 10\n10 10 10 are all too big\nimpossible\n1 3 3\n1 * 3 * 3 = 9\n(1 + 3) * 3 = 12\n1 3 3 are all too small\nimpossible\n7 9 10\n": "7 * 9 - 10 = 63 - 10 = 53\n(9 - 7) * 10 = 2 * 10 = 20\nI cannot obtain 24 now, but numbers are within a reasonable range\nlikely" + "Evaluate if given numbers can reach 24 (sure/likely/impossible)\n10 14\n10 + 14 = 24\nsure\n11 12\n11 + 12 = 23\n12 - 11 = 1\n11 * 12 = 132\n11 / 12 = 0.91\nimpossible\n4 4 10\n4 + 4 + 10 = 8 + 10 = 18\n4 * 10 - 4 = 40 - 4 = 36\n(10 - 4) * 4 = 6 * 4 = 24\nsure\n4 9 11\n9 + 11 + 4 = 20 + 4 = 24\nsure\n5 7 8\n5 + 7 + 8 = 12 + 8 = 20\n(8 - 5) * 7 = 3 * 7 = 21\nI cannot obtain 24 now, but numbers are within a reasonable range\nlikely\n5 6 6\n5 + 6 + 6 = 17\n(6 - 5) * 6 = 1 * 6 = 6\nI cannot obtain 24 now, but numbers are within a reasonable range\nlikely\n10 10 11\n10 + 10 + 11 = 31\n(11 - 10) * 10 = 10\n10 10 10 are all too big\nimpossible\n1 3 3\n1 * 3 * 3 = 9\n(1 + 3) * 3 = 12\n1 3 3 are all too small\nimpossible\n7 9 10\n": "7 * 9 - 10 = 63 - 10 = 53\n(9 - 7) * 10 = 2 * 10 = 20\nI cannot obtain 24 now, but numbers are within a reasonable range\nlikely", + "### Requirements\n1. Please summarize the latest dialogue based on the reference information (secondary) and dialogue history (primary). Do not include text that is irrelevant to the conversation.\n- The context is for reference only. If it is irrelevant to the user's search request history, please reduce its reference and usage.\n2. If there are citable links in the context, annotate them in the main text in the format [main text](citation link). If there are none in the context, do not write links.\n3. The reply should be graceful, clear, non-repetitive, smoothly written, and of moderate length, in {LANG}.\n\n### Dialogue History (For example)\nA: MLOps competitors\n\n### Current Question (For example)\nA: MLOps competitors\n\n### Current Reply (For example)\n1. Alteryx Designer: etc. if any\n2. Matlab: ditto\n3. IBM SPSS Statistics\n4. RapidMiner Studio\n5. DataRobot AI Platform\n6. Databricks Lakehouse Platform\n7. Amazon SageMaker\n8. Dataiku\n#SYSTEM_MSG_END#\n### Reference Information\nABC cleanser is preferred by many with oily skin.\nL'Oreal is a popular brand with many positive reviews.\n\n### Dialogue History\n\nuser: Which facial cleanser is good for oily skin?\n\n### Current Question\nuser: Which facial cleanser is good for oily skin?\n\n### Current Reply: Based on the information, please write the reply to the Question\n\n\n": "Based on the information provided, ABC cleanser is preferred by many with oily skin. Additionally, L'Oreal is a popular brand with many positive reviews. Both of these options could be good choices for oily skin." } \ No newline at end of file diff --git a/tests/metagpt/document_store/test_chromadb_store.py b/tests/metagpt/document_store/test_chromadb_store.py index fd115dcdd..70b30d814 100644 --- a/tests/metagpt/document_store/test_chromadb_store.py +++ b/tests/metagpt/document_store/test_chromadb_store.py @@ -12,7 +12,7 @@ from metagpt.document_store.chromadb_store import ChromaStore def test_chroma_store(): """FIXME:chroma使用感觉很诡异,一用Python就挂,测试用例里也是""" # 创建 ChromaStore 实例,使用 'sample_collection' 集合 - document_store = ChromaStore("sample_collection_1") + document_store = ChromaStore("sample_collection_1", get_or_create=True) # 使用 write 方法添加多个文档 document_store.write( diff --git a/tests/metagpt/document_store/test_faiss_store.py b/tests/metagpt/document_store/test_faiss_store.py index 97f84095a..f7032be9f 100644 --- a/tests/metagpt/document_store/test_faiss_store.py +++ b/tests/metagpt/document_store/test_faiss_store.py @@ -16,7 +16,7 @@ from metagpt.roles import Sales @pytest.mark.asyncio async def test_search_json(): - store = FaissStore(EXAMPLE_PATH / "data/example.json") + store = FaissStore(EXAMPLE_PATH / "data/search_kb/example.json") role = Sales(profile="Sales", store=store) query = "Which facial cleanser is good for oily skin?" result = await role.run(query) @@ -25,7 +25,7 @@ async def test_search_json(): @pytest.mark.asyncio async def test_search_xlsx(): - store = FaissStore(EXAMPLE_PATH / "data/example.xlsx", meta_col="Answer", content_col="Question") + store = FaissStore(EXAMPLE_PATH / "data/search_kb/example.xlsx", meta_col="Answer", content_col="Question") role = Sales(profile="Sales", store=store) query = "Which facial cleanser is good for oily skin?" result = await role.run(query) @@ -34,7 +34,7 @@ async def test_search_xlsx(): @pytest.mark.asyncio async def test_write(): - store = FaissStore(EXAMPLE_PATH / "data/example.xlsx", meta_col="Answer", content_col="Question") + store = FaissStore(EXAMPLE_PATH / "data/search_kb/example.xlsx", meta_col="Answer", content_col="Question") _faiss_store = store.write() assert _faiss_store.storage_context.docstore assert _faiss_store.storage_context.vector_store.client diff --git a/tests/metagpt/rag/engines/test_simple.py b/tests/metagpt/rag/engines/test_simple.py index 60e72e422..d490089c7 100644 --- a/tests/metagpt/rag/engines/test_simple.py +++ b/tests/metagpt/rag/engines/test_simple.py @@ -1,6 +1,6 @@ import pytest from llama_index.core import VectorStoreIndex -from llama_index.core.schema import NodeWithScore, TextNode +from llama_index.core.schema import TextNode from metagpt.rag.engines import SimpleEngine from metagpt.rag.retrievers.base import ModifiableRAGRetriever @@ -97,8 +97,8 @@ class TestSimpleEngine: mock_super_aretrieve = mocker.patch( "metagpt.rag.engines.simple.RetrieverQueryEngine.aretrieve", new_callable=mocker.AsyncMock ) - nodes = [NodeWithScore(node=TextNode())] - mock_super_aretrieve.return_value = nodes + + mock_super_aretrieve.return_value = [TextNode(text="node_with_score", metadata={"is_obj": False})] # Setup engine = SimpleEngine(retriever=mocker.MagicMock()) @@ -110,7 +110,8 @@ class TestSimpleEngine: # Assertions mock_query_bundle.assert_called_once_with(test_query) mock_super_aretrieve.assert_called_once_with("query_bundle") - assert result == nodes + + assert result[0].text == "node_with_score" def test_add_docs(self, mocker): # Mock @@ -158,4 +159,4 @@ class TestSimpleEngine: assert mock_retriever.add_nodes.call_count == 1 for node in mock_retriever.add_nodes.call_args[0][0]: assert isinstance(node, TextNode) - assert "obj_dict" in node.metadata + assert "is_obj" in node.metadata