{"id":25771851,"url":"https://github.com/langchain-ai/langgraph-supervisor-py","last_synced_at":"2025-05-15T07:07:36.239Z","repository":{"id":276690964,"uuid":"927970248","full_name":"langchain-ai/langgraph-supervisor-py","owner":"langchain-ai","description":null,"archived":false,"fork":false,"pushed_at":"2025-05-14T18:52:28.000Z","size":632,"stargazers_count":858,"open_issues_count":5,"forks_count":133,"subscribers_count":15,"default_branch":"main","last_synced_at":"2025-05-14T19:47:12.324Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/langchain-ai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-02-05T20:56:08.000Z","updated_at":"2025-05-14T18:53:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"3af0a83e-92a6-4c31-85e9-b89985c31b97","html_url":"https://github.com/langchain-ai/langgraph-supervisor-py","commit_stats":null,"previous_names":["langchain-ai/langgraph-supervisor","langchain-ai/langgraph-supervisor-py"],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/langchain-ai%2Flanggraph-supervisor-py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/langchain-ai%2Flanggraph-supervisor-py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/langchain-ai%2Flanggraph-supervisor-py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/langchain-ai%2Flanggraph-supervisor-py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/langchain-ai","download_url":"https://codeload.github.com/langchain-ai/langgraph-supervisor-py/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254292043,"owners_count":22046426,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-27T03:10:54.495Z","updated_at":"2025-05-15T07:07:31.185Z","avatar_url":"https://github.com/langchain-ai.png","language":"Python","funding_links":[],"categories":["🟢 Official LangGraph Projects 🦜"],"sub_categories":["🟩 Specialized Agent Libraries 🤖"],"readme":"# 🤖 LangGraph Multi-Agent Supervisor\n\nA Python library for creating hierarchical multi-agent systems using [LangGraph](https://github.com/langchain-ai/langgraph). Hierarchical systems are a type of [multi-agent](https://langchain-ai.github.io/langgraph/concepts/multi_agent) architecture where specialized agents are coordinated by a central **supervisor** agent. The supervisor controls all communication flow and task delegation, making decisions about which agent to invoke based on the current context and task requirements.\n\n## Features\n\n- 🤖 **Create a supervisor agent** to orchestrate multiple specialized agents\n- 🛠️ **Tool-based agent handoff mechanism** for communication between agents\n- 📝 **Flexible message history management** for conversation control\n\nThis library is built on top of [LangGraph](https://github.com/langchain-ai/langgraph), a powerful framework for building agent applications, and comes with out-of-box support for [streaming](https://langchain-ai.github.io/langgraph/how-tos/#streaming), [short-term and long-term memory](https://langchain-ai.github.io/langgraph/concepts/memory/) and [human-in-the-loop](https://langchain-ai.github.io/langgraph/concepts/human_in_the_loop/)\n\n## Installation\n\n```bash\npip install langgraph-supervisor\n```\n\n\u003e [!Note]\n\u003e LangGraph Supervisor requires Python \u003e= 3.10\n\n## Quickstart\n\nHere's a simple example of a supervisor managing two specialized agents:\n\n![Supervisor Architecture](static/img/supervisor.png)\n\n```bash\npip install langgraph-supervisor langchain-openai\n\nexport OPENAI_API_KEY=\u003cyour_api_key\u003e\n```\n\n```python\nfrom langchain_openai import ChatOpenAI\n\nfrom langgraph_supervisor import create_supervisor\nfrom langgraph.prebuilt import create_react_agent\n\nmodel = ChatOpenAI(model=\"gpt-4o\")\n\n# Create specialized agents\n\ndef add(a: float, b: float) -\u003e float:\n    \"\"\"Add two numbers.\"\"\"\n    return a + b\n\ndef multiply(a: float, b: float) -\u003e float:\n    \"\"\"Multiply two numbers.\"\"\"\n    return a * b\n\ndef web_search(query: str) -\u003e str:\n    \"\"\"Search the web for information.\"\"\"\n    return (\n        \"Here are the headcounts for each of the FAANG companies in 2024:\\n\"\n        \"1. **Facebook (Meta)**: 67,317 employees.\\n\"\n        \"2. **Apple**: 164,000 employees.\\n\"\n        \"3. **Amazon**: 1,551,000 employees.\\n\"\n        \"4. **Netflix**: 14,000 employees.\\n\"\n        \"5. **Google (Alphabet)**: 181,269 employees.\"\n    )\n\nmath_agent = create_react_agent(\n    model=model,\n    tools=[add, multiply],\n    name=\"math_expert\",\n    prompt=\"You are a math expert. Always use one tool at a time.\"\n)\n\nresearch_agent = create_react_agent(\n    model=model,\n    tools=[web_search],\n    name=\"research_expert\",\n    prompt=\"You are a world class researcher with access to web search. Do not do any math.\"\n)\n\n# Create supervisor workflow\nworkflow = create_supervisor(\n    [research_agent, math_agent],\n    model=model,\n    prompt=(\n        \"You are a team supervisor managing a research expert and a math expert. \"\n        \"For current events, use research_agent. \"\n        \"For math problems, use math_agent.\"\n    )\n)\n\n# Compile and run\napp = workflow.compile()\nresult = app.invoke({\n    \"messages\": [\n        {\n            \"role\": \"user\",\n            \"content\": \"what's the combined headcount of the FAANG companies in 2024?\"\n        }\n    ]\n})\n```\n\n## Message History Management\n\nYou can control how agent messages are added to the overall conversation history of the multi-agent system:\n\nInclude full message history from an agent:\n\n![Full History](static/img/full_history.png)\n\n```python\nworkflow = create_supervisor(\n    agents=[agent1, agent2],\n    output_mode=\"full_history\"\n)\n```\n\nInclude only the final agent response:\n\n![Last Message](static/img/last_message.png)\n\n```python\nworkflow = create_supervisor(\n    agents=[agent1, agent2],\n    output_mode=\"last_message\"\n)\n```\n\n## Multi-level Hierarchies\n\nYou can create multi-level hierarchical systems by creating a supervisor that manages multiple supervisors.\n\n```python\nresearch_team = create_supervisor(\n    [research_agent, math_agent],\n    model=model,\n    supervisor_name=\"research_supervisor\"\n).compile(name=\"research_team\")\n\nwriting_team = create_supervisor(\n    [writing_agent, publishing_agent],\n    model=model,\n    supervisor_name=\"writing_supervisor\"\n).compile(name=\"writing_team\")\n\ntop_level_supervisor = create_supervisor(\n    [research_team, writing_team],\n    model=model,\n    supervisor_name=\"top_level_supervisor\"\n).compile(name=\"top_level_supervisor\")\n```\n\n## Adding Memory\n\nYou can add [short-term](https://langchain-ai.github.io/langgraph/how-tos/persistence/) and [long-term](https://langchain-ai.github.io/langgraph/how-tos/cross-thread-persistence/) [memory](https://langchain-ai.github.io/langgraph/concepts/memory/) to your supervisor multi-agent system. Since `create_supervisor()` returns an instance of `StateGraph` that needs to be compiled before use, you can directly pass a [checkpointer](https://langchain-ai.github.io/langgraph/reference/checkpoints/#langgraph.checkpoint.base.BaseCheckpointSaver) or a [store](https://langchain-ai.github.io/langgraph/reference/store/#langgraph.store.base.BaseStore) instance to the `.compile()` method:\n\n```python\nfrom langgraph.checkpoint.memory import InMemorySaver\nfrom langgraph.store.memory import InMemoryStore\n\ncheckpointer = InMemorySaver()\nstore = InMemoryStore()\n\nmodel = ...\nresearch_agent = ...\nmath_agent = ...\n\nworkflow = create_supervisor(\n    [research_agent, math_agent],\n    model=model,\n    prompt=\"You are a team supervisor managing a research expert and a math expert.\",\n)\n\n# Compile with checkpointer/store\napp = workflow.compile(\n    checkpointer=checkpointer,\n    store=store\n)\n```\n\n## How to customize\n\n### Customizing handoff tools\n\nBy default, the supervisor uses handoff tools created with the prebuilt `create_handoff_tool`. You can also create your own, custom handoff tools. Here are some ideas on how you can modify the default implementation:\n\n* change tool name and/or description\n* add tool call arguments for the LLM to populate, for example a task description for the next agent\n* change what data is passed to the subagent as part of the handoff: by default `create_handoff_tool` passes **full** message history (all of the messages generated in the supervisor up to this point), as well as a tool message indicating successful handoff.\n\nHere is an example of how to pass customized handoff tools to `create_supervisor`:\n\n```python\nfrom langgraph_supervisor import create_handoff_tool\nworkflow = create_supervisor(\n    [research_agent, math_agent],\n    tools=[\n        create_handoff_tool(agent_name=\"math_expert\", name=\"assign_to_math_expert\", description=\"Assign task to math expert\"),\n        create_handoff_tool(agent_name=\"research_expert\", name=\"assign_to_research_expert\", description=\"Assign task to research expert\")\n    ],\n    model=model,\n)\n```\n\nHere is an example of what a custom handoff tool might look like:\n\n```python\nfrom typing import Annotated\n\nfrom langchain_core.tools import tool, BaseTool, InjectedToolCallId\nfrom langchain_core.messages import ToolMessage\nfrom langgraph.types import Command\nfrom langgraph.prebuilt import InjectedState\n\ndef create_custom_handoff_tool(*, agent_name: str, name: str | None, description: str | None) -\u003e BaseTool:\n\n    @tool(name, description=description)\n    def handoff_to_agent(\n        # you can add additional tool call arguments for the LLM to populate\n        # for example, you can ask the LLM to populate a task description for the next agent\n        task_description: Annotated[str, \"Detailed description of what the next agent should do, including all of the relevant context.\"],\n        # you can inject the state of the agent that is calling the tool\n        state: Annotated[dict, InjectedState],\n        tool_call_id: Annotated[str, InjectedToolCallId],\n    ):\n        tool_message = ToolMessage(\n            content=f\"Successfully transferred to {agent_name}\",\n            name=name,\n            tool_call_id=tool_call_id,\n        )\n        messages = state[\"messages\"]\n        return Command(\n            goto=agent_name,\n            graph=Command.PARENT,\n            # NOTE: this is a state update that will be applied to the swarm multi-agent graph (i.e., the PARENT graph)\n            update={\n                \"messages\": messages + [tool_message],\n                \"active_agent\": agent_name,\n                # optionally pass the task description to the next agent\n                # NOTE: individual agents would need to have `task_description` in their state schema\n                # and would need to implement logic for how to consume it\n                \"task_description\": task_description,\n            },\n        )\n\n    return handoff_to_agent\n```\n\n## Using Functional API \n\nHere's a simple example of a supervisor managing two specialized agentic workflows created using Functional API:\n\n```bash\npip install langgraph-supervisor langchain-openai\n\nexport OPENAI_API_KEY=\u003cyour_api_key\u003e\n```\n\n```python\nfrom langgraph.prebuilt import create_react_agent\nfrom langgraph_supervisor import create_supervisor\n\nfrom langchain_openai import ChatOpenAI\n\nfrom langgraph.func import entrypoint, task\nfrom langgraph.graph import add_messages\n\nmodel = ChatOpenAI(model=\"gpt-4o\")\n\n# Create specialized agents\n\n# Functional API - Agent 1 (Joke Generator)\n@task\ndef generate_joke(messages):\n    \"\"\"First LLM call to generate initial joke\"\"\"\n    system_message = {\n        \"role\": \"system\", \n        \"content\": \"Write a short joke\"\n    }\n    msg = model.invoke(\n        [system_message] + messages\n    )\n    return msg\n\n@entrypoint()\ndef joke_agent(state):\n    joke = generate_joke(state['messages']).result()\n    messages = add_messages(state[\"messages\"], [joke])\n    return {\"messages\": messages}\n\njoke_agent.name = \"joke_agent\"\n\n# Graph API - Agent 2 (Research Expert)\ndef web_search(query: str) -\u003e str:\n    \"\"\"Search the web for information.\"\"\"\n    return (\n        \"Here are the headcounts for each of the FAANG companies in 2024:\\n\"\n        \"1. **Facebook (Meta)**: 67,317 employees.\\n\"\n        \"2. **Apple**: 164,000 employees.\\n\"\n        \"3. **Amazon**: 1,551,000 employees.\\n\"\n        \"4. **Netflix**: 14,000 employees.\\n\"\n        \"5. **Google (Alphabet)**: 181,269 employees.\"\n    )\n\nresearch_agent = create_react_agent(\n    model=model,\n    tools=[web_search],\n    name=\"research_expert\",\n    prompt=\"You are a world class researcher with access to web search. Do not do any math.\"\n)\n\n# Create supervisor workflow\nworkflow = create_supervisor(\n    [research_agent, joke_agent],\n    model=model,\n    prompt=(\n        \"You are a team supervisor managing a research expert and a joke expert. \"\n        \"For current events, use research_agent. \"\n        \"For any jokes, use joke_agent.\"\n    )\n)\n\n# Compile and run\napp = workflow.compile()\nresult = app.invoke({\n    \"messages\": [\n        {\n            \"role\": \"user\",\n            \"content\": \"Share a joke to relax and start vibe coding for my next project idea.\"\n        }\n    ]\n})\n\nfor m in result[\"messages\"]:\n    m.pretty_print()\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flangchain-ai%2Flanggraph-supervisor-py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flangchain-ai%2Flanggraph-supervisor-py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flangchain-ai%2Flanggraph-supervisor-py/lists"}