Getting started

Introduction

What Assemble is, how it works, and where to start.

Assemble is a TypeScript SDK and CLI for building multi-agent AI workflows. You describe agents, tools, teams, and the topology that connects them; Assemble runs the workflow, records a full trace of every step, and lets you replay and evaluate those runs so you can ship changes with confidence.

Everything runs on your machine first. The starter workflow uses a built-in mock model, so you can go from zero to a running trace with no credit card and no external keys. A free developer key adds hosted traces: every run streams to a dashboard with a live timeline, an approvals inbox, eval results, analytics, and shareable read-only links.

The core loop#

Assemble is built around one loop you repeat as your team grows:

  1. Define agents, tools, and policies in TypeScript, with every input and output described by a Zod schema. See Agents, Tools, and Workflows & topologies.
  2. Run the workflow locally with asm run or workflow.run(). Every step is validated, policy-checked, and recorded. See Runtime & run state.
  3. Trace what happened — every agent call, tool call, routing decision, and policy decision lands in an ordered event stream you can stream to the console, a JSONL file, and the hosted dashboard. See Tracing.
  4. Replay a recorded run against your current code and diff the output, latency, and token usage, so you can see exactly how a prompt or model change moves a past run. See Replay.
  5. Evaluate with a suite that pins expected behavior, so regressions surface before your users see them. See Evals.

Design principles#

  • Local-first. Workflows execute in your process. Traces are written to disk before anything is uploaded, and every command works offline.
  • Bring your own model keys. Provider adapters call OpenAI, Anthropic, and Gemini directly from your machine with your own keys. Assemble never proxies your model calls, never sees your provider keys, and never bills you for model usage. See Model providers and Security.
  • Typed end to end. Zod schemas validate workflow input, agent output, tool arguments, and tool results at runtime, and the same schemas drive your TypeScript types.
  • Humans stay in the loop. Policies can pause a run until a person approves it — from code, the CLI, or the dashboard approvals inbox. See Policies and Human approval.

A complete workflow#

This is a runnable workflow: a supervisor routes a support ticket through a classifier and a refund specialist, runs a tool under an audit policy, and returns a typed reply. It uses the mock model, so it needs no API keys.

src/workflow.ts
import { mockModel } from "@assemble-dev/providers";
import { agent, finishWorkflow, policy, tool, workflow } from "@assemble-dev/sdk";
import { z } from "zod";

const classifier = agent({
  name: "classifier",
  role: "Classifies incoming support tickets",
  model: mockModel({ scriptedResponses: ['{"category":"refund"}'] }),
  instructions: "Classify the ticket as refund, technical, or qa.",
  outputSchema: z.object({ category: z.enum(["refund", "technical", "qa"]) }),
});

const refundSpecialist = agent({
  name: "refund-specialist",
  role: "Resolves refund requests",
  model: mockModel({ scriptedResponses: ['{"reply":"Refund issued."}'] }),
  instructions: "Resolve the refund request and confirm to the customer.",
  outputSchema: z.object({ reply: z.string() }),
});

const issueRefund = tool({
  name: "issueRefund",
  description: "Issues a refund for an order",
  inputSchema: z.object({ orderId: z.string().min(1) }),
  execute: async (input) =>
    await Promise.resolve({ refunded: true, orderId: input.orderId }),
});

export const supportWorkflow = workflow({
  name: "support-quickstart",
  inputSchema: z.object({ ticket: z.string().min(1) }),
  outputSchema: z.object({ reply: z.string() }),
  agents: [classifier, refundSpecialist],
  tools: [issueRefund],
  policies: [
    policy({
      name: "audit-refunds",
      appliesToToolNames: ["issueRefund"],
      logOnly: () => "refund audited for compliance",
    }),
  ],
  agentToolBindings: [
    {
      agentName: "refund-specialist",
      toolName: "issueRefund",
      buildToolInput: () => ({ orderId: "ord_1" }),
    },
  ],
  topology: {
    kind: "supervisor",
    supervisorName: "support-router",
    route: ({ stepIndex }) => {
      if (stepIndex === 0) {
        return "classifier";
      }

      if (stepIndex === 1) {
        return {
          agentName: "refund-specialist",
          reason: "classifier chose the refund category",
        };
      }

      return finishWorkflow;
    },
  },
});

Run it with the CLI and open the hosted trace it prints:

sh
asm run src/workflow.ts --input '{"ticket":"I want a refund"}'

The packages#

PackageWhat it provides
@assemble-dev/sdkAgents, tools, teams, workflows, policies, memory, tracing, and replay.
@assemble-dev/providersModel adapters: openai, anthropic, gemini, azureOpenai, bedrock, openrouter, cloudflareWorkersAi, and mockModel.
@assemble-dev/evalsEval suites, deterministic metrics, the LLM judge, and the runner.
@assemble-dev/cliThe asm command: login, init, run, dev, eval, and replay.

Install the SDK in a project and the CLI globally:

sh
pnpm add @assemble-dev/sdk @assemble-dev/providers zod
pnpm add -g @assemble-dev/cli

zod is a runtime dependency you also use directly to describe every input and output schema.

How these docs are organized#

Next steps#

Start with the Quickstart — you will have a running, traced workflow in minutes, without spending a dollar.