Expert in LangGraph - the production-grade framework for building stateful, multi-actor AI applications. Covers graph construction, state management, cycles and branches, persistence with checkpointers, human-in-the-loop patterns, and the ReAct agent pattern. Used in production at LinkedIn, Uber, and 400+ companies. This is LangChain's recommended approach for building agents. Use when: langgraph, langchain agent, stateful agent, agent graph, react agent.
Add this skill
npx mdskills install sickn33/langgraphComprehensive LangGraph instructions with clear patterns, reducers, and routing logic
1---2name: langgraph3description: "Expert in LangGraph - the production-grade framework for building stateful, multi-actor AI applications. Covers graph construction, state management, cycles and branches, persistence with checkpointers, human-in-the-loop patterns, and the ReAct agent pattern. Used in production at LinkedIn, Uber, and 400+ companies. This is LangChain's recommended approach for building agents. Use when: langgraph, langchain agent, stateful agent, agent graph, react agent."4source: vibeship-spawner-skills (Apache 2.0)5---67# LangGraph89**Role**: LangGraph Agent Architect1011You are an expert in building production-grade AI agents with LangGraph. You12understand that agents need explicit structure - graphs make the flow visible13and debuggable. You design state carefully, use reducers appropriately, and14always consider persistence for production. You know when cycles are needed15and how to prevent infinite loops.1617## Capabilities1819- Graph construction (StateGraph)20- State management and reducers21- Node and edge definitions22- Conditional routing23- Checkpointers and persistence24- Human-in-the-loop patterns25- Tool integration26- Streaming and async execution2728## Requirements2930- Python 3.9+31- langgraph package32- LLM API access (OpenAI, Anthropic, etc.)33- Understanding of graph concepts3435## Patterns3637### Basic Agent Graph3839Simple ReAct-style agent with tools4041**When to use**: Single agent with tool calling4243```python44from typing import Annotated, TypedDict45from langgraph.graph import StateGraph, START, END46from langgraph.graph.message import add_messages47from langgraph.prebuilt import ToolNode48from langchain_openai import ChatOpenAI49from langchain_core.tools import tool5051# 1. Define State52class AgentState(TypedDict):53 messages: Annotated[list, add_messages]54 # add_messages reducer appends, doesn't overwrite5556# 2. Define Tools57@tool58def search(query: str) -> str:59 """Search the web for information."""60 # Implementation here61 return f"Results for: {query}"6263@tool64def calculator(expression: str) -> str:65 """Evaluate a math expression."""66 return str(eval(expression))6768tools = [search, calculator]6970# 3. Create LLM with tools71llm = ChatOpenAI(model="gpt-4o").bind_tools(tools)7273# 4. Define Nodes74def agent(state: AgentState) -> dict:75 """The agent node - calls LLM."""76 response = llm.invoke(state["messages"])77 return {"messages": [response]}7879# Tool node handles tool execution80tool_node = ToolNode(tools)8182# 5. Define Routing83def should_continue(state: AgentState) -> str:84 """Route based on whether tools were called."""85 last_message = state["messages"][-1]86 if last_message.tool_calls:87 return "tools"88 return END8990# 6. Build Graph91graph = StateGraph(AgentState)9293# Add nodes94graph.add_node("agent", agent)95graph.add_node("tools", tool_node)9697# Add edges98graph.add_edge(START, "agent")99graph.add_conditional_edges("agent", should_continue, ["tools", END])100graph.add_edge("tools", "agent") # Loop back101102# Compile103app = graph.compile()104105# 7. Run106result = app.invoke({107 "messages": [("user", "What is 25 * 4?")]108})109```110111### State with Reducers112113Complex state management with custom reducers114115**When to use**: Multiple agents updating shared state116117```python118from typing import Annotated, TypedDict119from operator import add120from langgraph.graph import StateGraph121122# Custom reducer for merging dictionaries123def merge_dicts(left: dict, right: dict) -> dict:124 return {**left, **right}125126# State with multiple reducers127class ResearchState(TypedDict):128 # Messages append (don't overwrite)129 messages: Annotated[list, add_messages]130131 # Research findings merge132 findings: Annotated[dict, merge_dicts]133134 # Sources accumulate135 sources: Annotated[list[str], add]136137 # Current step (overwrites - no reducer)138 current_step: str139140 # Error count (custom reducer)141 errors: Annotated[int, lambda a, b: a + b]142143# Nodes return partial state updates144def researcher(state: ResearchState) -> dict:145 # Only return fields being updated146 return {147 "findings": {"topic_a": "New finding"},148 "sources": ["source1.com"],149 "current_step": "researching"150 }151152def writer(state: ResearchState) -> dict:153 # Access accumulated state154 all_findings = state["findings"]155 all_sources = state["sources"]156157 return {158 "messages": [("assistant", f"Report based on {len(all_sources)} sources")],159 "current_step": "writing"160 }161162# Build graph163graph = StateGraph(ResearchState)164graph.add_node("researcher", researcher)165graph.add_node("writer", writer)166# ... add edges167```168169### Conditional Branching170171Route to different paths based on state172173**When to use**: Multiple possible workflows174175```python176from langgraph.graph import StateGraph, START, END177178class RouterState(TypedDict):179 query: str180 query_type: str181 result: str182183def classifier(state: RouterState) -> dict:184 """Classify the query type."""185 query = state["query"].lower()186 if "code" in query or "program" in query:187 return {"query_type": "coding"}188 elif "search" in query or "find" in query:189 return {"query_type": "search"}190 else:191 return {"query_type": "chat"}192193def coding_agent(state: RouterState) -> dict:194 return {"result": "Here's your code..."}195196def search_agent(state: RouterState) -> dict:197 return {"result": "Search results..."}198199def chat_agent(state: RouterState) -> dict:200 return {"result": "Let me help..."}201202# Routing function203def route_query(state: RouterState) -> str:204 """Route to appropriate agent."""205 query_type = state["query_type"]206 return query_type # Returns node name207208# Build graph209graph = StateGraph(RouterState)210211graph.add_node("classifier", classifier)212graph.add_node("coding", coding_agent)213graph.add_node("search", search_agent)214graph.add_node("chat", chat_agent)215216graph.add_edge(START, "classifier")217218# Conditional edges from classifier219graph.add_conditional_edges(220 "classifier",221 route_query,222 {223 "coding": "coding",224 "search": "search",225 "chat": "chat"226 }227)228229# All agents lead to END230graph.add_edge("coding", END)231graph.add_edge("search", END)232graph.add_edge("chat", END)233234app = graph.compile()235```236237## Anti-Patterns238239### ❌ Infinite Loop Without Exit240241**Why bad**: Agent loops forever.242Burns tokens and costs.243Eventually errors out.244245**Instead**: Always have exit conditions:246- Max iterations counter in state247- Clear END conditions in routing248- Timeout at application level249250def should_continue(state):251 if state["iterations"] > 10:252 return END253 if state["task_complete"]:254 return END255 return "agent"256257### ❌ Stateless Nodes258259**Why bad**: Loses LangGraph's benefits.260State not persisted.261Can't resume conversations.262263**Instead**: Always use state for data flow.264Return state updates from nodes.265Use reducers for accumulation.266Let LangGraph manage state.267268### ❌ Giant Monolithic State269270**Why bad**: Hard to reason about.271Unnecessary data in context.272Serialization overhead.273274**Instead**: Use input/output schemas for clean interfaces.275Private state for internal data.276Clear separation of concerns.277278## Limitations279280- Python-only (TypeScript in early stages)281- Learning curve for graph concepts282- State management complexity283- Debugging can be challenging284285## Related Skills286287Works well with: `crewai`, `autonomous-agents`, `langfuse`, `structured-output`288
Full transparency — inspect the skill content before installing.