Recreating DeerFlow’s Multi‑Agent Research Pipeline with LangGraphGo in 30 Minutes
This article walks through the open‑source DeerFlow framework—its multi‑agent architecture, core features, and a step‑by‑step implementation using the Go‑based LangGraphGo library, covering planner, researcher, reporter and podcast nodes, state‑graph design, CLI/web modes, and deployment instructions.
Overview
DeerFlow is an open‑source multi‑agent research framework released on 2025‑05‑10. It orchestrates a series of agents (Planner, Researcher, Reporter, optional Podcast) to automate the full research workflow from information gathering to final report generation.
Feature Analysis
Planner : Decomposes a user query into executable steps and creates a research plan.
Researcher : Executes each step using an LLM (currently the model’s internal knowledge base) and appends results to the state.
Reporter : Concatenates all research results, asks the LLM to produce Markdown, converts it to HTML via github.com/gomarkdown/markdown, and stores the final report.
Podcast (optional) : Generates a two‑host dialogue script from the research results and returns JSON plus an HTML snippet with styled speech bubbles.
Architecture Design
The workflow is defined as a LangGraph state graph where each agent corresponds to a node. The high‑level pipeline is:
用户查询 → 规划器 → 研究员 → 报告者 → (可选)播客 → 最终输出A conditional edge after the reporter checks GeneratePodcast to decide whether to invoke the podcast node.
State Definition
type State struct {
Request Request `json:"request"`
Plan []string `json:"plan"`
ResearchResults []string `json:"research_results"`
Images []string `json:"images"`
FinalReport string `json:"final_report"`
PodcastScript string `json:"podcast_script"`
GeneratePodcast bool `json:"generate_podcast"`
Step int `json:"step"`
}Graph Structure
// Core graph construction
workflow.AddNode("planner", "...", PlannerNode)
workflow.AddNode("researcher", "...", ResearcherNode)
workflow.AddNode("reporter", "...", ReporterNode)
workflow.AddNode("podcast", "...", PodcastNode)
// Conditional edge after reporter
workflow.AddConditionalEdge("reporter", func(ctx context.Context, state interface{}) string {
s := state.(*State)
if s.GeneratePodcast {
return "podcast"
}
return graph.END
})Agent Implementations
PlannerNode
Function : Accepts state.Request.Query, prompts the LLM to return a JSON‑encoded plan, and sets state.Plan and state.GeneratePodcast.
Robustness : If JSON parsing fails, falls back to line‑by‑line parsing and keyword detection for the podcast flag.
ResearcherNode
Function : Iterates over state.Plan, calls the LLM for each step with a “researcher” prompt, and appends the LLM’s response to state.ResearchResults. The current implementation uses the LLM’s internal knowledge base; state.Images remains nil.
ReporterNode
Function : Concatenates all state.ResearchResults, asks the LLM to produce Markdown, converts it to HTML via github.com/gomarkdown/markdown, and stores the result in state.FinalReport.
Image handling : Detects placeholders like [IMAGE_X:Title] and replaces them with <img src="..." alt="Title"> when image URLs are available.
PodcastNode
Function : Generates a two‑host dialogue script from the research results, returns JSON, and builds an HTML snippet with styled speech bubbles (Host 1 in blue, Host 2 in pink) plus an “Export JSON” button.
Application Entry & Interaction
CLI Mode
# Run a single query
./deerflow "Your research question"
# Example queries
./deerflow "What are the latest advances in quantum computing?"
./deerflow "Explain AI's impact on healthcare"
./deerflow "Current state of renewable energy"The CLI creates an initial state, invokes the graph, and prints the final HTML report to stdout.
Web Server Mode
Static assets : Embedded via Go’s embed package from the web/ directory.
API : /api/run triggers the graph using Server‑Sent Events (SSE) for real‑time progress; /api/history lists past queries.
Replay system : If a query has been run before, the server streams the stored log at 200 ms intervals to simulate instant results and save tokens.
Logging : logf writes to stdout and, when a channel is present, pushes logs to the SSE stream.
Key Utility Functions
logf: Dual‑purpose logger for CLI and web modes. getLLM: Wraps LLM initialization using langchaingo/llm (currently OpenAI/Doubao).
Compilation & Deployment
# Navigate to the DeerFlow showcase
cd showcases/deerflow
# Set environment variables
export OPENAI_API_KEY="your-api-key-here"
# Optional for other providers
export OPENAI_API_BASE="https://api.deepseek.com/v1"
export OPENAI_MODEL="deepseek-chat"
# Build the binary
go build -o deerflow .Running the Application
Web Interface (recommended)
# Start the server
./deerflow
# Open in a browser
http://localhost:8085Enter a research query.
Watch real‑time progress via SSE.
View the formatted HTML report.
Access research history and replay past queries.
Command‑Line Interface
# Basic usage
./deerflow "Your research question"Both interfaces produce the same final report; the web UI adds interactive replay and visualisation.
References
[1] langgraphgo – http://lango.rpcx.io
[2] deerflow showcase – https://github.com/smallnest/langgraphgo/tree/main/showcases/deerflow
BirdNest Tech Talk
Author of the rpcx microservice framework, original book author, and chair of Baidu's Go CMC committee.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
