Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Build production-grade agentic workflows with LangGraph using graph-based orchestration, state machines, human-in-the-loop, and advanced control flow
.claude/skills/majiayu000-langgraph-patterns-expert/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-18 | ✗→✓ | ▲ Improved | 119% | 0% |
| case-22 | ✗→✓ | ▲ Improved | 75% | 0% |
| case-15 | ✓→✗ | ▼ Worse | 157% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 56% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 77% | 0% |
Master LangGraph for building production-ready AI agents with fine-grained control, checkpointing, streaming, and complex state management.
LangGraph is: An orchestration framework with both declarative and imperative APIs focused on control and durability for production agents.
Not: High-level abstractions that hide complexity - instead provides building blocks for full control.
Migration: LangGraph replaces legacy AgentExecutor - migrate all old code.
pythonfrom langgraph.graph import StateGraph, END # Define state class AgentState(TypedDict): messages: Annotated[list, add_messages] next_action: str # Create graph graph = StateGraph(AgentState) # Add nodes graph.add_node("analyze", analyze_node) graph.add_node("execute", execute_node) graph.add_node("verify", verify_node) # Define edges graph.add_edge("analyze", "execute") graph.add_conditional_edges( "execute", should_verify, {"yes": "verify", "no": END} ) # Compile app = graph.compile()
pythonfrom langgraph.prebuilt import create_react_agent tools = [search_tool, calculator_tool, db_query_tool] agent = create_react_agent( model=llm, tools=tools, checkpointer=MemorySaver() ) # Run with streaming for chunk in agent.stream({"messages": [("user", "Analyze sales data")]}): print(chunk)
python# Supervisor coordinates specialist agents supervisor_graph = StateGraph(SupervisorState) supervisor_graph.add_node("supervisor", supervisor_node) supervisor_graph.add_node("researcher", researcher_agent) supervisor_graph.add_node("analyst", analyst_agent) supervisor_graph.add_node("writer", writer_agent) # Supervisor routes to specialists supervisor_graph.add_conditional_edges( "supervisor", route_to_agent, { "research": "researcher", "analyze": "analyst", "write": "writer", "finish": END } )
pythonfrom langgraph.checkpoint.sqlite import SqliteSaver checkpointer = SqliteSaver.from_conn_string("checkpoints.db") graph = StateGraph(State) graph.add_node("propose_action", propose) graph.add_node("human_approval", interrupt()) # Pauses here graph.add_node("execute_action", execute) app = graph.compile(checkpointer=checkpointer) # Run until human input needed result = app.invoke(input, config={"configurable": {"thread_id": "123"}}) # Human reviews, then resume app.invoke(None, config={"configurable": {"thread_id": "123"}})
pythonclass ConversationState(TypedDict): messages: Annotated[list, add_messages] context: dict checkpointer = MemorySaver() app = graph.compile(checkpointer=checkpointer) # Maintains context across turns config = {"configurable": {"thread_id": "user_123"}} app.invoke({"messages": [("user", "Hello")]}, config) app.invoke({"messages": [("user", "What did I just say?")]}, config)
pythonfrom langgraph.checkpoint.postgres import PostgresSaver checkpointer = PostgresSaver.from_conn_string(db_url) # Persists across sessions app = graph.compile(checkpointer=checkpointer)
pythondef route_next(state): if state["confidence"] > 0.9: return "approve" elif state["confidence"] > 0.5: return "review" else: return "reject" graph.add_conditional_edges( "classifier", route_next, { "approve": "auto_approve", "review": "human_review", "reject": "reject_node" } )
pythondef should_continue(state): if state["iterations"] < 3 and not state["success"]: return "retry" return "finish" graph.add_conditional_edges( "process", should_continue, {"retry": "process", "finish": END} )
pythonfrom langgraph.graph import START # Fan out to parallel nodes graph.add_edge(START, ["agent_a", "agent_b", "agent_c"]) # Fan in to aggregator graph.add_edge(["agent_a", "agent_b", "agent_c"], "synthesize")
pythonasync for event in app.astream_events(input, version="v2"): if event["event"] == "on_chat_model_stream": print(event["data"]["chunk"].content, end="")
pythondef error_handler(state): try: return execute_risky_operation(state) except Exception as e: return {"error": str(e), "next": "fallback"} graph.add_node("risky_op", error_handler) graph.add_conditional_edges( "risky_op", lambda s: "fallback" if "error" in s else "success" )
pythonimport os os.environ["LANGCHAIN_TRACING_V2"] = "true" os.environ["LANGCHAIN_API_KEY"] = "..." # All agent actions automatically logged to LangSmith app.invoke(input)
DO: ✅ Use checkpointing for long-running tasks ✅ Stream outputs for better UX ✅ Implement human approval for critical actions ✅ Use conditional edges for complex routing ✅ Leverage parallel execution when possible ✅ Monitor with LangSmith in production
DON'T: ❌ Use AgentExecutor (deprecated) ❌ Skip error handling on nodes ❌ Forget to set thread_id for stateful conversations ❌ Over-complicate graphs unnecessarily ❌ Ignore memory management for long conversations
pythonfrom langchain_anthropic import ChatAnthropic llm = ChatAnthropic(model="claude-sonnet-4-5") agent = create_react_agent(llm, tools)
pythonfrom langchain_openai import ChatOpenAI llm = ChatOpenAI(model="gpt-4o") agent = create_react_agent(llm, tools)
pythonfrom langchain_mcp import MCPTool github_tool = MCPTool.from_server("github-mcp") tools = [github_tool, ...] agent = create_react_agent(llm, tools)
Use LangGraph when:
Use alternatives when:
LangGraph is the production-grade choice for complex agentic workflows requiring maximum control.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 13,155 | 14,228 | +8% | 1 | 1 | 0% | 2,444 | 3,822 | +56% | 0 | 0 | — |
case-02 | pass→pass | 9,513 | 10,982 | +15% | 1 | 1 | 0% | 1,758 | 3,118 | +77% | 0 | 0 | — |
case-03 | pass→pass | 11,668 | 12,756 | +9% | 1 | 1 | 0% | 1,203 | 3,109 | +158% | 0 | 0 | — |
case-04 | fail→fail | 21,037 | 18,546 | -12% | 1 | 1 | 0% | 3,978 | 5,507 | +38% | 0 | 0 | — |
case-05 | pass→pass | 11,753 | 13,829 | +18% | 1 | 1 | 0% | 2,264 | 3,740 | +65% | 0 | 0 | — |
case-06 | pass→pass | 6,182 | 8,915 | +44% | 1 | 1 | 0% | 1,191 | 2,699 | +127% | 0 | 0 | — |
case-07 | pass→pass | 15,543 | 17,618 | +13% | 1 | 1 | 0% | 2,970 | 4,391 | +48% | 0 | 0 | — |
case-08 | pass→pass | 8,207 | 5,293 | -36% | 1 | 1 | 0% | 1,545 | 2,993 | +94% | 0 | 0 | — |
case-09 | pass→pass | 13,516 | 15,514 | +15% | 1 | 1 | 0% | 2,363 | 3,753 | +59% | 0 | 0 | — |
case-10 | pass→pass | 8,629 | 12,691 | +47% | 1 | 1 | 0% | 1,486 | 3,312 | +123% | 0 | 0 | — |
case-11 | fail→fail | 17,394 | 15,186 | -13% | 1 | 1 | 0% | 3,212 | 4,931 | +54% | 0 | 0 | — |
case-12 | pass→pass | 12,511 | 16,578 | +33% | 1 | 1 | 0% | 2,331 | 4,218 | +81% | 0 | 0 | — |
case-13 | pass→pass | 15,127 | 15,311 | +1% | 1 | 1 | 0% | 2,821 | 4,802 | +70% | 0 | 0 | — |
case-14 | pass→pass | 7,875 | 10,177 | +29% | 1 | 1 | 0% | 1,519 | 3,009 | +98% | 0 | 0 | — |
case-15 | pass→fail | 6,152 | 5,474 | -11% | 1 | 1 | 0% | 1,163 | 2,991 | +157% | 0 | 0 | — |
case-16 | pass→pass | 20,181 | 7,824 | -61% | 1 | 1 | 0% | 2,510 | 3,289 | +31% | 0 | 0 | — |
case-17 | pass→pass | 13,806 | 11,511 | -17% | 1 | 1 | 0% | 1,471 | 3,142 | +114% | 0 | 0 | — |
case-18 | fail→pass | 9,750 | 9,114 | -7% | 1 | 1 | 0% | 1,603 | 3,504 | +119% | 0 | 0 | — |
case-19 | pass→pass | 12,539 | 6,044 | -52% | 1 | 1 | 0% | 1,299 | 3,243 | +150% | 0 | 0 | — |
case-20 | pass→pass | 7,218 | 4,879 | -32% | 1 | 1 | 0% | 1,294 | 2,850 | +120% | 0 | 0 | — |
case-21 | pass→pass | 16,550 | 17,032 | +3% | 1 | 1 | 0% | 2,696 | 4,855 | +80% | 0 | 0 | — |
case-22 | fail→pass | 12,385 | 10,632 | -14% | 1 | 1 | 0% | 2,379 | 4,167 | +75% | 0 | 0 | — |
case-23 | pass→pass | 7,971 | 2,710 | -66% | 1 | 1 | 0% | 597 | 2,435 | +308% | 0 | 0 | — |
case-24 | pass→pass | 10,951 | 4,081 | -63% | 1 | 1 | 0% | 2,427 | 2,764 | +14% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 24 cases were attempted. The headline lift of +4 percentage points is the difference between those two pass rates over the 24 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.