Skip to content

Instantly share code, notes, and snippets.

@decagondev
Created June 30, 2025 15:26
Show Gist options
  • Save decagondev/a34342b1b59920a2812c664f19566640 to your computer and use it in GitHub Desktop.
Save decagondev/a34342b1b59920a2812c664f19566640 to your computer and use it in GitHub Desktop.

Example of a Useful Application Requiring LangGraph

LangGraph, as a library within the LangChain ecosystem, is designed for building complex, stateful applications with large language models (LLMs) and multi-agent systems, as outlined in the class materials (README, slides, and code). Its strengths in managing state, coordinating multiple agents, and handling dynamic workflows make it ideal for applications that require iterative, collaborative, or context-aware processes. Below is an example of a useful application that would benefit from LangGraph’s capabilities, tailored to the class’s focus on multi-agent graphs, state management, and supervisor orchestration.

Example Application: Automated Research Report Generator

Description

An Automated Research Report Generator is a tool that conducts research on a given topic, generates a draft report, gathers feedback from multiple agents (e.g., for accuracy, clarity, or depth), and iteratively refines the report until it meets predefined quality criteria. This aligns with the class’s hands-on objective: “Code an AI graph that writes a report, provides feedback, and rewrites the report n number of times.”

Why LangGraph is Necessary

This application requires coordinating multiple components (LLMs, external tools, and feedback loops) with persistent state and dynamic decision-making, which LangGraph is uniquely suited to handle. Here’s how LangGraph’s features (from the slides and README) map to the application’s requirements:

  1. Multi-Agent Collaboration:

    • Requirement: The tool needs multiple agents: one to research and draft the report, another to fact-check, a third to improve clarity and style, and a supervisor to decide when to iterate or finalize.
    • LangGraph Solution: LangGraph’s multi-agent graph and supervisor concept (slides) enable orchestration of these agents. For example, a supervisor node can route the workflow based on the state (e.g., “needs more research” or “ready for finalization”).
    • Implementation: Nodes for each agent (e.g., research_node, fact_check_node, style_node) and a supervisor node to evaluate the report’s state and decide the next step (e.g., loop back for revisions or proceed to END).
  2. State Management:

    • Requirement: The tool must track the report’s content, feedback, and revision history across iterations, ensuring context is preserved (e.g., previous drafts, sources used).
    • LangGraph Solution: LangGraph’s state dictionary (slides: “State is a dictionary of relative information… updated as the graph is executed”) persists and updates data across nodes. For example, the state can store the current report draft, feedback comments, and source references.
    • Implementation: A MessageGraph (as in the class code) or custom state schema to hold the report text, metadata (e.g., iteration count), and external data (e.g., Tavily search results).
  3. Integration with External Tools:

    • Requirement: Research involves fetching data from external sources (e.g., web searches for up-to-date information), which must be integrated into the report.
    • LangGraph Solution: LangGraph supports integration with tools like the Tavily API (README: “You’ll need a free Tavily API key”). A node can call Tavily to gather research data, and the results are stored in the state for use by other nodes.
    • Implementation: A research_node that uses the Tavily API to fetch relevant articles or data, passing results to the state for the drafting node to process.
  4. Dynamic Workflow with Conditional Edges:

    • Requirement: The tool must dynamically decide whether to revise the report (based on feedback quality) or finalize it, potentially iterating multiple times.
    • LangGraph Solution: LangGraph’s conditional edges (slides: “Edges can be… conditional”) allow the supervisor node to route execution based on state criteria (e.g., feedback score, iteration limit).
    • Implementation: Conditional edges from the supervisor node to either a revision node (e.g., rewrite_node) or END, based on a quality threshold or maximum iterations (e.g., n times, as per the class objective).
  5. Iterative Processing:

    • Requirement: The tool must support iterative refinement, where the report is rewritten based on feedback until it meets standards.
    • LangGraph Solution: LangGraph’s graph structure supports loops and iterative workflows, as emphasized in the class objective. The state tracks changes across iterations, enabling continuous improvement.
    • Implementation: A loop in the graph where the feedback_node evaluates the draft, updates the state with comments, and routes back to the rewrite_node until the supervisor deems the report complete.

Example Workflow in LangGraph

Based on the class code (simple_message_graph.py) and slides, here’s how the application could be structured:

  • Nodes:

    • research_node: Calls the Tavily API to gather data on the topic (non-LLM function, as nodes can be non-LLM per previous discussion).
    • draft_node: Uses an LLM (e.g., ChatOpenAI) to write the initial report based on research data.
    • fact_check_node: Uses an LLM to verify factual accuracy, cross-referencing with sources.
    • style_node: Uses an LLM to improve clarity, coherence, and style.
    • supervisor_node: Evaluates the report and feedback, deciding whether to revise or finalize.
  • Edges:

    • Static edges: research_nodedraft_nodefact_check_nodestyle_nodesupervisor_node.
    • Conditional edges: From supervisor_node to either rewrite_node (for revisions) or END (if complete).
  • State:

    • A dictionary storing the current report draft, research data, feedback comments, iteration count, and quality scores.
  • Code Snippet (inspired by the class’s MessageGraph example):

from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
from langgraph.graph import StateGraph, END
from dotenv import load_dotenv
import os

load_dotenv()
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")
os.environ["TAVILY_API_KEY"] = os.getenv("TAVILY_API_KEY")

model = ChatOpenAI(temperature=0, model="gpt-4o-mini")

# Define state schema
class ResearchState:
    def __init__(self):
        self.report = ""
        self.research_data = []
        self.feedback = []
        self.iteration = 0
        self.max_iterations = 3

# Define nodes
def research_node(state):
    # Call Tavily API to fetch data
    # Update state.research_data
    return state

def draft_node(state):
    # Use LLM to write report based on state.research_data
    state.report = model.invoke(f"Write a report based on: {state.research_data}").content
    return state

def fact_check_node(state):
    # Use LLM to verify facts
    state.feedback.append(model.invoke(f"Check facts in: {state.report}").content)
    return state

def style_node(state):
    # Use LLM to improve style
    state.report = model.invoke(f"Improve clarity of: {state.report}").content
    return state

def supervisor_node(state):
    # Evaluate feedback and decide next step
    state.iteration += 1
    if state.iteration < state.max_iterations and "issues" in state.feedback[-1]:
        return "rewrite"
    return END

def rewrite_node(state):
    # Rewrite report based on feedback
    state.report = model.invoke(f"Rewrite report: {state.report} with feedback: {state.feedback}").content
    state.feedback = []  # Clear feedback for next iteration
    return state

# Build graph
graph = StateGraph(ResearchState)
graph.add_node("research", research_node)
graph.add_node("draft", draft_node)
graph.add_node("fact_check", fact_check_node)
graph.add_node("style", style_node)
graph.add_node("supervisor", supervisor_node)
graph.add_node("rewrite", rewrite_node)

# Define edges
graph.add_edge("research", "draft")
graph.add_edge("draft", "fact_check")
graph.add_edge("fact_check", "style")
graph.add_edge("style", "supervisor")
graph.add_conditional_edges("supervisor", supervisor_node, {"rewrite": "rewrite", END: END})
graph.add_edge("rewrite", "fact_check")

graph.set_entry_point("research")
runnable = graph.compile()

# Run the graph
state = ResearchState()
state.research_data = ["User input: Research AI ethics"]
result = runnable.invoke(state)
print(result.report)

Why Not Alternatives?

  • Pytransitions + Custom Agent Handling (as discussed previously):
    • Pytransitions could manage states (e.g., “researching”, “drafting”, “reviewing”), but you’d need to manually implement LLM calls, Tavily API integration, and agent coordination, requiring significant boilerplate.
    • State management would be less flexible for rich AI contexts (e.g., message histories, research data).
  • Custom Code Without a Framework:
    • Building from scratch offers full control but is time-intensive for coordinating LLMs, tools, and iterations, especially for dynamic workflows.
    • LangGraph’s graph structure simplifies dependency management and debugging (slides: “Easier to manage dependencies”).
  • LangChain Chains or Agents:
    • Chains are too rigid for iterative, multi-agent workflows (slides: “Limited to predefined flow”).
    • Agents offer dynamic decision-making but lack the structured control of graphs (slides: “Higher complexity and less control”).

Alignment with Class Materials

  • Multi-Agent Graphs: The application mirrors the class’s focus on multi-agent collaboration (slides: “Multi-agent graph concept”).
  • Supervisor Concept: The supervisor_node aligns with the supervisor orchestrating the workflow (slides: “The supervisor concept”).
  • State and Iteration: The state dictionary and iterative rewriting match the class objective and the slides’ emphasis on state persistence.
  • Tool Integration: Using the Tavily API (README) for research is directly supported by LangGraph’s ecosystem.

Conclusion

The Automated Research Report Generator is a practical example where LangGraph’s strengths—multi-agent coordination, state management, tool integration, and dynamic workflows—shine. It leverages LangGraph’s graph structure to manage complex, iterative AI tasks, making it more efficient than alternatives like pytransitions or custom code for this use case. Other applications with similar needs (e.g., customer support chatbots, automated content editors, or AI-driven decision systems) would also benefit from LangGraph’s capabilities.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment