Replies: 1 comment 4 replies
-
Yes, it is possible to combine a query pipeline and a query engine to create a more powerful 'query tool' that can query based on another query. You can achieve this by using a multi-step query engine that iteratively refines queries based on the responses from previous queries. Here is a step-by-step approach to achieve this:
The from llama_index.core.query_engine import BaseQueryEngine, MultiStepQueryEngine
from llama_index.core.query_pipeline import QueryPipeline, StepDecomposeQueryTransform
from llama_index.core.synthesizers import BaseSynthesizer, get_response_synthesizer
from llama_index.core.types import QueryBundle, NodeWithScore, TextNode, RESPONSE_TYPE
from typing import List, Dict, Any, Optional, Callable, Tuple
class CustomMultiStepQueryEngine(MultiStepQueryEngine):
def __init__(
self,
query_engine: BaseQueryEngine,
query_transform: StepDecomposeQueryTransform,
response_synthesizer: Optional[BaseSynthesizer] = None,
num_steps: Optional[int] = 3,
early_stopping: bool = True,
index_summary: str = "None",
stop_fn: Optional[Callable[[Dict], bool]] = None,
) -> None:
super().__init__(
query_engine=query_engine,
query_transform=query_transform,
response_synthesizer=response_synthesizer,
num_steps=num_steps,
early_stopping=early_stopping,
index_summary=index_summary,
stop_fn=stop_fn,
)
def _query(self, query_bundle: QueryBundle) -> RESPONSE_TYPE:
with self.callback_manager.event(
CBEventType.QUERY, payload={EventPayload.QUERY_STR: query_bundle.query_str}
) as query_event:
nodes, source_nodes, metadata = self._query_multistep(query_bundle)
final_response = self._response_synthesizer.synthesize(
query=query_bundle,
nodes=nodes,
additional_source_nodes=source_nodes,
)
final_response.metadata = metadata
query_event.on_end(payload={EventPayload.RESPONSE: final_response})
return final_response
def _query_multistep(
self, query_bundle: QueryBundle
) -> Tuple[List[NodeWithScore], List[NodeWithScore], Dict[str, Any]]:
prev_reasoning = ""
cur_response = None
should_stop = False
cur_steps = 0
final_response_metadata: Dict[str, Any] = {"sub_qa": []}
text_chunks = []
source_nodes = []
while not should_stop:
if self._num_steps is not None and cur_steps >= self._num_steps:
should_stop = True
break
elif should_stop:
break
updated_query_bundle = self._combine_queries(query_bundle, prev_reasoning)
stop_dict = {"query_bundle": updated_query_bundle}
if self._stop_fn(stop_dict):
should_stop = True
break
cur_response = self._query_engine.query(updated_query_bundle)
cur_qa_text = (
f"\nQuestion: {updated_query_bundle.query_str}\n"
f"Answer: {cur_response!s}"
)
text_chunks.append(cur_qa_text)
for source_node in cur_response.source_nodes:
source_nodes.append(source_node)
final_response_metadata["sub_qa"].append(
(updated_query_bundle.query_str, cur_response)
)
prev_reasoning += (
f"- {updated_query_bundle.query_str}\n" f"- {cur_response!s}\n"
)
cur_steps += 1
nodes = [
NodeWithScore(node=TextNode(text=text_chunk)) for text_chunk in text_chunks
]
return nodes, source_nodes, final_response_metadata
# Initialize your query pipeline
qp = QueryPipeline(
modules={
"input": InputComponent(),
"table_retriever": obj_retriever,
"table_output_parser": table_parser_component,
"text2sql_prompt": text2sql_prompt,
"text2sql_llm": llm,
"sql_output_parser": sql_parser_component,
"sql_retriever": sql_retriever,
"response_synthesis_prompt": response_synthesis_prompt,
"response_synthesis_llm": llm,
},
verbose=True,
)
# Initialize your query engine
query_engine = SubQuestionQueryEngine.from_defaults(
query_engine_tools=query_engine_tools,
use_async=True,
verbose=True,
)
# Combine them using MultiStepQueryEngine
multi_step_query_engine = CustomMultiStepQueryEngine(
query_engine=query_engine,
query_transform=StepDecomposeQueryTransform(),
response_synthesizer=get_response_synthesizer(),
num_steps=3,
early_stopping=True,
index_summary="index summary",
)
# Use the combined query tool
query_bundle = QueryBundle(query_str="Your initial query here")
response = multi_step_query_engine.query(query_bundle)
print(response) This approach allows you to create a more powerful and context-aware querying system by combining the capabilities of both a query pipeline and a query engine [1]. |
Beta Was this translation helpful? Give feedback.
4 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
I have a query pipe line and query engine like below. Is that possible to combine and create a 'query tool' and query based on query? I like to get best by combining both if possible.
My samples query pipe line sample:
My query pipe line sample:
Beta Was this translation helpful? Give feedback.
All reactions