Principle:Langchain ai Langgraph Remote Client Connection
| Property | Value |
|---|---|
| Concept | Connecting to a Deployed LangGraph API Server from Client Applications |
| Category | Client-Server Communication |
| Scope | CLI Deployment Workflow |
| Related Workflow | CLI_Deployment |
Overview
Remote Client Connection in LangGraph enables client applications to interact with a deployed LangGraph API server as if the graph were running locally. The `RemoteGraph` class provides a drop-in replacement for a local graph, implementing the same `PregelProtocol` interface (invoke, stream, get_state, update_state) while transparently routing operations over HTTP to the remote API. The `get_client` function from the SDK creates lower-level HTTP clients for direct API access. Together, these abstractions bridge the gap between local graph development and remote graph execution.
Description
Client-Server Pattern
LangGraph's deployment architecture follows a client-server pattern where:
- The server runs one or more graphs behind the LangGraph API (deployed via `langgraph up` or `langgraph build` + Docker).
- The client connects to the server's HTTP endpoints to execute graphs, manage threads, inspect state, and stream results.
This separation enables:
- Scalability: The server can be scaled independently of client applications.
- Language independence: Clients in any language can interact with the API (Python SDK, JS/TS SDK, raw HTTP).
- Deployment flexibility: The same client code works against local development servers, staging deployments, and production instances.
RemoteGraph Abstraction
The `RemoteGraph` class (`libs/langgraph/langgraph/pregel/remote.py`) implements the `PregelProtocol`, providing the same interface as a local compiled graph:
- `invoke(input, config)`: Create a run, wait for completion, and return the final state.
- `stream(input, config, stream_mode)`: Create a run and stream results in real-time.
- `get_state(config)`: Retrieve the current state of a thread.
- `update_state(config, values)`: Update the state of a thread.
- `get_state_history(config)`: Retrieve the state history of a thread.
- `get_graph()`: Retrieve the graph topology for visualization.
This means a `RemoteGraph` can be used directly as a node in another graph, enabling composition of local and remote graphs in a single workflow.
API Abstraction
The `get_client` function from `langgraph_sdk` creates a `LangGraphClient` that provides structured access to the LangGraph API endpoints:
- `client.assistants`: Manage graph versions and configurations.
- `client.threads`: Create and manage conversation threads.
- `client.runs`: Execute graph invocations with full streaming support.
- `client.crons`: Schedule recurring graph executions.
- `client.store`: Access persistent key-value storage.
The client handles authentication (API key from environment variables or explicit parameter), request serialization, response parsing, and error handling.
Authentication
API keys are resolved in the following order:
- Explicit `api_key` parameter.
- `LANGGRAPH_API_KEY` environment variable.
- `LANGSMITH_API_KEY` environment variable.
- `LANGCHAIN_API_KEY` environment variable.
Distributed Tracing
When `distributed_tracing=True` is set on `RemoteGraph`, LangSmith tracing headers are automatically injected into API requests. This enables end-to-end tracing across client and server, linking the calling graph's trace with the remote graph's execution trace for comprehensive observability.
In-Process Connection
When `url=None` is passed to `get_client`, the SDK attempts to connect in-process via ASGI transport to the co-located LangGraph API server. This enables subgraph calls within a deployed server to communicate directly without network overhead.
Usage
Connecting to a Deployed Server
from langgraph.pregel.remote import RemoteGraph
# Create a remote graph client
remote = RemoteGraph(
"my_agent",
url="http://localhost:8123",
api_key="your-api-key",
)
# Use like a local graph
result = remote.invoke({"messages": [{"role": "user", "content": "Hello!"}]})
Streaming from a Remote Graph
from langgraph.pregel.remote import RemoteGraph
remote = RemoteGraph("my_agent", url="http://localhost:8123")
config = {"configurable": {"thread_id": "thread-1"}}
for chunk in remote.stream(
{"messages": [{"role": "user", "content": "What is the weather?"}]},
config=config,
stream_mode="updates",
):
print(chunk)
Using the SDK Client Directly
from langgraph_sdk import get_client
client = get_client(url="http://localhost:8123")
# Create a thread
thread = await client.threads.create()
# Run a graph on the thread
result = await client.runs.wait(
thread_id=thread["thread_id"],
assistant_id="my_agent",
input={"messages": [{"role": "user", "content": "Hello!"}]},
)
Theoretical Basis
Remote Graph Execution
Remote graph execution distributes computation across process and machine boundaries while maintaining a uniform programming model. The `RemoteGraph` class implements the Proxy pattern, where the local object delegates all operations to the remote server. This transparency enables developers to compose local and remote graphs without changing their code.
Client-Server Architecture
The LangGraph client-server architecture follows REST principles for stateless request handling, with server-sent events (SSE) for streaming. The API design separates resource management (threads, assistants) from execution (runs, streams), enabling flexible client usage patterns.
API Abstraction
The SDK client provides a type-safe, method-based interface over the raw HTTP API. This abstraction hides the complexity of request serialization (via `orjson`), authentication header management, error handling, and SSE stream parsing. The client also supports both synchronous and asynchronous operation via separate `SyncLangGraphClient` and `LangGraphClient` implementations.
Distributed Tracing
Distributed tracing propagates trace context across service boundaries using the W3C Trace Context standard (via baggage and traceparent headers). When enabled on `RemoteGraph`, the LangSmith run tree headers are injected into API requests, allowing the remote server to associate its execution traces with the caller's trace. This provides complete visibility into multi-service graph execution flows.