### Quickstart Setup and Dependencies Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/README.md Install required packages and set the OpenAI API key environment variable. ```bash pip install langgraph-supervisor langchain-openai export OPENAI_API_KEY= ``` -------------------------------- ### Basic Supervisor Setup Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/quick_reference.md Set up a basic supervisor with a single agent and invoke it. ```python from langchain_openai import ChatOpenAI from langgraph.prebuilt import create_react_agent from langgraph_supervisor import create_supervisor # Create model model = ChatOpenAI(model="gpt-4o") # Create agents with tools def tool1(arg: str) -> str: return f"Result: {arg}" agent1 = create_react_agent( model=model, tools=[tool1], name="agent_1", ) # Create supervisor managing agents workflow = create_supervisor( agents=[agent1], model=model, prompt="You manage specialized agents. Delegate tasks appropriately.", ) # Compile and invoke app = workflow.compile() result = app.invoke({ "messages": [{"role": "user", "content": "Do something"}] }) ``` -------------------------------- ### Graph-Based Orchestration Setup Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/architecture.md Demonstrates the basic setup of a StateGraph for the supervisor, including adding nodes and edges. ```python builder = StateGraph(state_schema) builder.add_node("supervisor", supervisor_agent) builder.add_node("agent1", worker_1) builder.add_edge(START, "supervisor") builder.add_edge("agent1", "supervisor") ``` -------------------------------- ### Installation and Requirements Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/00_START_HERE.md Installs the necessary packages for the supervisor pattern and sets the OpenAI API key. Ensure Python 3.10+ and specific versions of langgraph and langchain-core are installed. ```bash pip install langgraph-supervisor langchain-openai export OPENAI_API_KEY=sk-... ``` -------------------------------- ### Basic Two-Agent Setup with Research and Math Experts Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/examples.md This snippet shows a fundamental setup with two specialized agents: a research expert and a math expert, managed by a supervisor. It demonstrates defining tools, creating agents, configuring the supervisor's prompt, and invoking the compiled workflow to handle a mixed query. ```python from langchain_openai import ChatOpenAI from langgraph.prebuilt import create_react_agent from langgraph_supervisor import create_supervisor model = ChatOpenAI(model="gpt-4o") # Define tools for each agent def web_search(query: str) -> str: """Search the web for current information.""" return "Result for: " + query def calculate(expression: str) -> str: """Evaluate a mathematical expression.""" return "Result: " + str(eval(expression)) # Create specialized agents research_agent = create_react_agent( model=model, tools=[web_search], name="research_expert", prompt="You are a research specialist. Always use web_search for information.", ) math_agent = create_react_agent( model=model, tools=[calculate], name="math_expert", prompt="You are a math specialist. Always use calculate for math problems.", ) # Create supervisor managing both workflow = create_supervisor( agents=[research_agent, math_agent], model=model, prompt=( "You are a supervisor managing research and math experts. " "For questions about current events or facts, use research_expert. " "For mathematical problems, use math_expert. " "Synthesize their responses into a clear answer." ), ) # Compile and run app = workflow.compile() result = app.invoke({ "messages": [ {"role": "user", "content": "What's 15 * 7? Also, who won the 2024 World Series?"} ] }) print("Final answer:") for msg in result["messages"]: if hasattr(msg, "content"): print(f"{msg.name or 'User'}: {msg.content}") ``` -------------------------------- ### Install langgraph-supervisor and dependencies Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/quick_reference.md Install the necessary packages and set your OpenAI API key. ```bash pip install langgraph-supervisor langchain-openai export OPENAI_API_KEY= ``` -------------------------------- ### Install LangGraph Supervisor Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/README.md Install the library via pip. ```bash pip install langgraph-supervisor ``` -------------------------------- ### Minimal Viable LangGraph Supervisor Example Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/api_summary.md Demonstrates the creation and invocation of a supervisor workflow with two agents. ```python from langchain_openai import ChatOpenAI from langgraph.prebuilt import create_react_agent from langgraph_supervisor import create_supervisor # 1. Create LLM model = ChatOpenAI(model="gpt-4o") # 2. Create agents agent1 = create_react_agent( model=model, tools=[tool1], name="agent_1", ) agent2 = create_react_agent( model=model, tools=[tool2], name="agent_2", ) # 3. Create supervisor workflow = create_supervisor( agents=[agent1, agent2], model=model, ) # 4. Compile and invoke app = workflow.compile() result = app.invoke({"messages": [{"role": "user", "content": "..."}]}) ``` -------------------------------- ### Basic Supervisor Workflow Setup Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/INDEX.md Demonstrates how to create two agents using create_react_agent and then set up a supervisor to manage them. The workflow is compiled and invoked with a sample user message. ```python from langchain_openai import ChatOpenAI from langgraph.prebuilt import create_react_agent from langgraph_supervisor import create_supervisor model = ChatOpenAI(model="gpt-4o") # Create agents agent1 = create_react_agent( model=model, tools=[tool1, tool2], name="specialist_1", ) agent2 = create_react_agent( model=model, tools=[tool3, tool4], name="specialist_2", ) # Create supervisor workflow = create_supervisor( agents=[agent1, agent2], model=model, prompt="Manage these agents: delegate appropriately.", ) # Compile and run app = workflow.compile() result = app.invoke({"messages": [{"role": "user", "content": "..."}]}) ``` -------------------------------- ### Basic Two-Agent Setup with LangGraph Supervisor Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/create_supervisor.md Sets up a supervisor with two specialized agents (research and math) and a basic prompt for task delegation. This is useful for simple agent workflows. ```python from langchain_openai import ChatOpenAI from langgraph.prebuilt import create_react_agent from langgraph_supervisor import create_supervisor model = ChatOpenAI(model="gpt-4o") # Define agent tools def web_search(query: str) -> str: """Search the web.""" return "Search results..." def calculate(expression: str) -> str: """Calculate mathematical expressions.""" return "42" # Create specialized agents research_agent = create_react_agent( model=model, tools=[web_search], name="research_expert", ) math_agent = create_react_agent( model=model, tools=[calculate], name="math_expert", ) # Create supervisor workflow = create_supervisor( agents=[research_agent, math_agent], model=model, prompt="You are a supervisor managing research and math experts. " "Delegate research tasks to research_expert and math tasks to math_expert.", ) # Compile and invoke app = workflow.compile() result = app.invoke({ "messages": [{"role": "user", "content": "What is 5 + 3?"}] }) ``` -------------------------------- ### Example Usage of LanguageModelLike with create_supervisor Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/types.md Demonstrates using direct `BaseChatModel` instances, wrapped `Runnable` models, and custom `RunnableLambda` models with the `create_supervisor` function. ```python from langchain_openai import ChatOpenAI from langgraph_supervisor import create_supervisor, with_agent_name # Direct model model1 = ChatOpenAI(model="gpt-4o") # Wrapped model (Runnable) model2 = with_agent_name(ChatOpenAI(model="gpt-4o"), "inline") # Custom Runnable model from langchain_core.runnables import RunnableLambda def custom_llm(messages): # Custom logic here return AIMessage(content="Custom response") model3 = RunnableLambda(custom_llm) # All work with create_supervisor for m in [model1, model2, model3]: workflow = create_supervisor( agents=[agent1, agent2], model=m, ) ``` -------------------------------- ### Basic Supervisor Setup with Inline Agent Names Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/with_agent_name.md Demonstrates creating a supervisor with agents that use inline agent name formatting. This approach ensures compatibility across different model providers. ```python from langchain_openai import ChatOpenAI from langgraph_supervisor import create_supervisor from langgraph.prebuilt import create_react_agent from langgraph_supervisor.agent_name import with_agent_name # Create model with inline agent name support base_model = ChatOpenAI(model="gpt-4o") model_with_names = with_agent_name(base_model, "inline") # Create supervisor using the wrapped model research_agent = create_react_agent( model=model_with_names, tools=[web_search], name="research_expert", ) math_agent = create_react_agent( model=model_with_names, tools=[calculate], name="math_expert", ) workflow = create_supervisor( agents=[research_agent, math_agent], model=model_with_names, include_agent_name="inline", # Coordinator level ) app = workflow.compile() ``` -------------------------------- ### Create Supervisor with Output Modes Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/types.md Example demonstrating how to configure the output mode when creating a supervisor. 'full_history' retains all intermediate messages, while 'last_message' (default) keeps the history concise. ```python from langgraph_supervisor import create_supervisor # Full history mode - all agent messages retained workflow1 = create_supervisor( agents=[agent1, agent2], model=model, output_mode="full_history", ) # Last message mode - concise history workflow2 = create_supervisor( agents=[agent1, agent2], model=model, output_mode="last_message", # Default ) ``` -------------------------------- ### Example Usage of StateSchemaType with TypedDict Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/types.md Shows how to define a custom state schema using TypedDict and pass it to create_supervisor. ```python from typing import TypedDict from typing_extensions import Annotated from langchain_core.messages import AnyMessage from langgraph.graph.message import add_messages from langgraph_supervisor import create_supervisor class CustomState(TypedDict): messages: Annotated[list[AnyMessage], add_messages] turn_count: int current_agent: str workflow = create_supervisor( agents=[agent1, agent2], model=model, state_schema=CustomState, ) ``` -------------------------------- ### Example Usage of RunnableLike for Hooks Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/types.md Demonstrates using both a Python callable and a LangChain Runnable as pre_model_hook in create_supervisor. ```python from langgraph_supervisor import create_supervisor # Callable hook def trim_messages(state): messages = state.get("messages", []) if len(messages) > 50: messages = messages[-30:] # Keep last 30 return {"messages": messages} # Runnable hook from langchain_core.runnables import RunnableLambda trim_runnable = RunnableLambda(trim_messages) workflow = create_supervisor( agents=[agent1, agent2], model=model, pre_model_hook=trim_messages, # Or trim_runnable ) ``` -------------------------------- ### Basic Supervisor Setup and Execution Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/00_START_HERE.md This snippet shows the minimal code required to create two agents, set up a supervisor to manage them, and then compile and invoke the workflow. It highlights the automatic creation of handoff tools and routing. ```python # 1. Create agents agent1 = create_react_agent(model=model, tools=[...], name="expert1") agent2 = create_react_agent(model=model, tools=[...], name="expert2") # 2. Create supervisor workflow = create_supervisor([agent1, agent2], model=model) # 3. Run it app = workflow.compile() result = app.invoke({"messages": [{"role": "user", "content": "..."}]}) ``` -------------------------------- ### Supervisor with TypedDict Response Format Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/types.md Example of creating a supervisor using a TypedDict for the response format. Ensure the TypedDict is defined before passing it to create_supervisor. ```python from typing import TypedDict from pydantic import BaseModel from langgraph_supervisor import create_supervisor # TypedDict schema class Answer(TypedDict): text: str confidence: float workflow1 = create_supervisor( agents=[agent1, agent2], model=model, response_format=Answer, ) ``` -------------------------------- ### Supervisor Setup Without Agent Name Wrapping Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/with_agent_name.md Demonstrates setting up a supervisor for models like OpenAI that natively support the 'name' field in messages. In this case, explicit wrapping with `with_agent_name` is not required. ```python # For OpenAI, the native name field is used automatically # No wrapping needed: workflow = create_supervisor( agents=[research_agent, math_agent], model=ChatOpenAI(model="gpt-4o"), # include_agent_name not set (None) or omitted ) # OpenAI's API sees the message with the name attribute # and uses it internally for context ``` -------------------------------- ### Supervisor Setup with Alternative Models and Inline Formatting Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/with_agent_name.md Shows how to use `with_agent_name` with models that do not natively support agent name fields, such as certain Anthropic models. Inline formatting ensures agent names are explicitly included in the prompt. ```python from anthropic import Anthropic from langchain_anthropic import ChatAnthropic # For models that don't support name fields, # inline formatting makes names explicit model = ChatAnthropic(model="claude-3-5-sonnet-20241022") model_with_names = with_agent_name(model, "inline") workflow = create_supervisor( agents=[agent1, agent2], model=model_with_names, ) ``` -------------------------------- ### Two-Agent Question Routing Setup Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/00_START_HERE.md Set up a supervisor workflow for two agents, demonstrating how to route questions between a research agent and a math agent. This is useful for tasks requiring specialized agent capabilities. ```python # See: examples.md → Example 1 research_agent = create_react_agent(..., name="research") math_agent = create_react_agent(..., name="math") workflow = create_supervisor([research_agent, math_agent], model=model) app = workflow.compile() result = app.invoke({"messages": [{"role": "user", "content": "..."}]}) ``` -------------------------------- ### Structured Output with Supervisor Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/quick_reference.md Configure the supervisor to expect a specific structured response format using response_format and state_schema. This example uses a TypedDict for the response structure. ```python from typing import TypedDict class Answer(TypedDict): response: str confidence: float workflow = create_supervisor( agents=[agent1, agent2], model=model, response_format=Answer, state_schema=AgentStateWithStructuredResponse, ) app = workflow.compile() result = app.invoke({"messages": [...]}) print(result["structured_response"]) ``` -------------------------------- ### Example: Extracting Agent Name and Content Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/agent_name_functions.md Demonstrates how to use the defined regex patterns to extract the agent name and message content from a sample XML string. ```python import re NAME_PATTERN = re.compile(r"(.*?)", re.DOTALL) CONTENT_PATTERN = re.compile(r"(.*?)", re.DOTALL) text = "research_expertMulti-line\ncontent here" name_match = NAME_PATTERN.search(text) name = name_match.group(1) if name_match else None # Result: "research_expert" content_match = CONTENT_PATTERN.search(text) content = content_match.group(1) if content_match else None # Result: "Multi-line\ncontent here" ``` -------------------------------- ### Define Agents with Functional API Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/README.md Example of creating a specialized agent using the Functional API's task and entrypoint decorators. ```python from langgraph.prebuilt import create_react_agent from langgraph_supervisor import create_supervisor from langchain_openai import ChatOpenAI from langgraph.func import entrypoint, task from langgraph.graph import add_messages model = ChatOpenAI(model="gpt-4o") # Create specialized agents # Functional API - Agent 1 (Joke Generator) @task def generate_joke(messages): """First LLM call to generate initial joke""" system_message = { "role": "system", "content": "Write a short joke" } msg = model.invoke( [system_message] + messages ) return msg @entrypoint() def joke_agent(state): joke = generate_joke(state['messages']).result() messages = add_messages(state["messages"], [joke]) return {"messages": messages} joke_agent.name = "joke_agent" ``` -------------------------------- ### Custom Handoff Tools with Task Descriptions Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/examples.md This example shows how to create and use custom handoff tools within a supervisor workflow. These tools allow for more granular control over delegation by including a detailed `task_description` argument, ensuring the receiving agent understands its specific objective. ```python from typing import Annotated from langchain_core.tools import tool, BaseTool, InjectedToolCallId from langchain_core.messages import ToolMessage from langgraph.prebuilt import InjectedState from langgraph.types import Command from langgraph_supervisor import create_supervisor from langgraph_supervisor.handoff import METADATA_KEY_HANDOFF_DESTINATION def create_advanced_handoff(agent_name: str, name: str | None = None) -> BaseTool: """Create handoff tool with task description argument.""" if name is None: name = f"transfer_to_{agent_name.lower().replace(' ', '_')}" @tool(name, description=f"Delegate task to {agent_name}") def handoff_to_agent( task_description: Annotated[ str, "Detailed description of what this agent should do" ], state: Annotated[dict, InjectedState], tool_call_id: Annotated[str, InjectedToolCallId], ) -> Command: tool_message = ToolMessage( content=f"Successfully transferred to {agent_name}", name=name, tool_call_id=tool_call_id, ) return Command( goto=agent_name, graph=Command.PARENT, update={ "messages": state["messages"] + [tool_message], "task_description": task_description, }, ) handoff_to_agent.metadata = {METADATA_KEY_HANDOFF_DESTINATION: agent_name} return handoff_to_agent # Use custom handoff tools tools = [ create_advanced_handoff("research_agent"), create_advanced_handoff("analysis_agent"), ] workflow = create_supervisor( agents=[research_agent, analysis_agent], model=model, tools=tools, prompt="""When delegating, provide a clear task description to the agent specifying exactly what you want them to do.""", ) ``` -------------------------------- ### Supervisor with Pydantic Response Format Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/types.md Example of creating a supervisor using a Pydantic BaseModel for the response format. Ensure the BaseModel is defined before passing it to create_supervisor. ```python from typing import TypedDict from pydantic import BaseModel from langgraph_supervisor import create_supervisor # Pydantic schema class Answer(BaseModel): text: str confidence: float workflow2 = create_supervisor( agents=[agent1, agent2], model=model, response_format=Answer, ) ``` -------------------------------- ### Message History Example for Forward Message Tool Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/create_forward_message_tool.md Demonstrates a typical message history where the forward_message tool would be used. It shows how the tool identifies the agent's direct response and forwards it. ```python # Given this message history: messages = [ HumanMessage(content="What is 2 + 2?"), AIMessage(content="", tool_calls=[{"name": "transfer_to_math_expert", ...}]), ToolMessage(content="Successfully transferred to math_expert", ...), AIMessage(content="4", name="math_expert"), # Agent's response AIMessage(content="", tool_calls=[{"name": "forward_message", "args": {"from_agent": "math_expert"}}]), ] # Calling forward_message with from_agent="math_expert" will: # 1. Find the AIMessage with name="math_expert" and content="4" # 2. Create a new AIMessage with that content and name="supervisor" # 3. Return it as the final output ``` -------------------------------- ### Customer Service Multi-Agent System Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/examples.md This example demonstrates a customer service routing system. It defines billing, technical, and general support agents, each with specialized tools. A supervisor agent routes incoming customer queries to the appropriate specialist agent and can forward messages to resolve issues. ```Python from langchain_openai import ChatOpenAI from langgraph.prebuilt import create_react_agent from langgraph_supervisor import create_supervisor, create_forward_message_tool model = ChatOpenAI(model="gpt-4o") # Support Agent 1: Billing Specialist def check_account(customer_id: str) -> str: """Check customer account details.""" return f"Account {customer_id}: Active, Premium plan, $99/month" def process_refund(customer_id: str, amount: str) -> str: """Process a refund.""" return f"Refund of ${amount} processed for customer {customer_id}" billing_agent = create_react_agent( model=model, tools=[check_account, process_refund], name="billing_specialist", prompt="""You help with billing and payment issues. 1. Check customer account status 2. Process refunds when appropriate 3. Explain charges and subscriptions 4. Provide clear resolution to billing problems""", ) # Support Agent 2: Technical Support def check_system_status() -> str: """Check if systems are operational.""" return "All systems operational" def restart_service(service: str) -> str: """Restart a service.""" return f"Service {service} restarted" def view_error_logs(customer_id: str) -> str: """View error logs for customer.""" return f"Error logs for {customer_id}: [log1, log2]" technical_agent = create_react_agent( model=model, tools=[check_system_status, restart_service, view_error_logs], name="technical_specialist", prompt="""You help with technical issues. 1. Check system status 2. Review error logs 3. Troubleshoot problems 4. Restart services when needed 5. Provide technical explanations""", ) # Support Agent 3: General Support def view_documentation(topic: str) -> str: """Look up relevant documentation.""" return f"Documentation for {topic}: [help1, help2]" def create_support_ticket(issue: str) -> str: """Create escalation ticket.""" return f"Ticket created for: {issue}" general_agent = create_react_agent( model=model, tools=[view_documentation, create_support_ticket], name="general_support", prompt="""You provide general support and escalation. 1. Answer common questions 2. Reference documentation 3. Create escalation tickets for complex issues 4. Direct customers to appropriate resources""", ) # Create supervisor with message forwarding workflow = create_supervisor( agents=[billing_agent, technical_agent, general_agent], model=model, tools=[create_forward_message_tool("supervisor")], # Enable forwarding prompt="""You are the customer support supervisor. Route issues appropriately: BILLING ISSUES → billing_specialist - Refunds, charges, subscriptions, payments TECHNICAL ISSUES → technical_specialist - Errors, system problems, troubleshooting, performance GENERAL/OTHER → general_support - FAQs, documentation, escalations If an agent's response fully resolves the issue, use forward_message to send their answer directly to the customer (saves the customer from hearing the same thing twice). Only synthesize if you need to combine multiple agent responses.""", output_mode="last_message", ) app = workflow.compile() # Example customer query result = app.invoke({ "messages": [ { "role": "user", "content": "I was charged twice this month. Can you help me?" } ] }) print("Response:") print(result["messages"][-1].content) ``` -------------------------------- ### Example Usage of Handoff Destination Metadata Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/types.md Demonstrates how the `METADATA_KEY_HANDOFF_DESTINATION` constant is used when creating a handoff tool. The resulting tool's metadata will include this key to specify the target agent. ```python from langgraph_supervisor.handoff import METADATA_KEY_HANDOFF_DESTINATION, create_handoff_tool tool = create_handoff_tool(agent_name="research_expert") # The tool's metadata includes: # {METADATA_KEY_HANDOFF_DESTINATION: "research_expert"} ``` -------------------------------- ### Agent Specialization with Supervisor Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/quick_reference.md Define agents with specific roles and tools using create_react_agent. This example creates a 'researcher' agent and an 'analyst' agent, then configures the supervisor to coordinate them. ```python # Create agents with specific instructions agent1 = create_react_agent( model=model, tools=[tool1, tool2], name="researcher", prompt="You are a research specialist. Search for information.", ) agent2 = create_react_agent( model=model, tools=[tool3, tool4], name="analyst", prompt="You are an analyst. Process and interpret data.", ) workflow = create_supervisor( agents=[agent1, agent2], model=model, prompt="Coordinate research and analysis for comprehensive answers.", ) ``` -------------------------------- ### Three-Agent Workflow Setup Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/00_START_HERE.md Configure a supervisor workflow for three distinct agents: research, analysis, and writing. This pattern is suitable for sequential task execution where each agent performs a specific step. ```python # See: examples.md → Example 2 research = create_react_agent(..., name="research") analysis = create_react_agent(..., name="analysis") writing = create_react_agent(..., name="writing") workflow = create_supervisor([research, analysis, writing], model=model) ``` -------------------------------- ### Supervisor with JSON Schema Dictionary Response Format Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/types.md Example of creating a supervisor using a JSON Schema dictionary for the response format. This provides flexibility but requires manual schema definition. ```python from typing import TypedDict from pydantic import BaseModel from langgraph_supervisor import create_supervisor # JSON Schema dict workflow3 = create_supervisor( agents=[agent1, agent2], model=model, response_format={ "type": "object", "properties": { "text": {"type": "string"}, "confidence": {"type": "number"} }, }, ) ``` -------------------------------- ### Basic Message Forwarding with Supervisor Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/create_forward_message_tool.md Demonstrates how to create and use the forward_message tool within a supervisor workflow for basic message forwarding. The tool is added to the supervisor's tools list, and the prompt guides the supervisor on when to use it. ```python from langgraph_supervisor import create_supervisor, create_forward_message_tool from langgraph.prebuilt import create_react_agent from langchain_openai import ChatOpenAI model = ChatOpenAI(model="gpt-4o") research_agent = create_react_agent( model=model, tools=[web_search], name="research_expert", ) math_agent = create_react_agent( model=model, tools=[calculate], name="math_expert", ) # Create supervisor with forwarding tool forwarding_tool = create_forward_message_tool("supervisor") workflow = create_supervisor( agents=[research_agent, math_agent], model=model, tools=[forwarding_tool], # Add the forwarding tool prompt=( "You are a supervisor managing research and math experts. " "After getting a response from an agent, you can use forward_message " "to send their response directly to the user if it fully answers the question." ), ) app = workflow.compile() # When invoked, the supervisor can decide to forward a response result = app.invoke({ "messages": [ {"role": "user", "content": "What is 2 + 2?"} ] }) # The supervisor delegates to math_agent, and if satisfied with the response, # calls forward_message to send it directly to output ``` -------------------------------- ### Supervisor with Tuple (Prompt + Schema) Response Format Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/types.md Example of creating a supervisor with a custom prompt and a response schema (e.g., TypedDict or Pydantic model). The first element is the custom prompt string, and the second is the schema type. ```python from typing import TypedDict from pydantic import BaseModel from langgraph_supervisor import create_supervisor # TypedDict schema class Answer(TypedDict): text: str confidence: float # Tuple with custom prompt workflow4 = create_supervisor( agents=[agent1, agent2], model=model, response_format=( "Please format your response as JSON", Answer, ), ) ``` -------------------------------- ### Defensive Handoff Tool Creation Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/errors.md Use a try-except block when creating handoff tools to gracefully handle potential errors and fall back to auto-generation if tool creation fails. This prevents errors during supervisor setup. ```python from langgraph_supervisor import create_handoff_tool try: tools = [ create_handoff_tool(agent_name=agent.name) for agent in agents ] except Exception as e: print(f"Error creating handoff tools: {e}") # Fall back to auto-generation tools = None workflow = create_supervisor( agents=agents, model=model, tools=tools, # None triggers auto-generation ) ``` -------------------------------- ### Stream Supervisor Execution Results Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/examples.md This example demonstrates how to process supervisor output progressively using streaming. It's beneficial for long-running tasks where you want to display intermediate results to the user as they become available. ```python from langchain_openai import ChatOpenAI from langgraph.prebuilt import create_react_agent from langgraph_supervisor import create_supervisor model = ChatOpenAI(model="gpt-4o") research_agent = create_react_agent(model=model, tools=[], name="researcher") workflow = create_supervisor( agents=[research_agent], model=model, ) app = workflow.compile() # Stream results print("Streaming supervisor execution:") for event in app.stream( {"messages": [{"role": "user", "content": "Research something"}]}, mode="values", ): messages = event.get("messages", []) if messages: last_msg = messages[-1] if hasattr(last_msg, "name"): print(f"{last_msg.name}: {last_msg.content[:100]}") # Can also use astream for async ``` -------------------------------- ### Gradio Integration for UI Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/INDEX.md Create a simple chat interface using Gradio to interact with your LangGraph supervisor. This example sets up a `ChatInterface` that takes user messages and displays the model's responses. ```python import gradio as gr def chat(message, history): result = app.invoke({"messages": [{"role": "user", "content": message}]}) return result["messages"][-1].content gradio.ChatInterface(chat).launch() ``` -------------------------------- ### Supervisor Custom Prompt Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/quick_reference.md Provide a custom prompt to guide the supervisor's decision-making and task delegation. ```python # Custom prompt prompt="Detailed instructions for supervisor..." ``` -------------------------------- ### Integrate Handoff Tools with create_supervisor (Auto-generated) Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/create_handoff_tool.md Demonstrates creating a supervisor workflow where handoff tools are automatically generated based on the provided agent configurations. ```python from langgraph_supervisor import create_supervisor, create_handoff_tool from langgraph.prebuilt import create_react_agent model = ChatOpenAI(model="gpt-4o") research_agent = create_react_agent(..., name="research_expert") math_agent = create_react_agent(..., name="math_expert") # Option 1: Auto-generate handoff tools (default) workflow1 = create_supervisor( agents=[research_agent, math_agent], model=model, ) ``` -------------------------------- ### Supervisor Handoff Tool Naming Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/00_START_HERE.md Customize the naming convention for handoff tools to agents. This prefix is prepended to agent names, for example, 'delegate_to_agent1'. ```python # Customize handoff tool names handoff_tool_prefix="delegate_to_" # Creates "delegate_to_agent1" ``` -------------------------------- ### Type Hinting for Supervisor Configuration Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/quick_reference.md Demonstrates how to use type hints for supervisor configuration, including OutputMode and AgentNameMode. ```python from langgraph_supervisor import ( create_supervisor, create_handoff_tool, create_forward_message_tool, ) from langgraph_supervisor.supervisor import OutputMode from langgraph_supervisor.agent_name import AgentNameMode output_mode: OutputMode = "last_message" agent_name_mode: AgentNameMode = "inline" ``` -------------------------------- ### Integrate Memory with InMemorySaver Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/quick_reference.md This example shows how to add memory to a supervisor workflow using `InMemorySaver`. Conversations can be managed using `thread_id` in the invocation config. ```python from langgraph.checkpoint.memory import InMemorySaver checkpointer = InMemorySaver() workflow = create_supervisor( agents=[agent1, agent2], model=model, ) app = workflow.compile(checkpointer=checkpointer) # Use thread_id for conversations result = app.invoke( {"messages": [...]}, config={"configurable": {"thread_id": "user_123"}} ) ``` -------------------------------- ### Create Supervisor with String Prompt Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/types.md Illustrates the creation of a supervisor workflow using a simple string as the prompt. The string is automatically converted to a SystemMessage and prepended to the messages. ```python from langgraph_supervisor import create_supervisor # String prompt (simplest) workflow1 = create_supervisor( agents=[agent1, agent2], model=model, prompt="You manage two agents: agent1 and agent2.", ) ``` -------------------------------- ### Preprocess Messages Before Model Invocation Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/INDEX.md Implement a `pre_model_hook` function to preprocess messages before they are sent to the model. This example keeps only the last 20 messages in the conversation history. ```python def trim_messages(state): messages = state["messages"] return {"messages": messages[-20:]} # Keep last 20 workflow = create_supervisor( agents=[...], model=model, pre_model_hook=trim_messages, ) ``` -------------------------------- ### Create Supervisor with SystemMessage Prompt Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/types.md Shows how to initialize a supervisor with an explicit LangChain SystemMessage object for the prompt. This offers more control over message attributes compared to a plain string. ```python from langchain_core.messages import SystemMessage from langgraph_supervisor import create_supervisor # SystemMessage prompt (explicit) workflow2 = create_supervisor( agents=[agent1, agent2], model=model, prompt=SystemMessage(content="You manage two agents..."), ) ``` -------------------------------- ### Creating a Custom Handoff Tool Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/architecture.md Demonstrates how to create a specialized delegation tool using `create_handoff_tool`. This allows for custom logic when handing off tasks to other agents. ```python from langgraph_supervisor import create_handoff_tool tool = create_handoff_tool( agent_name="expert", name="delegate_with_context", description="Custom delegation logic", ) # Can override in Python with custom implementation ``` -------------------------------- ### Hierarchical Supervisor Organization Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/00_START_HERE.md Demonstrates creating a hierarchical structure where supervisors manage other supervisors. This example shows two teams ('team1', 'team2') managed by a top-level supervisor. ```python team1 = create_supervisor([agent1, agent2], ...).compile(name="team1") team2 = create_supervisor([agent3, agent4], ...).compile(name="team2") top = create_supervisor([team1, team2], ...).compile(name="top") ``` -------------------------------- ### Create Supervisor with Runnable Prompt Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/types.md Illustrates initializing a supervisor with a LangChain Runnable for the prompt. This allows for complex prompt engineering logic, such as chains or pipelines, to be used as the supervisor's instructions. ```python from langchain_core.runnables import RunnableLambda from langgraph_supervisor import create_supervisor # Runnable prompt (complex) prompt_chain = RunnableLambda(lambda state: f"Prompt: {state}") workflow4 = create_supervisor( agents=[agent1, agent2], model=model, prompt=prompt_chain, ) ``` -------------------------------- ### Create Supervisor Workflow Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/README.md Sets up a supervisor workflow using create_supervisor, which manages a list of agents. The supervisor's prompt defines how requests are routed to different agents based on their expertise. ```python # Create supervisor workflow workflow = create_supervisor( [research_agent, joke_agent], model=model, prompt=( "You are a team supervisor managing a research expert and a joke expert. " "For current events, use research_agent. " "For any jokes, use joke_agent." ) ) ``` -------------------------------- ### Question Routing with Supervisor Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/quick_reference.md Direct questions to specific agents based on their type using a custom prompt. This example routes math questions to 'math_agent' and research questions to 'research_agent'. ```python workflow = create_supervisor( agents=[research_agent, math_agent], model=model, prompt=""" Route questions appropriately: - Math questions → math_agent - Research questions → research_agent """, ) ``` -------------------------------- ### Inline Name Formatting Example Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/with_agent_name.md Demonstrates how agent names are embedded in message content using XML-style tags in 'inline' mode. This format is used before sending messages to the LLM. ```text agent_nameactual message content ``` -------------------------------- ### Integrate Handoff Tools with create_supervisor (Explicit Custom) Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/create_handoff_tool.md Shows how to explicitly define and pass custom handoff tools to the `create_supervisor` function for fine-grained control over agent communication. ```python from langgraph_supervisor import create_supervisor, create_handoff_tool from langgraph.prebuilt import create_react_agent model = ChatOpenAI(model="gpt-4o") research_agent = create_react_agent(..., name="research_expert") math_agent = create_react_agent(..., name="math_expert") # Option 2: Create custom handoff tools explicitly custom_tools = [ create_handoff_tool( agent_name="research_expert", name="ask_researcher", description="Ask the research specialist", ), create_handoff_tool( agent_name="math_expert", name="ask_mathematician", description="Ask the math specialist", ), ] workflow2 = create_supervisor( agents=[research_agent, math_agent], model=model, tools=custom_tools, ) ``` -------------------------------- ### Set Up Hierarchical Supervisors Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/quick_reference.md Demonstrates creating nested supervisors where top-level supervisors manage other supervisors. Each sub-supervisor is compiled with a name. ```python # Team 1 team1 = create_supervisor([agent1, agent2], model=model).compile(name="team1") # Team 2 team2 = create_supervisor([agent3, agent4], model=model).compile(name="team2") # Top level managing teams top = create_supervisor([team1, team2], model=model).compile() ``` -------------------------------- ### Providing All Handoff Tools in create_supervisor Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/errors.md If you customize handoff tools using the `tools` parameter in `create_supervisor`, ensure a tool is provided for every agent. Alternatively, omit the `tools` parameter to allow auto-generation. ```python from langgraph_supervisor import create_handoff_tool # Wrong - missing math_expert handoff tools = [ create_handoff_tool(agent_name="research_expert"), # Missing: create_handoff_tool(agent_name="math_expert") ] workflow = create_supervisor( agents=[research_agent, math_agent], model=model, tools=tools, # Error! ) # Correct - include all handoffs tools = [ create_handoff_tool(agent_name="research_expert"), create_handoff_tool(agent_name="math_expert"), ] workflow = create_supervisor( agents=[research_agent, math_agent], model=model, tools=tools, ) # Alternative - omit tools parameter for auto-generation workflow = create_supervisor( agents=[research_agent, math_agent], model=model, # No tools parameter - auto-generates all handoffs ) ``` -------------------------------- ### Create Custom Named and Described Handoff Tool Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/create_handoff_tool.md Creates a handoff tool with explicitly defined custom names and descriptions, allowing for more specific communication about the handoff purpose. ```python # Custom naming and descriptions custom_research = create_handoff_tool( agent_name="research_expert", name="delegate_to_researcher", description="Send this task to our research specialist for comprehensive investigation", ) custom_math = create_handoff_tool( agent_name="math_expert", name="calculate_with_math_bot", description="Hand off to our mathematical computation specialist", ) ``` -------------------------------- ### Create Supervisor and Compile Workflow Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/create_supervisor.md Instantiates a supervisor workflow and compiles it into a runnable graph. The compiled graph processes state with a 'messages' key. ```python workflow = create_supervisor([agent1, agent2], model=model) app = workflow.compile() # Returns a CompiledStateGraph ``` -------------------------------- ### Create Default Handoff Tool Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/create_handoff_tool.md Creates a handoff tool with default naming conventions based on the agent's name. The tool name will be 'transfer_to_' and the description will be 'Ask agent \'\' for help'. ```python from langgraph_supervisor import create_handoff_tool # Create a handoff tool with default naming research_handoff = create_handoff_tool(agent_name="research_expert") # Tool will be named: transfer_to_research_expert # Description: "Ask agent 'research_expert' for help" math_handoff = create_handoff_tool(agent_name="math_expert") # Tool will be named: transfer_to_math_expert ``` -------------------------------- ### Handling Agent Not Found in History Error Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/errors.md Illustrates how to guide the supervisor in prompts to avoid calling 'forward_message' with an agent name that has not yet produced a message. This helps prevent 'Agent Not Found in History' errors. ```python workflow = create_supervisor( agents=[agent1, agent2], model=model, tools=[create_forward_message_tool()], prompt=""" You can use forward_message to send an agent's response directly to the user. Use forward_message only after you've received a response from that agent. The agent name is case-sensitive. """, ) ``` -------------------------------- ### Use Type Hints for Supervisor Parameters Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/errors.md Leverage type hints for parameters like `output_mode` and `include_agent_name` to improve code clarity and catch potential type-related issues early. ```python from langgraph_supervisor.supervisor import OutputMode from langgraph_supervisor.agent_name import AgentNameMode def create_my_supervisor( agents: list, model, output_mode: OutputMode = "last_message", include_agent_name: AgentNameMode | None = None, ): return create_supervisor( agents=agents, model=model, output_mode=output_mode, include_agent_name=include_agent_name, ) ``` -------------------------------- ### Create Custom Handoff Tool Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/quick_reference.md Create a custom tool to explicitly delegate tasks to a specific agent. ```python from langgraph_supervisor import create_handoff_tool tools = [ create_handoff_tool( agent_name="agent1", name="call_agent_1", description="Delegate to agent 1", ), ] workflow = create_supervisor( agents=[agent1], model=model, tools=tools, ) ``` -------------------------------- ### Updating Supervisor Creation: config_schema to context_schema Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/errors.md Demonstrates the transition from the deprecated 'config_schema' parameter to the current 'context_schema' when creating a supervisor. Use 'context_schema' for consistency with LangGraph terminology. ```python # Old (deprecated) workflow = create_supervisor( agents=[agent1, agent2], model=model, config_schema=MySchema, ) # New workflow = create_supervisor( agents=[agent1, agent2], model=model, context_schema=MySchema, ) ``` -------------------------------- ### FastAPI Integration for Serving Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/INDEX.md Serve your LangGraph application using FastAPI by creating an API endpoint that accepts user messages and returns the supervisor's response. This example demonstrates a basic POST endpoint for invoking the compiled workflow. ```python from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() workflow = create_supervisor([...], model=model).compile() class Query(BaseModel): message: str @app.post("/ask") async def ask(query: Query): result = await workflow.ainvoke({ "messages": [{"role": "user", "content": query.message}] }) return {"response": result["messages"][-1].content} ``` -------------------------------- ### Use Custom Handoff Tool in Supervisor Source: https://github.com/langchain-ai/langgraph-supervisor-py/blob/main/_autodocs/create_handoff_tool.md Demonstrates integrating a custom-defined handoff tool, which includes additional arguments like task description, into a supervisor workflow. ```python from typing import Annotated from langchain_core.tools import tool, BaseTool, InjectedToolCallId from langchain_core.messages import ToolMessage from langgraph.prebuilt import InjectedState from langgraph.types import Command from langgraph_supervisor.handoff import METADATA_KEY_HANDOFF_DESTINATION from langgraph_supervisor import create_supervisor from langgraph.prebuilt import create_react_agent # Assume create_custom_handoff_tool is defined as above # Use the custom handoff tool custom_handoff = create_custom_handoff_tool( agent_name="research_expert", name="delegate_research_task", ) # Assume model, research_agent, math_agent are defined model = ChatOpenAI(model="gpt-4o") research_agent = create_react_agent(..., name="research_expert") math_agent = create_react_agent(..., name="math_expert") workflow = create_supervisor( agents=[research_agent, math_agent], model=model, tools=[custom_handoff, ...], # Include other handoff tools ) ```