Agentic LLM workflow suite (LangGraph)
Why graphs instead of chains
A simple chain works fine until the workflow has to make a decision, do two things at the same time, or repeat a step until the result is good enough. LangGraph models the workflow as a state graph, so these cases are built in and you don't have to hack them together with extra code around the LLM.
I built 10+ apps using four patterns, to learn when each one is worth the extra complexity:
Prompt chaining: each step's output becomes the next step's input. This is the default. Use something more complex only if you really need it.
Parallel execution: independent tasks run at the same time and the results are combined. It is faster, and it stops one task's reasoning from affecting another.
Conditional routing: a classifier node sends the input to different branches. The customer review triage app uses this: the review's sentiment and category decide which path it takes.
Evaluator-optimizer loops: one node generates output, another node scores it, and the graph repeats until the score is good enough or a limit is reached. The essay grader and the content improvement agent both use this. It gives the best quality, but without a hard limit on loops it can run forever.
Structured output makes it reliable
Every node returns Pydantic-validated output instead of free text. This matters more than any prompt tuning. If a node has to return data that matches a schema, it either returns valid data or fails with a clear error. Parsing free text later is where these systems usually break without anyone noticing.
Memory and UI
A Streamlit chat UI streams responses in real time. LangGraph checkpointers save the memory for each chat thread, so a conversation survives a page reload and different threads never mix.
Stack
Python · LangGraph · LangChain · OpenAI GPT-4o-mini · Pydantic · Streamlit · Jupyter