Advanced Features
After mastering the basics, LangGraphGo provides a series of advanced features to help you build more complex, robust, and maintainable AI systems.
1. Parallel Execution
Background & Functionality
In many tasks, multiple steps can be performed simultaneously. For example, when writing an article, you can search for three different topics at the same time. Parallel execution can significantly reduce total latency.
Implementation Principle
LangGraphGo's runtime automatically detects parallel opportunities. If a node has multiple outgoing edges pointing to different nodes (Fan-out), or multiple nodes have no dependencies and all meet execution conditions, the runtime will execute them concurrently in Goroutines.
The results of concurrent execution need to be merged. This is why the Reducer in the State Schema is so important. The Reducer defines how to safely merge partial states generated concurrently into the main state.
Code Showcase
// Simple Fan-out pattern
g.AddEdge("start", "search_topic_a")
g.AddEdge("start", "search_topic_b")
g.AddEdge("start", "search_topic_c")
// Fan-in pattern: aggregate results after all searches complete
g.AddEdge("search_topic_a", "aggregator")
g.AddEdge("search_topic_b", "aggregator")
g.AddEdge("search_topic_c", "aggregator")
// Runtime will automatically execute search_topic_a, b, c in parallel
// aggregator will only execute when they are all done (or based on specific logic)
2. Subgraphs
Background & Functionality
As applications grow complex, a single large graph becomes hard to manage. Subgraphs allow you to modularize your graph. You can call another compiled graph just like calling a normal node.
This not only helps with code organization but also supports multi-agent collaboration patterns, where each agent is an independent subgraph.
Implementation Principle
A compiled graph (CompiledGraph) implements the same interface as a node function (accepts
Context and State, returns State). Therefore, it can be directly added as a node to a parent graph.
Note that the State Schema of the parent graph and subgraph need to be compatible, or conversion is needed.
Code Showcase
// 1. Define subgraph (Researcher Agent)
researchGraph := graph.NewStateGraph(...)
// ... Build researchGraph ...
researchRunnable := researchGraph.Compile()
// 2. Define parent graph (Main Assistant)
mainGraph := graph.NewStateGraph(...)
// 3. Add subgraph as a node to parent graph
mainGraph.AddNode("research_agent", researchRunnable)
// 4. Define flow
mainGraph.AddEdge("classify_input", "research_agent")
3. Visualization
Background & Functionality
"A picture is worth a thousand words". For complex logic graphs, code is often less intuitive than diagrams. LangGraphGo has built-in Mermaid.js format export, allowing you to see the graph structure directly.
Implementation Principle
The graph object traverses its internal node and edge structure to generate a string description conforming to Mermaid syntax.
Code Showcase
exporter := graph.NewExporter(g)
mermaidChart := exporter.DrawMermaid()
fmt.Println(mermaidChart)
// Output example:
// graph TD
// start --> node_a
// node_a --> node_b
// ...
You can copy the output to Mermaid Live Editor to view the chart.
4. Runtime Configuration
Background & Functionality
Without changing graph structure and code, we often need to adjust runtime behavior. For example, using different LLM models for different users, or passing a User ID for logging.
The Config object provides a standard way to pass this metadata.
Implementation Principle
The Config object is passed in the graph execution context. Any node can access the current
configuration via graph.GetConfig(ctx).
Code Showcase
// Pass config when invoking
config := &graph.Config{
Configurable: map[string]interface{}{
"user_id": "123",
"model": "gpt-4",
},
}
runnable.InvokeWithConfig(ctx, input, config)
// Access config in node
func myNode(ctx context.Context, state interface{}) (interface{}, error) {
config := graph.GetConfig(ctx)
userID := config.Configurable["user_id"]
// ...
}