[{"data":1,"prerenderedAt":412},["ShallowReactive",2],{"blog:/blog/coordinate-langchain-agents-with-nolag":3},{"id":4,"title":5,"author":6,"body":7,"category":401,"date":402,"description":403,"excerpt":404,"extension":405,"meta":406,"navigation":133,"path":407,"readTime":408,"seo":409,"stem":410,"__hash__":411},"blog/blog/coordinate-langchain-agents-with-nolag.md","Coordinate LangChain Agents with NoLag","Henco Burger",{"type":8,"value":9,"toc":392},"minimark",[10,14,19,56,59,63,94,98,291,296,300,303,328,334,338,355,359,362,366,388],[11,12,13],"p",{},"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.",[15,16,18],"h2",{"id":17},"the-shape","The shape",[20,21,22,36,50],"ul",{},[23,24,25,26,30,31,35],"li",{},"A ",[27,28,29],"strong",{},"dispatcher"," publishes tasks to a ",[32,33,34],"code",{},"tasks"," topic.",[23,37,38,39,42,43,45,46,49],{},"One or more ",[27,40,41],{},"workers",", each wrapping a LangChain chain, subscribe to ",[32,44,34],{},", run the chain, and publish to ",[32,47,48],{},"results",".",[23,51,52,53,55],{},"Anything can watch ",[32,54,48],{},": a UI, a supervisor agent, or a human.",[11,57,58],{},"Because it is pub/sub, you add workers by starting more subscribers. No queue to run, no orchestration server to operate.",[15,60,62],{"id":61},"_1-install","1. Install",[64,65,70],"pre",{"className":66,"code":67,"language":68,"meta":69,"style":69},"language-bash shiki shiki-themes github-light github-dark","pip install nolag langchain langchain-openai\n","bash","",[32,71,72],{"__ignoreMap":69},[73,74,77,81,85,88,91],"span",{"class":75,"line":76},"line",1,[73,78,80],{"class":79},"sScJk","pip",[73,82,84],{"class":83},"sZZnC"," install",[73,86,87],{"class":83}," nolag",[73,89,90],{"class":83}," langchain",[73,92,93],{"class":83}," langchain-openai\n",[15,95,97],{"id":96},"_2-a-langchain-worker-on-a-nolag-room","2. A LangChain worker on a NoLag room",[64,99,103],{"className":100,"code":101,"language":102,"meta":69,"style":69},"language-python shiki shiki-themes github-light github-dark","import asyncio\nfrom nolag import NoLag\nfrom langchain_openai import ChatOpenAI\nfrom langchain_core.prompts import ChatPromptTemplate\n\n# Build the LangChain agent (a simple summariser here)\nllm = ChatOpenAI(model=\"gpt-4o-mini\")\nprompt = ChatPromptTemplate.from_template(\"Summarise this in one sentence:\\n\\n{input}\")\nchain = prompt | llm\n\nasync def main():\n    client = NoLag(\"your_access_token\")\n    await client.connect()\n\n    room = client.set_app(\"agents\").set_room(\"workflow\")\n    await room.subscribe(\"tasks\")\n\n    def on_task(data, meta):\n        async def run():\n            result = await chain.ainvoke({\"input\": data[\"input\"]})\n            await room.emit(\"results\", {\n                \"task_id\": data[\"task_id\"],\n                \"output\": result.content,\n            })\n        asyncio.create_task(run())\n\n    room.on(\"tasks\", on_task)\n\n    # Keep the worker alive\n    await asyncio.Event().wait()\n\nasyncio.run(main())\n","python",[32,104,105,110,116,122,128,135,141,147,153,159,164,170,176,182,187,193,199,204,210,216,222,228,234,240,246,252,257,263,268,274,280,285],{"__ignoreMap":69},[73,106,107],{"class":75,"line":76},[73,108,109],{},"import asyncio\n",[73,111,113],{"class":75,"line":112},2,[73,114,115],{},"from nolag import NoLag\n",[73,117,119],{"class":75,"line":118},3,[73,120,121],{},"from langchain_openai import ChatOpenAI\n",[73,123,125],{"class":75,"line":124},4,[73,126,127],{},"from langchain_core.prompts import ChatPromptTemplate\n",[73,129,131],{"class":75,"line":130},5,[73,132,134],{"emptyLinePlaceholder":133},true,"\n",[73,136,138],{"class":75,"line":137},6,[73,139,140],{},"# Build the LangChain agent (a simple summariser here)\n",[73,142,144],{"class":75,"line":143},7,[73,145,146],{},"llm = ChatOpenAI(model=\"gpt-4o-mini\")\n",[73,148,150],{"class":75,"line":149},8,[73,151,152],{},"prompt = ChatPromptTemplate.from_template(\"Summarise this in one sentence:\\n\\n{input}\")\n",[73,154,156],{"class":75,"line":155},9,[73,157,158],{},"chain = prompt | llm\n",[73,160,162],{"class":75,"line":161},10,[73,163,134],{"emptyLinePlaceholder":133},[73,165,167],{"class":75,"line":166},11,[73,168,169],{},"async def main():\n",[73,171,173],{"class":75,"line":172},12,[73,174,175],{},"    client = NoLag(\"your_access_token\")\n",[73,177,179],{"class":75,"line":178},13,[73,180,181],{},"    await client.connect()\n",[73,183,185],{"class":75,"line":184},14,[73,186,134],{"emptyLinePlaceholder":133},[73,188,190],{"class":75,"line":189},15,[73,191,192],{},"    room = client.set_app(\"agents\").set_room(\"workflow\")\n",[73,194,196],{"class":75,"line":195},16,[73,197,198],{},"    await room.subscribe(\"tasks\")\n",[73,200,202],{"class":75,"line":201},17,[73,203,134],{"emptyLinePlaceholder":133},[73,205,207],{"class":75,"line":206},18,[73,208,209],{},"    def on_task(data, meta):\n",[73,211,213],{"class":75,"line":212},19,[73,214,215],{},"        async def run():\n",[73,217,219],{"class":75,"line":218},20,[73,220,221],{},"            result = await chain.ainvoke({\"input\": data[\"input\"]})\n",[73,223,225],{"class":75,"line":224},21,[73,226,227],{},"            await room.emit(\"results\", {\n",[73,229,231],{"class":75,"line":230},22,[73,232,233],{},"                \"task_id\": data[\"task_id\"],\n",[73,235,237],{"class":75,"line":236},23,[73,238,239],{},"                \"output\": result.content,\n",[73,241,243],{"class":75,"line":242},24,[73,244,245],{},"            })\n",[73,247,249],{"class":75,"line":248},25,[73,250,251],{},"        asyncio.create_task(run())\n",[73,253,255],{"class":75,"line":254},26,[73,256,134],{"emptyLinePlaceholder":133},[73,258,260],{"class":75,"line":259},27,[73,261,262],{},"    room.on(\"tasks\", on_task)\n",[73,264,266],{"class":75,"line":265},28,[73,267,134],{"emptyLinePlaceholder":133},[73,269,271],{"class":75,"line":270},29,[73,272,273],{},"    # Keep the worker alive\n",[73,275,277],{"class":75,"line":276},30,[73,278,279],{},"    await asyncio.Event().wait()\n",[73,281,283],{"class":75,"line":282},31,[73,284,134],{"emptyLinePlaceholder":133},[73,286,288],{"class":75,"line":287},32,[73,289,290],{},"asyncio.run(main())\n",[11,292,293,294,35],{},"Start this process on as many machines as you like. Each instance is another worker pulling from the same ",[32,295,34],{},[15,297,299],{"id":298},"_3-dispatch-work","3. Dispatch work",[11,301,302],{},"Any authorised client can publish a task:",[64,304,306],{"className":100,"code":305,"language":102,"meta":69,"style":69},"await room.emit(\"tasks\", {\n    \"task_id\": \"t-001\",\n    \"input\": \"NoLag is realtime messaging infrastructure with a coordination layer for agents.\",\n})\n",[32,307,308,313,318,323],{"__ignoreMap":69},[73,309,310],{"class":75,"line":76},[73,311,312],{},"await room.emit(\"tasks\", {\n",[73,314,315],{"class":75,"line":112},[73,316,317],{},"    \"task_id\": \"t-001\",\n",[73,319,320],{"class":75,"line":118},[73,321,322],{},"    \"input\": \"NoLag is realtime messaging infrastructure with a coordination layer for agents.\",\n",[73,324,325],{"class":75,"line":124},[73,326,327],{},"})\n",[11,329,330,331,333],{},"Results arrive on the ",[32,332,48],{}," topic for anyone subscribed, so a dashboard or a supervising agent can react as they land.",[15,335,337],{"id":336},"keeping-a-human-in-the-loop","Keeping a human in the loop",[11,339,340,341,344,345,350,351,354],{},"For steps that need sign-off, NoLag's coordination patterns include ",[27,342,343],{},"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 ",[346,347,349],"a",{"href":348},"/docs/agents","AI agents guide"," covers approval gates, shared blackboard state, and observability in depth. For higher-level Python ergonomics, the ",[32,352,353],{},"nolag-agents"," package wraps these patterns so you do not hand-roll the topics.",[15,356,358],{"id":357},"why-coordinate-over-pubsub","Why coordinate over pub/sub",[11,360,361],{},"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.",[15,363,365],{"id":364},"next-steps","Next steps",[20,367,368,375,382],{},[23,369,370,371,49],{},"Read ",[346,372,374],{"href":373},"/blog/multi-agent-coordination-layer","why multi-agent systems need a coordination layer",[23,376,377,378,49],{},"Start with the ",[346,379,381],{"href":380},"/docs/getting-started","5-minute quick start",[23,383,384,385,49],{},"Go deeper on the six ",[346,386,387],{"href":348},"coordination patterns",[389,390,391],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":69,"searchDepth":112,"depth":112,"links":393},[394,395,396,397,398,399,400],{"id":17,"depth":112,"text":18},{"id":61,"depth":112,"text":62},{"id":96,"depth":112,"text":97},{"id":298,"depth":112,"text":299},{"id":336,"depth":112,"text":337},{"id":357,"depth":112,"text":358},{"id":364,"depth":112,"text":365},"Integration","2026-08-02","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.",null,"md",{},"/blog/coordinate-langchain-agents-with-nolag","8 min read",{"title":5,"description":403},"blog/coordinate-langchain-agents-with-nolag","P-de1Q94YFbLBJDwWjAflmnjP7W5omy8zKgqRExQjX4",1788160339717]