mech.app

The mech.app newsletter

Agentic AI, minus the noise.

Get practical field notes on AI agents, automation, developer tools and security delivered to your inbox.

No spam. Unsubscribe anytime.

AI Agents

Ruflo: Meta-Harness Architecture for Multi-Framework Agent Orchestration

How Ruflo unifies LangGraph, CrewAI, AutoGen, and custom agents behind a single interface, with state isolation, MCP integration, and swarm coordination.

Source: github.com
Ruflo: Meta-Harness Architecture for Multi-Framework Agent Orchestration

When you run five different agent frameworks in production, the plumbing problem is not the frameworks themselves. It is the lack of a common interface layer. Ruflo is a meta-harness that sits above LangGraph, CrewAI, AutoGen, and custom agent implementations, providing unified orchestration, state management, and observability across heterogeneous agent stacks.

The project has 68,000+ stars and 8,000+ forks, with active deployment in multi-agent systems that need framework-agnostic coordination. The core problem it solves: you cannot swap out LangGraph for CrewAI without rewriting your orchestration layer, and you cannot run both in the same workflow without building custom glue code.

The Abstraction Layer

Ruflo enforces a harness interface that normalizes execution primitives across frameworks. Each framework has different execution models:

  • LangGraph uses state graphs with checkpointing and conditional edges.
  • CrewAI uses task delegation with role-based agents.
  • AutoGen uses conversational turns with message passing.
  • Swarm uses lightweight agent handoffs with context sharing.

Ruflo abstracts these into a common set of operations: invoke, stream, batch, and coordinate. The harness layer translates these operations into framework-specific calls, handling state serialization, error boundaries, and result normalization.

The key architectural decision is that Ruflo does not try to unify the agent definition layer. You still define agents in their native frameworks. The harness layer only unifies the execution and coordination layer.

State Isolation and Context Boundaries

Each framework manages state differently. LangGraph checkpoints state to a database. CrewAI passes task context through memory objects. AutoGen maintains conversation history in message lists.

Ruflo provides a unified state store that sits above these framework-specific mechanisms:

interface HarnessState {
  agentId: string;
  frameworkType: 'langgraph' | 'crewai' | 'autogen' | 'custom';
  executionContext: Record<string, unknown>;
  checkpointRef?: string;
  memorySnapshot?: Buffer;
  conversationHistory?: Message[];
}

When an agent invocation completes, Ruflo serializes the framework-specific state into this normalized structure. When the next agent in the workflow starts, Ruflo deserializes the state back into the target framework’s format.

This creates a clear boundary: framework-specific state stays inside the harness execution context, but cross-framework coordination happens through the normalized state store.

MCP Integration for Tool Calls

Ruflo integrates Model Context Protocol (MCP) servers as a common tool interface. Instead of each framework defining its own tool calling mechanism, agents invoke MCP servers through a unified client.

The harness layer:

  1. Registers MCP servers at startup.
  2. Exposes them to all agents regardless of framework.
  3. Handles authentication and rate limiting at the harness level.
  4. Logs all tool calls to a central observability store.

This means you can swap out a LangGraph agent for a CrewAI agent without changing the tool definitions. The MCP server interface stays constant.

Swarm Coordination Across Frameworks

Ruflo supports multi-agent swarms where agents from different frameworks coordinate on a shared task. The coordination layer uses a message bus pattern:

  • Agents publish events to named channels.
  • Other agents subscribe to channels and react to events.
  • The harness layer handles message routing and delivery guarantees.

Example workflow: a LangGraph agent performs RAG retrieval, publishes results to a channel, a CrewAI agent consumes the results and generates a report, then an AutoGen agent reviews the report in a conversational loop.

The harness layer ensures that if the CrewAI agent crashes, the LangGraph agent does not see the failure unless it explicitly subscribes to error events. Execution contexts are isolated by default.

Observability and Debugging

Each framework has its own logging format. LangGraph emits structured logs with state transitions. CrewAI logs task assignments and completions. AutoGen logs conversational turns.

Ruflo normalizes these into a common observability schema:

FieldDescriptionSource
trace_idUnique identifier for the entire workflowHarness
span_idUnique identifier for a single agent invocationHarness
frameworkWhich framework executed this spanAgent metadata
agent_idWhich agent executed this spanAgent metadata
inputSerialized input to the agentFramework logs
outputSerialized output from the agentFramework logs
duration_msExecution timeHarness
errorError message if the agent failedFramework logs

All logs are written to a central store (PostgreSQL, S3, or a time-series database). You can query across frameworks to see the full execution trace.

Failure Modes and Isolation

When an agent crashes, Ruflo isolates the failure to that execution context. Other agents in the workflow continue unless they explicitly depend on the failed agent’s output.

Common failure scenarios:

  • Framework-specific crash: LangGraph state graph hits an invalid transition. Ruflo catches the exception, logs it, and marks the agent as failed. Downstream agents that depend on this output receive a failure signal.
  • Tool call timeout: An MCP server does not respond within the timeout window. Ruflo retries with exponential backoff, then fails the agent invocation if retries are exhausted.
  • State deserialization error: The harness cannot deserialize state from one framework into another. This is a configuration error and fails fast at workflow startup.

The harness layer does not automatically retry failed agents. Retry logic is delegated to the workflow orchestrator (which may be a separate system like Temporal or a custom scheduler).

Deployment Shape

Ruflo runs as a TypeScript service with three deployment modes:

  1. Embedded: The harness runs in the same process as your application. Agents are invoked via function calls.
  2. Sidecar: The harness runs as a separate process on the same host. Agents are invoked via HTTP or gRPC.
  3. Distributed: The harness runs as a cluster of services. Agents are invoked via a message queue (RabbitMQ, Kafka, or SQS).

The distributed mode is necessary when you need to scale agent execution across multiple hosts or when you need to isolate agent execution for security reasons (for example, running untrusted agents in sandboxed containers).

Security Boundaries

Ruflo enforces security at the harness layer:

  • Authentication: Each agent invocation requires a valid API key or JWT token.
  • Authorization: Agents can only invoke tools they have been granted access to.
  • Rate limiting: The harness enforces per-agent and per-tool rate limits.
  • Sandboxing: In distributed mode, agents run in isolated containers with no network access except to the harness API and registered MCP servers.

The harness layer does not enforce data access controls. That is the responsibility of the MCP servers and the underlying data stores.

Code Example: Cross-Framework Workflow

import { Ruflo, HarnessConfig } from 'ruflo';

const config: HarnessConfig = {
  stateStore: { type: 'postgres', connectionString: process.env.DB_URL },
  mcpServers: [
    { name: 'search', url: 'http://localhost:3001' },
    { name: 'database', url: 'http://localhost:3002' },
  ],
  observability: { type: 's3', bucket: 'agent-logs' },
};

const harness = new Ruflo(config);

// Register agents from different frameworks
harness.registerAgent({
  id: 'retriever',
  framework: 'langgraph',
  definition: langGraphAgent,
});

harness.registerAgent({
  id: 'writer',
  framework: 'crewai',
  definition: crewAIAgent,
});

// Define workflow
const workflow = harness.createWorkflow('research-report')
  .step('retriever', { query: 'latest AI research' })
  .step('writer', { input: '{{retriever.output}}' })
  .onError('retriever', { retry: 3, backoff: 'exponential' });

// Execute
const result = await workflow.execute();
console.log(result.output);

The harness handles state passing between the LangGraph retriever and the CrewAI writer, logs all tool calls, and retries the retriever if it fails.

Technical Verdict

Use Ruflo when:

  • You are running multiple agent frameworks in production and need a common orchestration layer.
  • You need to swap out frameworks without rewriting coordination logic.
  • You need centralized observability across heterogeneous agent stacks.
  • You need to enforce security boundaries at the harness level rather than in each framework.

Avoid Ruflo when:

  • You are only using one framework and do not need cross-framework coordination.
  • You need framework-specific features that the harness abstraction does not expose (for example, LangGraph’s time-travel debugging).
  • You need sub-millisecond latency and cannot afford the overhead of the harness layer (typically 5-10ms per invocation).

The meta-harness pattern is becoming critical as teams deploy heterogeneous agent stacks. Ruflo provides the plumbing layer that makes this practical.