Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.swarmd.ai/llms.txt

Use this file to discover all available pages before exploring further.

Migrating from LangChain

Adopting SwarmD doesn’t require rewriting your LangChain agents. Your tools, prompts, and graph stay the same — what changes is how agents discover and connect to each other.

Before: Hardcoded remote agents as tools

With standalone LangChain, you’d typically wire up a remote agent by writing a custom tool that posts to its URL directly:
import httpx
from langchain.agents import create_agent
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI


@tool
def get_weather(city: str) -> str:
    """Get the current weather for a city."""
    return f"The weather in {city} is sunny"


# Every remote agent is a hand-rolled HTTP tool
@tool
def call_time_agent(prompt: str) -> str:
    """Ask the time agent for time information."""
    r = httpx.post(
        "https://time-agent.internal:8080/messages",
        json={"prompt": prompt},
        timeout=60,
    )
    return r.text


@tool
def call_calendar_agent(prompt: str) -> str:
    """Ask the calendar agent to manage events."""
    r = httpx.post(
        "https://calendar-agent.internal:8080/messages",
        json={"prompt": prompt},
        timeout=60,
    )
    return r.text


agent = create_agent(
    model=ChatOpenAI(model="gpt-4o"),
    tools=[get_weather, call_time_agent, call_calendar_agent],
    system_prompt="You are a helpful weather agent.",
)
Problems with this approach:
  • Agent URLs are hardcoded — adding or removing agents requires a code change and redeployment
  • No centralized authentication between agents
  • No A2A protocol — each remote tool reinvents request/response shape
  • No polling for long-running tasks; the LLM blocks until the remote replies
  • No visibility into inter-agent traffic
  • No policy enforcement or approval workflows

After: Discovery through SwarmD

With SwarmD, remote agents are discovered from the registry at startup and exposed as standard LangChain BaseTool instances. Your agent logic is identical — only the wiring changes:
from langchain.agents import create_agent
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI

from swarmd_langchain import create_runtime, fetch_remote_agents


@tool
def get_weather(city: str) -> str:
    """Get the current weather for a city."""
    return f"The weather in {city} is sunny"


# Discover remote agents from the SwarmD registry — each one becomes a tool
runtime = create_runtime()
remote_tools = fetch_remote_agents(runtime)  # Routes through SwarmD relay

agent = create_agent(
    model=ChatOpenAI(model="gpt-4o"),
    tools=[get_weather, *remote_tools],  # Local + dynamically discovered
    system_prompt="You are a helpful weather agent.",
)
.env
SWARMD_AGENT_ID=your-agent-id
SWARMD_CLIENT_SECRET=your-client-secret
SWARMD_BASE_URL=https://api.swarmd.ai
SWARMD_TOKEN_URL=https://auth.swarmd.ai/realms/swarmd/protocol/openid-connect/token
If you want SwarmD to also build the agent and serve it over A2A, use create_llm_agent + serve — these wrap the boilerplate above and add an A2A server with admin endpoints:
from swarmd_langchain import create_llm_agent, create_runtime, serve

runtime = create_runtime()

agent = create_llm_agent(
    runtime,
    name="weather_agent",
    description="A weather agent that collaborates with other agents",
    instruction="You are a helpful weather agent.",
    tools=[get_weather],   # Local tools; remote ones are auto-discovered
)

if __name__ == "__main__":
    serve(agent, runtime)
What you get:
  • Agents are discovered at runtime from the registry — no hardcoded URLs
  • OAuth2 authentication is handled by the SDK
  • Each remote agent is a PollingA2aTool that handles A2A message/send and polls tasks/get until terminal state, so long-running sub-agents don’t block your LLM
  • All traffic routes through the relay with audit logging, policy enforcement, and HITL approval support
  • Adding or removing agents is a subscription change in the dashboard, not a code change

What stays the same

  • Your create_agent graph (model, tools, system prompt)
  • Your tool functions and @tool-decorated callables
  • Your downstream invocation patterns — agent.ainvoke({"messages": [...]}) works identically
  • Your existing LangChain integrations (chat history, memory, structured output)

Migration steps

  1. Install the SDKpip install swarmd-langchain
  2. Register your agent on SwarmD via the dashboard or Registry API
  3. Subscribe to the downstream agents your agent needs
  4. Set credentials — add SWARMD_AGENT_ID, SWARMD_CLIENT_SECRET, SWARMD_BASE_URL, and SWARMD_TOKEN_URL to your environment
  5. Replace hardcoded HTTP tools with fetch_remote_agents(runtime) (or switch to create_llm_agent + serve for the full SwarmD-managed setup)