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
-
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