---
title: "Coordinate LangChain Agents with NoLag"
description: Use NoLag as the coordination layer for LangChain agents. Dispatch tasks to workers, collect results, and keep a human in the loop, over realtime pub/sub.
excerpt: "LangChain builds the agent; NoLag coordinates many of them. Here is how to dispatch tasks to LangChain workers and collect results over realtime pub/sub."
date: '2026-08-02'
readTime: 8 min read
category: Integration
---

LangChain is excellent at building a single agent: prompts, tools, memory, and chains. What it does not give you is the layer above a single agent, where several agents and humans coordinate: dispatching work, sharing state, and gating actions. That is what NoLag provides. This guide connects a LangChain worker to a NoLag room so you can fan work out and collect results in realtime.

## The shape

- A **dispatcher** publishes tasks to a `tasks` topic.
- One or more **workers**, each wrapping a LangChain chain, subscribe to `tasks`, run the chain, and publish to `results`.
- Anything can watch `results`: a UI, a supervisor agent, or a human.

Because it is pub/sub, you add workers by starting more subscribers. No queue to run, no orchestration server to operate.

## 1. Install

```bash
pip install nolag langchain langchain-openai
```

## 2. A LangChain worker on a NoLag room

```python
import asyncio
from nolag import NoLag
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

# Build the LangChain agent (a simple summariser here)
llm = ChatOpenAI(model="gpt-4o-mini")
prompt = ChatPromptTemplate.from_template("Summarise this in one sentence:\n\n{input}")
chain = prompt | llm

async def main():
    client = NoLag("your_access_token")
    await client.connect()

    room = client.set_app("agents").set_room("workflow")
    await room.subscribe("tasks")

    def on_task(data, meta):
        async def run():
            result = await chain.ainvoke({"input": data["input"]})
            await room.emit("results", {
                "task_id": data["task_id"],
                "output": result.content,
            })
        asyncio.create_task(run())

    room.on("tasks", on_task)

    # Keep the worker alive
    await asyncio.Event().wait()

asyncio.run(main())
```

Start this process on as many machines as you like. Each instance is another worker pulling from the same `tasks` topic.

## 3. Dispatch work

Any authorised client can publish a task:

```python
await room.emit("tasks", {
    "task_id": "t-001",
    "input": "NoLag is realtime messaging infrastructure with a coordination layer for agents.",
})
```

Results arrive on the `results` topic for anyone subscribed, so a dashboard or a supervising agent can react as they land.

## Keeping a human in the loop

For steps that need sign-off, NoLag's coordination patterns include **approval gates**: an agent publishes a proposed action, a human approves or rejects it from a UI, and the agent proceeds only on approval. The [AI agents guide](/docs/agents) covers approval gates, shared blackboard state, and observability in depth. For higher-level Python ergonomics, the `nolag-agents` package wraps these patterns so you do not hand-roll the topics.

## Why coordinate over pub/sub

Direct orchestration, where one process calls each agent in sequence, is easy to start and hard to scale: it couples your agents together and hides what is happening. A realtime coordination layer decouples dispatch from execution, lets you add workers freely, and gives you a single stream to observe every decision. LangChain builds the agent; NoLag coordinates the system.

## Next steps

- Read [why multi-agent systems need a coordination layer](/blog/multi-agent-coordination-layer).
- Start with the [5-minute quick start](/docs/getting-started).
- Go deeper on the six [coordination patterns](/docs/agents).
