From a52310748d6f8191be1af039872abca46138b6f2 Mon Sep 17 00:00:00 2001 From: tanxing Date: Mon, 11 Aug 2025 15:05:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9A=82=E6=97=B6=E7=A7=BB=E9=99=A4=E5=BC=82?= =?UTF-8?q?=E6=AD=A5=E6=A3=80=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deepsearcher/agent/deep_search.py | 45 +++++++++++-------------------- deepsearcher/online_query.py | 4 +-- 2 files changed, 17 insertions(+), 32 deletions(-) diff --git a/deepsearcher/agent/deep_search.py b/deepsearcher/agent/deep_search.py index e882790..c1623d4 100644 --- a/deepsearcher/agent/deep_search.py +++ b/deepsearcher/agent/deep_search.py @@ -1,5 +1,3 @@ -import asyncio - from deepsearcher.agent.base import BaseAgent, describe_class from deepsearcher.embedding.base import BaseEmbedding from deepsearcher.llm.base import BaseLLM @@ -52,7 +50,8 @@ Query Questions: {query} Retrieved Chunks: {retrieved_chunks} -Respond with a list of "YES" or "NO" values, one for each chunk, in the same order as the chunks are listed. For example a list of chunks of three: ["YES", "NO", "YES"] +Respond with a list of "YES" or "NO" values, one for each chunk, in the same order as the chunks are listed. +For example, if there is a list of four chunks, the answer could be: ["YES", "NO", "YES", "YES"] """ @@ -60,7 +59,7 @@ REFLECT_PROMPT = """ Determine whether additional search queries are needed based on the original query, previous sub queries, and all retrieved document chunks. If returned chunks does not cover all previous sub-queries, this means that there are no related documents can be retrieved. In this case, try generate simliar but slightly different queries to the previous sub-queries. -And if further research is needed based on the new information, provide a Python list of more queries. +And if further research is needed based on the new information which those chunks provided, give more queries on the basis of them. (which is prefered, even if the previous sub-queries can be well answered by retrieved chunks, but ultimately according to your judge) If no further research is needed, return an empty list. @@ -79,7 +78,7 @@ You are a AI content analysis expert. Please generate a long, specific and detailed answer or report based on the previous queries and the retrieved document chunks. If the chunks are not enough to answer the query or additional information is needed to enhance the content, you should answer with your own knowledge. In this case, mark the part(s) that generated by your own with your knowledge here -(Don't place part(s) individually into one paragraph, but insert it the proper place of the context) +(Don't place part(s) individually into one paragraph, but insert it the proper place of the report) Original Query: {question} @@ -198,7 +197,7 @@ class DeepSearch(BaseAgent): content = self.llm.remove_think(content) return self.llm.literal_eval(content) - async def _search_chunks_from_vectordb(self, query: str): + def _search_chunks_from_vectordb(self, query: str): if self.route_collection: selected_collections = self.invoke( query=query, dim=self.embedding_model.dimension @@ -222,7 +221,7 @@ class DeepSearch(BaseAgent): # Format all chunks for batch processing formatted_chunks = "" for i, retrieved_result in enumerate(retrieved_results): - formatted_chunks += f"\n{retrieved_result.text}\n\n" + formatted_chunks += f"\n{retrieved_result.text}\n\n" # Batch process all chunks with a single LLM call content = self.llm.chat( @@ -308,11 +307,6 @@ class DeepSearch(BaseAgent): - A list of retrieved document results - Additional information about the retrieval process """ - return asyncio.run(self.async_retrieve(original_query, **kwargs)) - - async def async_retrieve( - self, original_query: str, **kwargs - ) -> tuple[list[RetrievalResult], dict]: max_iter = kwargs.pop("max_iter", self.max_iter) ### SUB QUERIES ### log.color_print(f" {original_query} \n") @@ -325,8 +319,7 @@ class DeepSearch(BaseAgent): return [], {} else: log.color_print( - f" Break down the original query into new sub queries: {sub_queries}\n" - ) + f" Break down the original query into new sub queries: {sub_queries} ") all_sub_queries.extend(sub_queries) sub_gap_queries = sub_queries @@ -335,36 +328,28 @@ class DeepSearch(BaseAgent): search_res_from_vectordb = [] search_res_from_internet = [] # TODO - # Create all search tasks - search_tasks = [ - self._search_chunks_from_vectordb(query) - for query in sub_gap_queries - ] - # Execute all tasks in parallel and wait for results - search_results = await asyncio.gather(*search_tasks) - # Merge all results - for result in search_results: - search_res = result - search_res_from_vectordb.extend(search_res) + # Execute all search tasks sequentially + for query in sub_gap_queries: + result = self._search_chunks_from_vectordb(query) + search_res_from_vectordb.extend(result) search_res_from_vectordb = deduplicate(search_res_from_vectordb) # search_res_from_internet = deduplicate_results(search_res_from_internet) all_search_res.extend(search_res_from_vectordb + search_res_from_internet) if iter == max_iter - 1: - log.color_print(" Exceeded maximum iterations. Exiting. \n") + log.color_print(" Exceeded maximum iterations. Exiting. ") break ### REFLECTION & GET GAP QUERIES ### - log.color_print(" Reflecting on the search results... \n") + log.color_print(" Reflecting on the search results... ") sub_gap_queries = self._generate_gap_queries( original_query, all_sub_queries, all_search_res ) if not sub_gap_queries or len(sub_gap_queries) == 0: - log.color_print(" No new search queries were generated. Exiting. \n") + log.color_print(" No new search queries were generated. Exiting. ") break else: log.color_print( - f" New search queries for next iteration: {sub_gap_queries} \n" - ) + f" New search queries for next iteration: {sub_gap_queries} ") all_sub_queries.extend(sub_gap_queries) all_search_res = deduplicate(all_search_res) diff --git a/deepsearcher/online_query.py b/deepsearcher/online_query.py index 92b1acb..eb0a321 100644 --- a/deepsearcher/online_query.py +++ b/deepsearcher/online_query.py @@ -39,10 +39,10 @@ def retrieve( Returns: A tuple containing: - A list of retrieval results - - An empty list (placeholder for future use) + - A list of strings representing consumed tokens """ default_searcher = configuration.default_searcher retrieved_results, consume_tokens, metadata = default_searcher.retrieve( original_query, max_iter=max_iter ) - return retrieved_results, [] + return retrieved_results, consume_tokens