langchain-ai / langgraph

Build resilient language agents as graphs.
https://langchain-ai.github.io/langgraph/
MIT License
4.21k stars 630 forks source link

Storm example contains outdated check for END in stream output #358

Open csellis opened 2 months ago

csellis commented 2 months ago

Checked other resources

Example Code

from typing_extensions import TypedDict
class ResearchState(TypedDict):

    topic: str
    # outline: Outline
    # editors: List[Editor]
    # interview_results: List[InterviewState]
    # # The final sections output
    # sections: List[WikiSection]
    # article: str

import asyncio
from langgraph.graph import StateGraph, END
from IPython.display import Image

async def initialize_research(state: ResearchState):
    print("initialize_research")
    return {
        **state,
    }

async def conduct_interviews(state: ResearchState):
    print("conduct_interview")
    return {
        **state,
    }

async def refine_outline(state: ResearchState):
    print("refine_outline")
    return {
        **state,
    }

async def index_references(state: ResearchState):
    print("index_references")
    return {
        **state,
    }

async def write_sections(state: ResearchState):
    print("write_sections")
    return {
        **state,
    }

async def write_article(state: ResearchState):
    print("write_article")
    return {
        **state,
    }

builder_of_storm = StateGraph(ResearchState)

nodes = [
    ("init_research", initialize_research),
    ("conduct_interviews", conduct_interviews),
    ("refine_outline", refine_outline),
    ("index_references", index_references),
    ("write_sections", write_sections),
    ("write_article", write_article),
]
for i in range(len(nodes)):
    name, node = nodes[i]
    builder_of_storm.add_node(name, node)
    if i > 0:
        builder_of_storm.add_edge(nodes[i - 1][0], name)

builder_of_storm.set_entry_point(nodes[0][0])
builder_of_storm.set_finish_point(nodes[-1][0])
storm = builder_of_storm.compile()

Image(storm.get_graph().draw_png())

async for step in storm.astream(
    {
        "topic": "Practical processes for implementing ORPO. ORPO: Monolithic Preference Optimization without Reference Model found at https://arxiv.org/abs/2403.07691",
    }
):
    name = next(iter(step))
    print(name)
    print("-- ", str(step[name])[:300])
    if END in step:
        results = step

print(results)

Error Message and Stack Trace (if applicable)

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[9], line 92
     89     if END in step:
     90         results = step
---> 92 print(results)

NameError: name 'results' is not defined

Description

I am trying to go through the Storm tutorial and the END is not being run. I verified the conditions were satisfied and threw END up front but still couldn't catch the condition. It is processing through the graph according to LangSmith.

This proof of concept shows that although the endpoint is set in the Graph, it's not being reached when specifically set with set_finish_point

System Info

langchain==0.1.16 langchain-anthropic==0.1.11 langchain-community==0.0.34 langchain-core==0.1.46 langchain-fireworks==0.1.2 langchain-openai==0.1.4 langchain-text-splitters==0.0.1 langchainhub==0.1.15

hinthornw commented 2 months ago

Ah I think this is caused by removing the __end__ from the stream outputs by default in a recent change

SruthiDevarachetty commented 1 month ago

How do you capture the final_step in this case as end is not being streamed?

hinthornw commented 1 month ago

Do you want just the update returned in that last step?

You can just remember the last value in the loop:

last_update = None
for event in graph.stream(..., stream_mode="updates'):
    last_update = event
deanchanter commented 1 month ago

This worked for me the tutorials will need to be updated to reflect this change. Is there a way to create the end or that that no longer best practice?

Do you want just the update returned in that last step?

You can just remember the last value in the loop:

last_update = None
for event in graph.stream(..., stream_mode="updates'):
    last_update = event