-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug]: draw_all_possible_flow returns a blank html #15935
Comments
To fix the issue of # Add nodes from all steps
steps = get_steps_from_class(workflow)
if not steps:
# If no steps are defined in the class, try to get them from the instance
steps = get_steps_from_instance(workflow) If Here is a minimal example to ensure your workflow has steps: from llama_index.core.workflow import Workflow
from llama_index.core.decorators import step
class MyWorkflow(Workflow):
@step
def step1(self):
pass
@step
def step2(self):
pass
workflow = MyWorkflow()
draw_all_possible_flows(workflow) Ensure that your workflow class or instance has steps decorated with Additionally, the from pyvis.network import Network
def draw_all_possible_flows(
workflow: Workflow,
filename: str = "workflow_all_flows.html",
notebook: bool = False,
) -> None:
net = Network(directed=True, height="750px", width="100%")
# Add the nodes + edge for stop events
net.add_node(
StopEvent.__name__,
label=StopEvent.__name__,
color="#FFA07A",
shape="ellipse",
)
net.add_node("_done", label="_done", color="#ADD8E6", shape="box")
net.add_edge(StopEvent.__name__, "_done")
# Add nodes from all steps
steps = get_steps_from_class(workflow)
if not steps:
steps = get_steps_from_instance(workflow)
for step_name, step_func in steps.items():
step_config = getattr(step_func, "__step_config", None)
if step_config is None:
continue
net.add_node(
step_name, label=step_name, color="#ADD8E6", shape="box"
)
for event_type in step_config.accepted_events:
net.add_node(
event_type.__name__,
label=event_type.__name__,
color="#90EE90" if event_type != StartEvent else "#E27AFF",
shape="ellipse",
)
# Add edges from all steps
for step_name, step_func in steps.items():
step_config = getattr(step_func, "__step_config", None)
if step_config is None:
continue
for return_type in step_config.return_types:
if return_type != type(None):
net.add_edge(step_name, return_type.__name__)
for event_type in step_config.accepted_events:
net.add_edge(event_type.__name__, step_name)
net.show(filename, notebook=notebook) By ensuring that your workflow has steps defined and that |
I have declared the steps in the workflow
Also could you mention the package from which i can import get_steps_from_class
|
To fix the Here is the corrected code: from llama_index.core.workflow.utils import get_steps_from_class, get_steps_from_instance
from llama_index.core.workflow.events import StartEvent, StopEvent
from llama_index.core.workflow.decorators import StepConfig
from llama_index.core.workflow.workflow import Workflow
def draw_all_possible_flows(
workflow: Workflow,
filename: str = "workflow_all_flows.html",
notebook: bool = False,
) -> None:
"""Draws all possible flows of the workflow."""
from pyvis.network import Network
net = Network(directed=True, height="750px", width="100%")
# Add the nodes + edge for stop events
net.add_node(
StopEvent.__name__,
label=StopEvent.__name__,
color="#FFA07A",
shape="ellipse",
)
net.add_node("_done", label="_done", color="#ADD8E6", shape="box")
net.add_edge(StopEvent.__name__, "_done")
# Add nodes from all steps
steps = get_steps_from_class(workflow)
if not steps:
# If no steps are defined in the class, try to get them from the instance
steps = get_steps_from_instance(workflow)
step_config: Optional[StepConfig] = None
for step_name, step_func in steps.items():
step_config = getattr(step_func, "__step_config", None)
if step_config is None:
continue
net.add_node(
step_name, label=step_name, color="#ADD8E6", shape="box"
) # Light blue for steps
for event_type in step_config.accepted_events:
net.add_node(
event_type.__name__,
label=event_type.__name__,
color="#90EE90" if event_type != StartEvent else "#E27AFF",
shape="ellipse",
) # Light green for events
# Add edges from all steps
for step_name, step_func in steps.items():
step_config = getattr(step_func, "__step_config", None)
if step_config is None:
continue
for return_type in step_config.return_types:
if return_type != type(None):
net.add_edge(step_name, return_type.__name__)
for event_type in step_config.accepted_events:
net.add_edge(event_type.__name__, step_name)
net.show(filename, notebook=notebook) Make sure to install the pip install llama-index-utils-workflow This should resolve the |
The response i get from RAGWORKFLOW is as follows. So I do not understand how the steps will not be defined.Please help me understand
|
To resolve the issue of Here is the relevant part of the code that checks for steps = get_steps_from_class(workflow)
if not steps:
steps = get_steps_from_instance(workflow)
step_config: Optional[StepConfig] = None
for step_name, step_func in steps.items():
step_config = getattr(step_func, "__step_config", None)
if step_config is None:
continue
net.add_node(
step_name, label=step_name, color="#ADD8E6", shape="box"
) # Light blue for steps
for event_type in step_config.accepted_events:
net.add_node(
event_type.__name__,
label=event_type.__name__,
color="#90EE90" if event_type != StartEvent else "#E27AFF",
shape="ellipse",
) # Light green for events
# Add edges from all steps
for step_name, step_func in steps.items():
step_config = getattr(step_func, "__step_config", None)
if step_config is None:
continue
for return_type in step_config.return_types:
if return_type != type(None):
net.add_edge(step_name, return_type.__name__)
for event_type in step_config.accepted_events:
net.add_edge(event_type.__name__, step_name) Make sure that each step function in your workflow has the If the steps are correctly defined and the issue persists, consider using the updated import as suggested by the deprecation warning: from llama_index.utils.workflow import draw_all_possible_flows This might resolve any underlying issues related to the deprecated function. Additionally, ensure that the |
@dosu
|
Your
Here is your updated code with the necessary imports and a check for the from llama_index.core import SimpleDirectoryReader, VectorStoreIndex
from llama_index.core.response_synthesizers import CompactAndRefine
from llama_index.core.postprocessor.llm_rerank import LLMRerank
from llama_index.core.workflow import (
Context,
Workflow,
StartEvent,
StopEvent,
step,
)
from llama_index.core.workflow.utils import get_steps_from_class, get_steps_from_instance
from llama_index.llms.groq import Groq
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
class RetrieverEvent(Event):
"""Result of running retrieval"""
nodes: list[NodeWithScore]
class RerankEvent(Event):
"""Result of running reranking on retrieved nodes"""
nodes: list[NodeWithScore]
class RAGWorkflow(Workflow):
@step
async def ingest(self, ctx: Context, ev: StartEvent) -> StopEvent | None:
"""Entry point to ingest a document, triggered by a StartEvent with `dirname`."""
dirname = ev.get("dirname")
if not dirname:
return None
documents = SimpleDirectoryReader(dirname).load_data()
index = VectorStoreIndex.from_documents(
documents=documents,
embed_model=HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5"),
)
return StopEvent(result=index)
@step
async def retrieve(
self, ctx: Context, ev: StartEvent
) -> RetrieverEvent | None:
"Entry point for RAG, triggered by a StartEvent with `query`."
query = ev.get("query")
index = ev.get("index")
if not query:
return None
print(f"Query the database with: {query}")
# store the query in the global context
await ctx.set("query", query)
# get the index from the global context
if index is None:
print("Index is empty, load some documents before querying!")
return None
retriever = index.as_retriever(similarity_top_k=2)
nodes = await retriever.aretrieve(query)
print(f"Retrieved {len(nodes)} nodes.")
return RetrieverEvent(nodes=nodes)
@step
async def rerank(self, ctx: Context, ev: RetrieverEvent) -> RerankEvent:
# Rerank the nodes
ranker = LLMRerank(
choice_batch_size=5, top_n=3, llm=Groq(model="llama-3.1-70b-versatile")
)
print(await ctx.get("query", default=None), flush=True)
new_nodes = ranker.postprocess_nodes(
ev.nodes, query_str=await ctx.get("query", default=None)
)
print(f"Reranked nodes to {len(new_nodes)}")
print(new_nodes)
return RerankEvent(nodes=new_nodes)
@step
async def synthesize(self, ctx: Context, ev: RerankEvent) -> StopEvent:
"""Return a streaming response using reranked nodes."""
llm = Groq(model="llama-3.1-70b-versatile")
summarizer = CompactAndRefine(llm=llm, streaming=True, verbose=True)
query = await ctx.get("query", default=None)
response = await summarizer.asynthesize(query, nodes=ev.nodes)
return StopEvent(result=response)
# Check if steps have __step_config attribute
workflow = RAGWorkflow()
steps = get_steps_from_class(RAGWorkflow)
if not steps:
steps = get_steps_from_instance(workflow)
for step_name, step_func in steps.items():
step_config = getattr(step_func, "__step_config", None)
if step_config is None:
print(f"Step {step_name} is missing __step_config")
# Visualization
from llama_index.utils.workflow import draw_all_possible_flows, draw_most_recent_execution
# Draw all possible flows
draw_all_possible_flows(RAGWorkflow, filename="multi_step_workflow.html")
# Draw the most recent execution
w = RAGWorkflow()
# Ingest the documents
index = await w.run(dirname="Data")
result = await w.run(query="What is Fibromyalgia?", index=index)
async for chunk in result.async_response_gen():
print(chunk, end="", flush=True)
draw_most_recent_execution(w, filename="rag_flow_recent.html") Ensure you have the |
@dosu
Please help me. |
Given that your workflow steps are correctly defined and the Here are a few steps to troubleshoot and resolve the issue:
By following these steps, you should be able to identify and resolve the issue with visualizing the workflow in Google Colab. If the problem persists, consider running the code in a local environment to see if the issue is specific to Colab. |
1. pyvis has been installed in colab2. Check HTML File Content:
3. Node and Edge Data:
4. Render HTML in Colab: gives an empty display |
To fix the issue of Here is the relevant part of the code with the def draw_all_possible_flows(
workflow: Workflow,
filename: str = "workflow_all_flows.html",
notebook: bool = True, # Set notebook to True
) -> None:
"""Draws all possible flows of the workflow."""
from pyvis.network import Network
net = Network(directed=True, height="750px", width="100%")
# Add the nodes + edge for stop events
net.add_node(
StopEvent.__name__,
label=StopEvent.__name__,
color="#FFA07A",
shape="ellipse",
)
net.add_node("_done", label="_done", color="#ADD8E6", shape="box")
net.add_edge(StopEvent.__name__, "_done")
# Add nodes from all steps
steps = get_steps_from_class(workflow)
if not steps:
# If no steps are defined in the class, try to get them from the instance
steps = get_steps_from_instance(workflow)
step_config: Optional[StepConfig] = None
for step_name, step_func in steps.items():
step_config = getattr(step_func, "__step_config", None)
if step_config is None:
continue
net.add_node(
step_name, label=step_name, color="#ADD8E6", shape="box"
) # Light blue for steps
for event_type in step_config.accepted_events:
net.add_node(
event_type.__name__,
label=event_type.__name__,
color="#90EE90" if event_type != StartEvent else "#E27AFF",
shape="ellipse",
) # Light green for events
# Add edges from all steps
for step_name, step_func in steps.items():
step_config = getattr(step_func, "__step_config", None)
if step_config is None:
continue
for return_type in step_config.return_types:
if return_type != type(None):
net.add_edge(step_name, return_type.__name__)
for event_type in step_config.accepted_events:
net.add_edge(event_type.__name__, step_name)
net.show(filename, notebook=notebook) By setting |
@dosu
Please advise |
To resolve the Here is an example of how you can modify your code to work in Google Colab: from pyvis.network import Network
from IPython.core.display import display, HTML
def draw_all_possible_flows(
workflow: Workflow,
filename: str = "workflow_all_flows.html",
notebook: bool = True, # Set notebook to True
) -> None:
"""Draws all possible flows of the workflow."""
net = Network(directed=True, height="750px", width="100%")
# Add the nodes + edge for stop events
net.add_node(
StopEvent.__name__,
label=StopEvent.__name__,
color="#FFA07A",
shape="ellipse",
)
net.add_node("_done", label="_done", color="#ADD8E6", shape="box")
net.add_edge(StopEvent.__name__, "_done")
# Add nodes from all steps
steps = get_steps_from_class(workflow)
if not steps:
# If no steps are defined in the class, try to get them from the instance
steps = get_steps_from_instance(workflow)
step_config: Optional[StepConfig] = None
for step_name, step_func in steps.items():
step_config = getattr(step_func, "__step_config", None)
if step_config is None:
continue
net.add_node(
step_name, label=step_name, color="#ADD8E6", shape="box"
) # Light blue for steps
for event_type in step_config.accepted_events:
net.add_node(
event_type.__name__,
label=event_type.__name__,
color="#90EE90" if event_type != StartEvent else "#E27AFF",
shape="ellipse",
) # Light green for events
# Add edges from all steps
for step_name, step_func in steps.items():
step_config = getattr(step_func, "__step_config", None)
if step_config is None:
continue
for return_type in step_config.return_types:
if return_type != type(None):
net.add_edge(step_name, return_type.__name__)
for event_type in step_config.accepted_events:
net.add_edge(event_type.__name__, step_name)
if notebook:
net.show(filename, notebook=True)
with open(filename, "r") as file:
display(HTML(file.read()))
else:
net.show(filename)
# Example usage in Google Colab
draw_all_possible_flows(
RAGWorkflow, filename="multi_step_workflow.html", notebook=True
) This code ensures that the visualization is properly rendered within the Google Colab notebook by using the !pip install pyvis llama-index-core llama-index-llms-openai llama-index-embeddings-openai llama-index-readers-file llama-index-utils-workflow By following these steps, you should be able to visualize the |
did as instructructed but still encounter
|
To resolve the Here is an example of how you can modify your code to work in Google Colab: from pyvis.network import Network
from IPython.core.display import display, HTML
def draw_all_possible_flows(
workflow: Workflow,
filename: str = "workflow_all_flows.html",
notebook: bool = True, # Set notebook to True
) -> None:
"""Draws all possible flows of the workflow."""
net = Network(directed=True, height="750px", width="100%")
# Add the nodes + edge for stop events
net.add_node(
StopEvent.__name__,
label=StopEvent.__name__,
color="#FFA07A",
shape="ellipse",
)
net.add_node("_done", label="_done", color="#ADD8E6", shape="box")
net.add_edge(StopEvent.__name__, "_done")
# Add nodes from all steps
steps = get_steps_from_class(workflow)
if not steps:
# If no steps are defined in the class, try to get them from the instance
steps = get_steps_from_instance(workflow)
step_config: Optional[StepConfig] = None
for step_name, step_func in steps.items():
step_config = getattr(step_func, "__step_config", None)
if step_config is None:
continue
net.add_node(
step_name, label=step_name, color="#ADD8E6", shape="box"
) # Light blue for steps
for event_type in step_config.accepted_events:
net.add_node(
event_type.__name__,
label=event_type.__name__,
color="#90EE90" if event_type != StartEvent else "#E27AFF",
shape="ellipse",
) # Light green for events
# Add edges from all steps
for step_name, step_func in steps.items():
step_config = getattr(step_func, "__step_config", None)
if step_config is None:
continue
for return_type in step_config.return_types:
if return_type != type(None):
net.add_edge(step_name, return_type.__name__)
for event_type in step_config.accepted_events:
net.add_edge(event_type.__name__, step_name)
if notebook:
net.show(filename, notebook=True)
with open(filename, "r") as file:
display(HTML(file.read()))
else:
net.show(filename)
# Example usage in Google Colab
draw_all_possible_flows(
RAGWorkflow, filename="multi_step_workflow.html", notebook=True
) This code ensures that the visualization is properly rendered within the Google Colab notebook by using the !pip install pyvis llama-index-core llama-index-llms-openai llama-index-embeddings-openai llama-index-readers-file llama-index-utils-workflow By following these steps, you should be able to visualize the |
I am now trying it in my local environment and I have python3.9.12. I encounter below error : How to resolve
|
The error Here is the corrected code for the from typing import Union
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex
from llama_index.core.response_synthesizers import CompactAndRefine
from llama_index.core.postprocessor.llm_rerank import LLMRerank
from llama_index.core.workflow import (
Context,
Workflow,
StartEvent,
StopEvent,
step,
)
from llama_index.llms.groq import Groq
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
class RetrieverEvent(Event):
"""Result of running retrieval"""
nodes: list[NodeWithScore]
class RerankEvent(Event):
"""Result of running reranking on retrieved nodes"""
nodes: list[NodeWithScore]
class RAGWorkflow(Workflow):
@step
async def ingest(self, ctx: Context, ev: StartEvent) -> Union[StopEvent, None]:
"""Entry point to ingest a document, triggered by a StartEvent with `dirname`."""
dirname = ev.get("dirname")
if not dirname:
return None
documents = SimpleDirectoryReader(dirname).load_data()
index = VectorStoreIndex.from_documents(
documents=documents,
embed_model=HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5"),
)
return StopEvent(result=index)
@step
async def retrieve(
self, ctx: Context, ev: StartEvent
) -> Union[RetrieverEvent, None]:
"Entry point for RAG, triggered by a StartEvent with `query`."
query = ev.get("query")
index = ev.get("index")
if not query:
return None
print(f"Query the database with: {query}")
# store the query in the global context
await ctx.set("query", query)
# get the index from the global context
if index is None:
print("Index is empty, load some documents before querying!")
return None
retriever = index.as_retriever(similarity_top_k=2)
nodes = await retriever.aretrieve(query)
print(f"Retrieved {len(nodes)} nodes.")
return RetrieverEvent(nodes=nodes)
@step
async def rerank(self, ctx: Context, ev: RetrieverEvent) -> RerankEvent:
# Rerank the nodes
ranker = LLMRerank(
choice_batch_size=5, top_n=3, llm=Groq(model="llama-3.1-70b-versatile")
)
print(await ctx.get("query", default=None), flush=True)
new_nodes = ranker.postprocess_nodes(
ev.nodes, query_str=await ctx.get("query", default=None)
)
print(f"Reranked nodes to {len(new_nodes)}")
return RerankEvent(nodes=new_nodes)
@step
async def synthesize(self, ctx: Context, ev: RerankEvent) -> StopEvent:
"""Return a streaming response using reranked nodes."""
llm = Groq(model="llama-3.1-70b-versatile")
summarizer = CompactAndRefine(llm=llm, streaming=True, verbose=True)
query = await ctx.get("query", default=None)
response = await summarizer.asynthesize(query, nodes=ev.nodes)
return StopEvent(result=response) By replacing the |
I now encounter the below eror:
|
The Here is the corrected code for your
Here is the complete code: from typing import Union, List
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex
from llama_index.core.response_synthesizers import CompactAndRefine
from llama_index.core.postprocessor.llm_rerank import LLMRerank
from llama_index.core.workflow import (
Context,
Workflow,
StartEvent,
StopEvent,
step,
Event,
)
from llama_index.core.schema import NodeWithScore, QueryType
from llama_index.llms.groq import Groq
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
class RetrieverEvent(Event):
"""Result of running retrieval"""
str_or_query_bundle: QueryType
nodes: List[NodeWithScore]
@classmethod
def class_name(cls) -> str:
"""Class name."""
return "RetrieverEvent"
class RerankEvent(Event):
"""Result of running reranking on retrieved nodes"""
str_or_query_bundle: QueryType
nodes: List[NodeWithScore]
@classmethod
def class_name(cls) -> str:
"""Class name."""
return "RerankEvent"
class RAGWorkflow(Workflow):
@step
async def ingest(self, ctx: Context, ev: StartEvent) -> Union[StopEvent, None]:
"""Entry point to ingest a document, triggered by a StartEvent with `dirname`."""
dirname = ev.get("dirname")
if not dirname:
return None
documents = SimpleDirectoryReader(dirname).load_data()
index = VectorStoreIndex.from_documents(
documents=documents,
embed_model=HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5"),
)
return StopEvent(result=index)
@step
async def retrieve(
self, ctx: Context, ev: StartEvent
) -> Union[RetrieverEvent, None]:
"Entry point for RAG, triggered by a StartEvent with `query`."
query = ev.get("query")
index = ev.get("index")
if not query:
return None
print(f"Query the database with: {query}")
# store the query in the global context
await ctx.set("query", query)
# get the index from the global context
if index is None:
print("Index is empty, load some documents before querying!")
return None
retriever = index.as_retriever(similarity_top_k=2)
nodes = await retriever.aretrieve(query)
print(f"Retrieved {len(nodes)} nodes.")
return RetrieverEvent(nodes=nodes)
@step
async def rerank(self, ctx: Context, ev: RetrieverEvent) -> RerankEvent:
# Rerank the nodes
ranker = LLMRerank(
choice_batch_size=5, top_n=3, llm=Groq(model="llama-3.1-70b-versatile")
)
print(await ctx.get("query", default=None), flush=True)
new_nodes = ranker.postprocess_nodes(
ev.nodes, query_str=await ctx.get("query", default=None)
)
print(f"Reranked nodes to {len(new_nodes)}")
return RerankEvent(nodes=new_nodes)
@step
async def synthesize(self, ctx: Context, ev: RerankEvent) -> StopEvent:
"""Return a streaming response using reranked nodes."""
llm = Groq(model="llama-3.1-70b-versatile")
summarizer = CompactAndRefine(llm=llm, streaming=True, verbose=True)
query = await ctx.get("query", default=None)
response = await summarizer.asynthesize(query, nodes=ev.nodes)
return StopEvent(result=response) This should resolve the |
@dosu
|
The Here is the corrected code for your
Here is the complete code: from typing import Union, List
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex
from llama_index.core.response_synthesizers import CompactAndRefine
from llama_index.core.postprocessor.llm_rerank import LLMRerank
from llama_index.core.workflow import (
Context,
Workflow,
StartEvent,
StopEvent,
step,
Event,
)
from llama_index.core.schema import NodeWithScore, QueryType
from llama_index.llms.groq import Groq
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
class RetrieverEvent(Event):
"""Result of running retrieval"""
nodes: List[NodeWithScore]
class RerankEvent(Event):
"""Result of running reranking on retrieved nodes"""
nodes: List[NodeWithScore]
class RAGWorkflow(Workflow):
@step
async def ingest(self, ctx: Context, ev: StartEvent) -> Union[StopEvent, None]:
"""Entry point to ingest a document, triggered by a StartEvent with `dirname`."""
dirname = ev.get("dirname")
if not dirname:
return None
documents = SimpleDirectoryReader(dirname).load_data()
index = VectorStoreIndex.from_documents(
documents=documents,
embed_model=HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5"),
)
return StopEvent(result=index)
@step
async def retrieve(
self, ctx: Context, ev: StartEvent
) -> Union[RetrieverEvent, None]:
"Entry point for RAG, triggered by a StartEvent with `query`."
query = ev.get("query")
index = ev.get("index")
if not query:
return None
print(f"Query the database with: {query}")
# store the query in the global context
await ctx.set("query", query)
# get the index from the global context
if index is None:
print("Index is empty, load some documents before querying!")
return None
retriever = index.as_retriever(similarity_top_k=2)
nodes = await retriever.aretrieve(query)
print(f"Retrieved {len(nodes)} nodes.")
return RetrieverEvent(nodes=nodes)
@step
async def rerank(self, ctx: Context, ev: RetrieverEvent) -> RerankEvent:
# Rerank the nodes
ranker = LLMRerank(
choice_batch_size=5, top_n=3, llm=Groq(model="llama-3.1-70b-versatile")
)
print(await ctx.get("query", default=None), flush=True)
new_nodes = ranker.postprocess_nodes(
ev.nodes, query_str=await ctx.get("query", default=None)
)
print(f"Reranked nodes to {len(new_nodes)}")
return RerankEvent(nodes=new_nodes)
@step
async def synthesize(self, ctx: Context, ev: RerankEvent) -> StopEvent:
"""Return a streaming response using reranked nodes."""
llm = Groq(model="llama-3.1-70b-versatile")
summarizer = CompactAndRefine(llm=llm, streaming=True, verbose=True)
query = await ctx.get("query", default=None)
response = await summarizer.asynthesize(query, nodes=ev.nodes)
return StopEvent(result=response) This should resolve the |
I still encounter : return StopEvent(result=response)
|
The Here is the corrected code for your
Here is the complete code: from typing import Union, List
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex
from llama_index.core.response_synthesizers import CompactAndRefine
from llama_index.core.postprocessor.llm_rerank import LLMRerank
from llama_index.core.workflow import (
Context,
Workflow,
StartEvent,
StopEvent,
step,
Event,
)
from llama_index.core.schema import NodeWithScore
from llama_index.llms.groq import Groq
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
class RetrieverEvent(Event):
"""Result of running retrieval"""
nodes: List[NodeWithScore]
class RerankEvent(Event):
"""Result of running reranking on retrieved nodes"""
nodes: List[NodeWithScore]
class RAGWorkflow(Workflow):
@step
async def ingest(self, ctx: Context, ev: StartEvent) -> Union[StopEvent, None]:
"""Entry point to ingest a document, triggered by a StartEvent with `dirname`."""
dirname = ev.get("dirname")
if not dirname:
return None
documents = SimpleDirectoryReader(dirname).load_data()
index = VectorStoreIndex.from_documents(
documents=documents,
embed_model=HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5"),
)
return StopEvent(result=index)
@step
async def retrieve(
self, ctx: Context, ev: StartEvent
) -> Union[RetrieverEvent, None]:
"Entry point for RAG, triggered by a StartEvent with `query`."
query = ev.get("query")
index = ev.get("index")
if not query:
return None
print(f"Query the database with: {query}")
# store the query in the global context
await ctx.set("query", query)
# get the index from the global context
if index is None:
print("Index is empty, load some documents before querying!")
return None
retriever = index.as_retriever(similarity_top_k=2)
nodes = await retriever.aretrieve(query)
print(f"Retrieved {len(nodes)} nodes.")
return RetrieverEvent(nodes=nodes)
@step
async def rerank(self, ctx: Context, ev: RetrieverEvent) -> RerankEvent:
# Rerank the nodes
ranker = LLMRerank(
choice_batch_size=5, top_n=3, llm=Groq(model="llama-3.1-70b-versatile")
)
print(await ctx.get("query", default=None), flush=True)
new_nodes = ranker.postprocess_nodes(
ev.nodes, query_str=await ctx.get("query", default=None)
)
print(f"Reranked nodes to {len(new_nodes)}")
return RerankEvent(nodes=new_nodes)
@step
async def synthesize(self, ctx: Context, ev: RerankEvent) -> StopEvent:
"""Return a streaming response using reranked nodes."""
llm = Groq(model="llama-3.1-70b-versatile")
summarizer = CompactAndRefine(llm=llm, streaming=True, verbose=True)
query = await ctx.get("query", default=None)
response = await summarizer.asynthesize(query, nodes=ev.nodes)
return StopEvent(result=response) This should resolve the |
@dosu,
|
Here are my Observations :1. I had installed python 3.11.0 locally and then installed the required llama_index packages. I was able to run the workflow locally and the visualization also happened successfully.2. In Python 3.9.12 I ahd to make the following changes to make the workflow run successfully and visualize the workflow.
3. The Visualiztion is simply not working in Colab even with notebook = True parameter.Could you please have a look at the above observations and advise |
Your observations highlight a few key points regarding compatibility and functionality across different Python versions and environments. Here are some detailed insights and recommendations based on your observations: 1. Python 3.11.0 Compatibility
2. Python 3.9.12 Compatibility
3. Visualization in Google Colab
Summary
By following these recommendations, you should be able to achieve consistent functionality across different environments and Python versions. |
Bug Description
I am trying out the example specified in https://docs.llamaindex.ai/en/stable/examples/workflow/rag/ page.
Please find my code below
Balnk html is returned
import IPython
IPython.display.HTML(filename='/content/rag_flow_recent.html')
Content of HTML file
Please help me with some directives to visualize the workflow
Version
llama_index.core==0.11.8
Steps to Reproduce
draw_all_possible_flows(RAGWorkflow, filename="multi_step_workflow.html")
Relevant Logs/Tracbacks
No response
The text was updated successfully, but these errors were encountered: