A LlamaIndex query engine normally returns an answer after response synthesis finishes. Streaming exposes generated text fragments as they arrive, allowing a chat interface or long-running RAG request to display output before the final fragment is ready.
The high-level query engine API enables this behavior with streaming=True on index.as_query_engine(). The resulting query() call returns a StreamingResponse object whose response_gen generator can feed a terminal, web response, or application callback one fragment at a time.
The selected LLM must implement streaming or LlamaIndex raises NotImplementedError. Query engines that make several LLM calls stream only the final call, so retrieval and earlier synthesis work may still delay the first visible fragment.
Steps to stream LlamaIndex query engine responses:
- Create query_engine_streaming_check.py with an offline index and mock LLM.
- query_engine_streaming_check.py
from llama_index.core import Document, Settings, VectorStoreIndex from llama_index.core.embeddings import MockEmbedding from llama_index.core.llms import MockLLM Settings.llm = MockLLM() Settings.embed_model = MockEmbedding(embed_dim=8) documents = [ Document( text=( "Acme support answers refund questions from the policy index. " "Refund requests remain eligible for 30 days after purchase." ) ) ] index = VectorStoreIndex.from_documents(documents)
MockLLM and MockEmbedding keep the smoke test offline while exercising the same query engine interface used with a production provider.
- Append the streaming query engine configuration after the index assignment.
query_engine = index.as_query_engine( streaming=True, similarity_top_k=1, response_mode="simple_summarize", )
An application's existing response mode can remain when it supports the selected streaming LLM. Manually assembled RetrieverQueryEngine instances receive the same setting through get_response_synthesizer().
- Append the streaming response check after the query engine configuration.
streaming_response = query_engine.query("How long is the Acme refund window?") fragments = list(streaming_response.response_gen) full_response = "".join(fragments) assert type(streaming_response).__name__ == "StreamingResponse" assert len(fragments) > 1 assert "Refund requests remain eligible" in full_response print(f"response_class={type(streaming_response).__name__}") print(f"fragment_count={len(fragments)}") print(f"contains_policy_context={'Refund requests remain eligible' in full_response}")
Production handlers should forward each value directly while iterating over response_gen instead of converting the generator to a list. LLM providers may yield tokens, substrings, or individual characters.
- Run the completed smoke test to confirm the response streams multiple fragments with retrieved policy context.
$ python query_engine_streaming_check.py response_class=StreamingResponse fragment_count=323 contains_policy_context=True
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.