← All blueprints

Deep Research LangGraph

blueprint · 5 agents · 1 MCP server
1755★ stars
254forks
4.8rating

What it does

A planner splits a broad question into focused sub-questions. Several searchers research them in parallel so the wall-clock stays low. A synthesizer merges the findings, removes overlap, resolves contradictions, and writes a brief with citations back to the sources. For questions a single search cannot answer. Point the searchers at your own search or retrieval server.

The cast · 5 agents

Plannerplannerreasoning

Break the question into focused, non-overlapping sub-questions that together cover it. Assign them across three lanes as evenly as you can. Do not research yet.

no tools · reasoning only
Searcher AsearcherAfast

Research the sub-questions in your assigned lane. Report findings with a source for each claim. Do not stray into the other lanes.

search.web
Searcher BsearcherBfast

Research the sub-questions in your assigned lane. Report findings with a source for each claim. Do not stray into the other lanes.

search.web
Searcher CsearcherCfast

Research the sub-questions in your assigned lane. Report findings with a source for each claim. Do not stray into the other lanes.

search.web
Synthesizersynthesizerreasoning

Merge the three lanes' findings into one brief. Remove overlap, resolve contradictions by weighing sources, and cite a source for every claim. Note anything the research could not settle.

no tools · reasoning only

Flow

Plannersubquestions
⇉ parallel
Searcher AfindingsA
Searcher BfindingsB
Searcher CfindingsC
Synthesizerbrief

Interface

Inputs
questionstring
The broad question to research.
Outputs
briefstring
A synthesized brief with citations.

Depends on · 1 MCP server

io.github.brave/brave-search-mcpnot in the registry yetsearch
⤓ Export runnable code
# Generated by @socketcat/compiler for target: langgraph
# blueprint: com.socketcat/deep-research v1.0.0   schema: socketcat.dev/blueprint/v0
# This code is yours. Edit it freely. The socketcat_runtime helper is optional and can be vendored.

from typing import TypedDict
from langgraph.graph import StateGraph, START, END
import socketcat_runtime as _rt

class State(TypedDict, total=False):
    question: object
    brief: object
    subquestions: object
    findingsA: object
    findingsB: object
    findingsC: object

def node_AgentInvoke_0(state):
    return _rt.run_agent("planner", state, {"question":"question"}, "subquestions")

def node_Fork_1(state):
    return {}

def node_Join_2(state):
    return {}

def node_AgentInvoke_3(state):
    return _rt.run_agent("searcherA", state, {"subquestions":"subquestions"}, "findingsA")

def node_AgentInvoke_4(state):
    return _rt.run_agent("searcherB", state, {"subquestions":"subquestions"}, "findingsB")

def node_AgentInvoke_5(state):
    return _rt.run_agent("searcherC", state, {"subquestions":"subquestions"}, "findingsC")

def node_AgentInvoke_6(state):
    return _rt.run_agent("synthesizer", state, {"findingsA":"findingsA","findingsB":"findingsB","findingsC":"findingsC"}, "brief")

def build():
    b = StateGraph(State)
    b.add_node("AgentInvoke_0", node_AgentInvoke_0)
    b.add_node("Fork_1", node_Fork_1)
    b.add_node("Join_2", node_Join_2)
    b.add_node("AgentInvoke_3", node_AgentInvoke_3)
    b.add_node("AgentInvoke_4", node_AgentInvoke_4)
    b.add_node("AgentInvoke_5", node_AgentInvoke_5)
    b.add_node("AgentInvoke_6", node_AgentInvoke_6)
    b.add_edge(START, "AgentInvoke_0")
    b.add_edge("AgentInvoke_0", "Fork_1")
    b.add_edge("Fork_1", "AgentInvoke_3")
    b.add_edge("Fork_1", "AgentInvoke_4")
    b.add_edge("Fork_1", "AgentInvoke_5")
    b.add_edge("Join_2", "AgentInvoke_6")
    b.add_edge("AgentInvoke_3", "Join_2")
    b.add_edge("AgentInvoke_4", "Join_2")
    b.add_edge("AgentInvoke_5", "Join_2")
    b.add_edge("AgentInvoke_6", END)
    return b.compile()

INPUTS = ["question"]
OUTPUTS = ["brief"]

if __name__ == "__main__":
    _rt.main(build, INPUTS, OUTPUTS)
blueprint.json (the portable format)
{
  "id": "com.socketcat/deep-research",
  "flow": {
    "type": "sequence",
    "blocks": [
      {
        "in": {
          "question": "question"
        },
        "out": "subquestions",
        "use": "planner",
        "type": "agent"
      },
      {
        "type": "parallel",
        "blocks": [
          {
            "in": {
              "subquestions": "subquestions"
            },
            "out": "findingsA",
            "use": "searcherA",
            "type": "agent"
          },
          {
            "in": {
              "subquestions": "subquestions"
            },
            "out": "findingsB",
            "use": "searcherB",
            "type": "agent"
          },
          {
            "in": {
              "subquestions": "subquestions"
            },
            "out": "findingsC",
            "use": "searcherC",
            "type": "agent"
          }
        ]
      },
      {
        "in": {
          "findingsA": "findingsA",
          "findingsB": "findingsB",
          "findingsC": "findingsC"
        },
        "out": "brief",
        "use": "synthesizer",
        "type": "agent"
      }
    ]
  },
  "tags": [
    "research",
    "parallel",
    "citations",
    "synthesis"
  ],
  "title": "Deep Research",
  "agents": {
    "planner": {
      "model": {
        "hint": "reasoning"
      },
      "title": "Planner",
      "instructions": "Break the question into focused, non-overlapping sub-questions that together cover it. Assign them across three lanes as evenly as you can. Do not research yet."
    },
    "searcherA": {
      "model": {
        "hint": "fast"
      },
      "title": "Searcher A",
      "tools": [
        "search.web"
      ],
      "instructions": "Research the sub-questions in your assigned lane. Report findings with a source for each claim. Do not stray into the other lanes."
    },
    "searcherB": {
      "model": {
        "hint": "fast"
      },
      "title": "Searcher B",
      "tools": [
        "search.web"
      ],
      "instructions": "Research the sub-questions in your assigned lane. Report findings with a source for each claim. Do not stray into the other lanes."
    },
    "searcherC": {
      "model": {
        "hint": "fast"
      },
      "title": "Searcher C",
      "tools": [
        "search.web"
      ],
      "instructions": "Research the sub-questions in your assigned lane. Report findings with a source for each claim. Do not stray into the other lanes."
    },
    "synthesizer": {
      "model": {
        "hint": "reasoning"
      },
      "title": "Synthesizer",
      "instructions": "Merge the three lanes' findings into one brief. Remove overlap, resolve contradictions by weighing sources, and cite a source for every claim. Note anything the research could not settle."
    }
  },
  "estate": {
    "findingsA": {
      "type": "object",
      "description": "First searcher's findings."
    },
    "findingsB": {
      "type": "object",
      "description": "Second searcher's findings."
    },
    "findingsC": {
      "type": "object",
      "description": "Third searcher's findings."
    },
    "subquestions": {
      "type": "array",
      "description": "The planner's focused sub-questions."
    }
  },
  "$schema": "socketcat.dev/blueprint/v0",
  "authors": [
    {
      "url": "https://socketcat.com",
      "name": "SocketCat"
    }
  ],
  "license": "MIT",
  "servers": [
    {
      "ref": "io.github.brave/brave-search-mcp",
      "alias": "search"
    }
  ],
  "summary": "Plans sub-questions, researches them in parallel, and synthesizes a single cited brief.",
  "targets": [
    "langgraph",
    "*"
  ],
  "version": "1.0.0",
  "interface": {
    "inputs": {
      "question": {
        "type": "string",
        "description": "The broad question to research."
      }
    },
    "outputs": {
      "brief": {
        "type": "string",
        "description": "A synthesized brief with citations."
      }
    }
  },
  "extensions": {
    "dev.langgraph": {
      "checkpointer": "memory"
    }
  },
  "description": "A planner splits a broad question into focused sub-questions. Several searchers research them in parallel so the wall-clock stays low. A synthesizer merges the findings, removes overlap, resolves contradictions, and writes a brief with citations back to the sources. For questions a single search cannot answer. Point the searchers at your own search or retrieval server."
}

More in Core patterns

Browse all →

Supervisor Team

com.socketcat/supervisor-team
LangGraph

A supervisor decides who works next — a researcher who searches or a coder who edits the repo — and assembles the result when the work is done.

21402 servers
312

Agentic RAG

com.socketcat/agentic-rag
LangGraph

Retrieval that doesn't trust its first search: it grades the results, rewrites the query when they're weak, and only answers once the context is good.

16801 server
241

Plan and Execute

com.socketcat/plan-and-execute
LangGraph

A planner breaks a goal into steps, an executor works them one at a time, and a replanner adjusts the plan as reality comes back — until it's done.

14902 servers
208