← all projects

Agentic LLM workflow suite (LangGraph)

Python · LangGraph · LangChain · Pydantic · Streamlit

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