You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I assume the error appears when RouterQueryEngine uses more than one VectorStore or collection. This indeed is when a RuntimeError occurs on my end and in the linked issue. In my case the error is only thrown when using a front end (see below—I replaced the front end interaction with print statements).
The method run_async_tasks generates a list of coroutines, which is than executed via asyncio_run. The method asyncio_run is used to conrurrently execute the coroutines.
I suggest to rely on the newer functionalty of Task Groups¶ to run the coroutines directly in the RouterEngine.
The implementation below shows how the tasks are grouped together and executed before the acombine_responses generates a summary based on the results of all selected collections.
asyncio.TaskGroup.create_task() is a new alternative leveraging structural concurrency; it allows for waiting for a group of related tasks with strong safety guarantees.
Make a Qdrant-instance available to your python run time (i.e. via a docker container).
for reference, this is llamas Qdrant example
Insert your OpenAI Key.
Install the dependencies (ref. imports.)
importasynciofromllama_index.core.llama_datasetimportdownload_llama_datasetfromllama_index.coreimportVectorStoreIndeximportosfromllama_index.coreimportVectorStoreIndex, SimpleDirectoryReaderfromllama_index.coreimportStorageContextfromllama_index.vector_stores.qdrantimportQdrantVectorStorefromllama_index.coreimportSettingsfromllama_index.core.workflowimportContextfromllama_index.core.agent.workflowimport (
FunctionAgent,
AgentWorkflow,
AgentOutput,
AgentInput,
)
fromllama_index.core.selectorsimportLLMMultiSelectorfromllama_index.core.indices.baseimportBaseQueryEnginefromllama_index.core.toolsimportFunctionToolfromllama_index.core.toolsimportQueryEngineTool, ToolMetadatafromllama_index.core.query_engineimportRouterQueryEnginefromqdrant_clientimportQdrantClient, AsyncQdrantClient# 1. first load the environment variables for your LLMs I hide this via## This is how i hide the Mistral API Key init and llama Index Settings ## from config_loader import LLM# Copied this from the Qdrant exampleos.environ["OPENAI_API_KEY"] ="your_api_key_here"# download and install dependencies for benchmark datasetdata_collection='Uber10KDataset2021'col_name_2="".join([data_collection, "_copy"])
# if data does not exists, download itifnotos.path.exists(f'./data/{data_collection}'):
rag_dataset, documents=download_llama_dataset(data_collection, './data')
else:
documents=SimpleDirectoryReader(f'./data/{data_collection}').load_data()
definit_collection_1_and_2():
client=QdrantClient(host="localhost", port=6333)
vector_store1=QdrantVectorStore(client=client, collection_name=data_collection)
ifvector_store1._collection_exists(data_collection):
print(f"collection {data_collection} exists")
else:
storage_context1=StorageContext.from_defaults(vector_store=vector_store1)
index1=VectorStoreIndex.from_documents(
documents,
storage_context=storage_context1,
)
print(index1.as_query_engine().query("What is the total revenue of Uber in 2021?"))
vector_store2=QdrantVectorStore(client=client, collection_name=col_name_2)
ifvector_store2._collection_exists(col_name_2):
print(f"collection {col_name_2} exists")
else:
storage_context2=StorageContext.from_defaults(vector_store=vector_store2)
index2=VectorStoreIndex.from_documents(
documents,
storage_context=storage_context2,
)
print(index2.as_query_engine().query("What is the total revenue of Uber in 2021?"))
# test if it worksdefbuild_workflow_and_context():
aqdrant_client=AsyncQdrantClient(host="localhost", port=6333)
defget_query_engine(collection_name: str) ->BaseQueryEngine:
vector_store: QdrantVectorStore=QdrantVectorStore(aclient=aqdrant_client, collection_name=collection_name)
index: VectorStoreIndex=VectorStoreIndex.from_vector_store( vector_store)
returnindex.as_query_engine(use_async=True)
query_engine_tools= [
QueryEngineTool(
query_engine=get_query_engine(data_collection),
metadata=ToolMetadata(
name=data_collection,
description="Public data for {data_collection}",
)),
QueryEngineTool(
query_engine=get_query_engine(col_name_2),
metadata=ToolMetadata(
name=col_name_2,
description="Public data for {data_collection}",
)),
]
router_engine=RouterQueryEngine(
selector=LLMMultiSelector.from_defaults(
prompt_template_str="Given a user query, select a collection."
),
query_engine_tools=query_engine_tools,
verbose=True,
)
asyncdefquery_router_engine(query: str) ->str:
response=awaitrouter_engine.aquery(query)
returnstr(response)
retrieve_tool=FunctionTool.from_defaults(
async_fn=query_router_engine,
name="RagAgent",
description=f"The RagAgent for Uber finance data collections."
)
response_agent=FunctionAgent(
name="GeneralAgent",
description="The GeneralAgent communicates with the user",
system_prompt=""" You are the GeneralAgent. Your task is to query the available knowledge resources. Make sure to leverage all available collections. """,
tools=[retrieve_tool]
)
workflow=AgentWorkflow(
agents=[response_agent],
root_agent=response_agent.name
)
ctx=Context(workflow=workflow)
returnworkflow, ctxasyncdefmain():
user_request="What is the total revenue for Uber in 2021 ?"workflow, ctx=build_workflow_and_context()
handler=workflow.run(
user_msg=user_request,
ctx=ctx,
verbose=True
)
asyncforeventinhandler.stream_events():
ifisinstance(event, AgentInput):
print(f"========{event.current_agent_name}:=========>")
print(event.input)
print("=================<")
ifisinstance(event, AgentOutput) andevent.response.content:
print("<================>")
print(f"{event.current_agent_name}: {event.response.content}")
print("<================>")
if__name__=="__main__":
init_collection_1_and_2()
asyncio.run(main())
Relevant Logs/Tracbacks
See the Error Message: "Detected nested async. Please use nest_asyncio.apply() to allow nested event loops.Or, use async entry methods like aquery(), aretriever, achat, etc." in the verbose Log.
collection Uber10KDataset2021 exists
collection Uber10KDataset2021_copy exists
Keyword arguments are not supported when 'run()' is invoked with the 'start_event' parameter. These keyword arguments will be ignored: {'verbose': True}
========GeneralAgent:=========>
[ChatMessage(role=<MessageRole.SYSTEM: 'system'>, additional_kwargs={}, blocks=[TextBlock(block_type='text', text='\n You are the GeneralAgent. Your task is to query the available knowledge resources. Make sure to leverage all available collections.\n ')]), ChatMessage(role=<MessageRole.USER: 'user'>, additional_kwargs={}, blocks=[TextBlock(block_type='text', text='What is the total revenue for Uber in 2021 ?')])]
=================<
Selecting query engine 0: This choice is selected because it best fits the criteria of the user query..
Selecting query engine 1: This choice is selected because it provides additional relevant information to the user query..
========GeneralAgent:=========>
[ChatMessage(role=<MessageRole.SYSTEM: 'system'>, additional_kwargs={}, blocks=[TextBlock(block_type='text', text='\n You are the GeneralAgent. Your task is to query the available knowledge resources. Make sure to leverage all available collections.\n ')]), ChatMessage(role=<MessageRole.USER: 'user'>, additional_kwargs={}, blocks=[TextBlock(block_type='text', text='What is the total revenue for Uber in 2021 ?')]), ChatMessage(role=<MessageRole.ASSISTANT: 'assistant'>, additional_kwargs={'tool_calls': [ToolCall(function=FunctionCall(name='RagAgent', arguments='{"query": "What is the total revenue for Uber in 2021 ?"}'), id='w8jKyCeKk', type=None, index=0)]}, blocks=[TextBlock(block_type='text', text='')]), ChatMessage(role=<MessageRole.TOOL: 'tool'>, additional_kwargs={'tool_call_id': 'w8jKyCeKk'}, blocks=[TextBlock(block_type='text', text='Detected nested async. Please use nest_asyncio.apply() to allow nested event loops.Or, use async entry methods like `aquery()`, `aretriever`, `achat`, etc.')])]
=================<
Selecting query engine 0: This collection is selected because it matches the user's query criteria..Selecting query engine 1: This collection is selected because it contains relevant information to the user's query..
========GeneralAgent:=========>
[ChatMessage(role=<MessageRole.SYSTEM: 'system'>, additional_kwargs={}, blocks=[TextBlock(block_type='text', text='\n You are the GeneralAgent. Your task is to query the available knowledge resources. Make sure to leverage all available collections.\n ')]), ChatMessage(role=<MessageRole.USER: 'user'>, additional_kwargs={}, blocks=[TextBlock(block_type='text', text='What is the total revenue for Uber in 2021 ?')]), ChatMessage(role=<MessageRole.ASSISTANT: 'assistant'>, additional_kwargs={'tool_calls': [ToolCall(function=FunctionCall(name='RagAgent', arguments='{"query": "What is the total revenue for Uber in 2021 ?"}'), id='w8jKyCeKk', type=None, index=0)]}, blocks=[TextBlock(block_type='text', text='')]), ChatMessage(role=<MessageRole.TOOL: 'tool'>, additional_kwargs={'tool_call_id': 'w8jKyCeKk'}, blocks=[TextBlock(block_type='text', text='Detected nested async. Please use nest_asyncio.apply() to allow nested event loops.Or, use async entry methods like `aquery()`, `aretriever`, `achat`, etc.')]), ChatMessage(role=<MessageRole.ASSISTANT: 'assistant'>, additional_kwargs={'tool_calls': [ToolCall(function=FunctionCall(name='RagAgent', arguments='{"query": "What is the total revenue for Uber in 2021 ?"}'), id='xI20fyhbU', type=None, index=0)]}, blocks=[TextBlock(block_type='text', text='')]), ChatMessage(role=<MessageRole.TOOL: 'tool'>, additional_kwargs={'tool_call_id': 'xI20fyhbU'}, blocks=[TextBlock(block_type='text', text='Detected nested async. Please use nest_asyncio.apply() to allow nested event loops.Or, use async entry methods like `aquery()`, `aretriever`, `achat`, etc.')])]
=================<<================>
GeneralAgent: The total revenue forUberin 2021 was $17.45 billion.
The text was updated successfully, but these errors were encountered:
@logan-markewich, thank you for your response.
I created an example. I unfortunately was not able to isolate the async error, as a result the code is clode to the real issue, but also requires dependencies.
Uh oh!
There was an error while loading. Please reload this page.
Bug Description
Related: #17349
The method _aquery in the class RouterQueryEngine fires "aquery"s and later delegates the task to be run again, generating RuntimeErrors.
lines 211 to 223:
I assume the error appears when RouterQueryEngine uses more than one VectorStore or collection. This indeed is when a RuntimeError occurs on my end and in the linked issue. In my case the error is only thrown when using a front end (see below—I replaced the front end interaction with print statements).
The method run_async_tasks generates a list of coroutines, which is than executed via asyncio_run. The method asyncio_run is used to conrurrently execute the coroutines.
I suggest to rely on the newer functionalty of Task Groups¶ to run the coroutines directly in the RouterEngine.
The implementation below shows how the tasks are grouped together and executed before the
acombine_responses
generates a summary based on the results of all selected collections.I am using Python 12.9
Version
0.12.35
Steps to Reproduce
for reference, this is llamas Qdrant example
Relevant Logs/Tracbacks
See the Error Message: "Detected nested async. Please use nest_asyncio.apply() to allow nested event loops.Or, use async entry methods like
aquery()
,aretriever
,achat
, etc." in the verbose Log.The text was updated successfully, but these errors were encountered: