Get AI summaries of any video or article — Sign up free
Parallel Workflows in LangGraph | Agentic AI using LangGraph | Video 6 | CampusX thumbnail

Parallel Workflows in LangGraph | Agentic AI using LangGraph | Video 6 | CampusX

CampusX·
5 min read

Based on CampusX's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.

TL;DR

Parallel nodes must return partial state updates (only the computed keys) rather than the entire shared state to avoid conflicting writes.

Briefing

LangGraph can run truly parallel computations—but only if each parallel node updates state in a conflict-free way. The walkthrough first builds a simple cricket analytics workflow where three metrics (strike rate, boundary percentage, and balls-to-boundary) are computed simultaneously from the same inputs, then merged into a final summary. The key implementation detail is that parallel nodes must not return the entire shared state; doing so triggers an “invalid update” conflict because LangGraph can’t reconcile simultaneous writes to the same fields. The fix is “partial state updates”: each node returns only the specific key(s) it computes (as a small dictionary), allowing the graph to merge results safely.

The cricket example starts with a typed state holding raw inputs—runs, balls, fours, and sixes—and computed outputs—strike rate, boundary percentage, balls per boundary—plus a final summary string. Four nodes are added: three calculation nodes run in parallel from the Start node, and a fourth summary node concatenates the computed metrics into a single output. When the first attempt returns the full state from each parallel node, LangGraph raises an error indicating it expected only one value update per step. After switching to partial updates (returning only the computed metric per node), the workflow executes cleanly and produces consistent outputs.

A second, more realistic parallel workflow then shifts from arithmetic to LLM-based evaluation. The goal is to grade an essay on three dimensions—clarity of thought, depth of analysis, and language quality—using separate LLM calls running in parallel. Each LLM produces two structured outputs: textual feedback and a numeric score from 0 to 10. Those three parallel results feed into a final evaluation node that merges the feedback into a summarized response and computes an overall score by averaging the three numeric values.

Reliability hinges on structured output. To ensure every LLM returns the same schema every time, the workflow uses a structured-output model (e.g., GPT 4o mini) with a Pydantic-defined schema that forces outputs into a JSON-like format containing a feedback string and an integer score constrained to 0–10. The state for this workflow stores the essay text, three feedback strings, an overall feedback string, a list of individual scores, and an averaged final score.

Because the three numeric scores are produced in parallel and must accumulate rather than overwrite, the workflow uses a reducer function (operator.add) for the “individual scores” list. This prevents the last writer from replacing earlier scores and instead appends each score into a single list. The final node then averages that list and returns both the summarized feedback and the computed average score. The example concludes by demonstrating the graph with a deliberately misspelled, low-quality essay and showing that the evaluation outputs degrade accordingly—confirming the parallel LLM pipeline and structured parsing are working end-to-end.

Cornell Notes

The workflow demonstrates how to build parallel computations in LangGraph, first with a non-LLM cricket example and then with an LLM-based essay grader. The central lesson is conflict-free parallel state updates: parallel nodes should return only partial updates (the specific keys they compute), not the entire shared state, to avoid LangGraph “invalid update” errors. For the LLM version, structured output is enforced using a Pydantic schema so each LLM call returns consistent JSON-like fields: textual feedback plus an integer score from 0 to 10. Finally, a reducer function (operator.add) merges the three parallel scores into a list so they can be averaged in the final node.

Why does returning the entire state from multiple parallel nodes cause an error in LangGraph?

In the cricket workflow, three parallel nodes each compute different metrics from the same inputs. When each node returns the full state object, LangGraph interprets that multiple nodes may be writing to the same fields simultaneously (runs, balls, fours, sixes, etc.). That creates a conflict because parallel updates aren’t coordinated field-by-field. The fix is to return partial updates: each node returns only a dictionary containing the single computed key (e.g., only strike_rate, only bp, or only balls_per_boundary).

How are the cricket metrics computed, and how do they map to parallel nodes?

The state includes runs, balls, fours, and sixes. Strike rate is computed as (runs / balls) * 100. Balls per boundary is computed as balls / (fours + sixes) because each boundary corresponds to a four or six. Boundary percentage is computed as ((fours*4 + sixes*6) / runs) * 100. Three separate nodes compute these metrics in parallel from the same input state, and a summary node merges the results into a final string.

What does “partial state update” look like in practice?

Instead of returning the whole state, each calculation node returns a small dictionary with only the field it updates. For example, the strike-rate node returns something like {"strike_rate": computed_value}. The boundary-percentage node returns {"bp": computed_value}. The balls-per-boundary node returns {"bpb": computed_value}. This allows LangGraph to merge outputs without conflicting writes.

How does the essay grading workflow ensure LLM outputs are reliable and machine-readable?

It uses structured output with a Pydantic schema (a class like EvaluationSchema) that defines two fields: feedback (string) and score (integer constrained to 0–10). The LLM is invoked via a structured-output wrapper (e.g., model.with_structured_output(schema)). That prevents cases where the model might output “seven” as text instead of the integer 7, which would break averaging and parsing.

Why is a reducer function needed for the list of individual scores?

The three aspect-evaluation nodes run in parallel and each produces one integer score. If the state field is a list and each node writes to it directly, later updates can overwrite earlier ones. Using a reducer (operator.add) makes LangGraph merge list updates by appending: the final list becomes [score_clarity, score_depth, score_language]. Then the final node averages the list length to compute the overall score.

Review Questions

  1. In the cricket example, what specific change prevents the “invalid update” error when running parallel nodes?
  2. What two fields does the structured-output schema require from each LLM call, and how is the 0–10 constraint enforced?
  3. How does operator.add function as a reducer for the individual scores list, and what would likely happen without it?

Key Points

  1. 1

    Parallel nodes must return partial state updates (only the computed keys) rather than the entire shared state to avoid conflicting writes.

  2. 2

    A simple parallel graph can compute independent metrics (strike rate, boundary percentage, balls per boundary) from the same inputs and merge them in a final summary node.

  3. 3

    For LLM-based grading, structured output with a Pydantic schema enforces consistent JSON-like fields: feedback text plus an integer score.

  4. 4

    When multiple parallel nodes contribute to the same list field, a reducer function (operator.add) is required so scores accumulate instead of overwriting.

  5. 5

    The final evaluation node can merge textual feedbacks into a summarized response and compute an overall score by averaging the accumulated individual scores.

  6. 6

    The same LangGraph design pattern scales from non-LLM parallel arithmetic to multi-LLM parallel evaluation workflows.

Highlights

LangGraph parallelism breaks when each parallel node returns the full state; partial dictionaries per node resolve the conflict cleanly.
Structured output is the difference between “sometimes parseable” and “always parseable” LLM scoring—Pydantic schema + structured model invocation makes the 0–10 score dependable.
Reducer functions (like operator.add) are essential when parallel nodes must append to the same list field rather than overwrite it.
The essay grader runs three LLM calls in parallel for clarity, depth, and language, then merges feedback and averages scores in a final node.

Topics

  • LangGraph Parallel Workflows
  • Partial State Updates
  • Structured Output with Pydantic
  • Reducer Functions
  • LLM-based Essay Evaluation

Mentioned

  • Nish
  • LLM
  • UPS C
  • JSON
  • GPT
  • GPT 4o mini