Choosing Between Graph and Functional APIs
Status: ACTIVE (pulled from docs.langchain.com) Source: https://docs.langchain.com/oss/python/langgraph/choosing-apis Timestamp: 2026-05-11
LangGraph offers two APIs for building agents. They share the same underlying runtime (Pregel) and can be used together.
Quick Decision
| Use Graph API if... | Use Functional API if... |
|---|---|
| You want explicit control over graph topology | You want to add persistence to existing code |
| You need to visualize the agent as a graph | You prefer function-based mental model |
| You're building complex, multi-branch workflows | Your workflow is a linear sequence with conditionals |
| You want node-level retries, timeouts, caching | You want minimal boilerplate |
Comparison
| Aspect | Graph API | Functional API |
|---|---|---|
| Mental model | Nodes + Edges = Graph | Functions calling functions |
| State definition | Explicit TypedDict/dataclass | Inferred from function signatures |
| Routing | add_edge / add_conditional_edges / Command | Standard if/else/while |
| Parallelism | Add edges from one node to multiple | Call tasks and collect futures |
| Subgraphs | add_node("name", compiled_subgraph) | Call graph.invoke() inside entrypoint |
| Streaming | stream_mode parameter | stream_mode parameter + get_stream_writer() |
| Visualization | get_graph().draw_mermaid_png() | No graph visualization |
| Persistence | compile(checkpointer=...) | @entrypoint(checkpointer=...) |
| Retries | add_node(retry_policy=...) | @task(retry_policy=...) |
Can Mix Both
from langgraph.func import entrypoint
from langgraph.graph import StateGraph
builder = StateGraph(...)
some_graph = builder.compile()
@entrypoint()
def my_workflow(inputs: dict) -> int:
result = some_graph.invoke(inputs)
return result
Migration
Both APIs share the Pregel runtime. You can: - Start with Functional API for speed - Extract complex sections into a Graph API subgraph later - Call Graph API graphs from Functional API entrypoints
There's no lock-in -- choose per-component.