Swarms Logo

Swarms for Legal

Contract review against a playbook, clause extraction, legal research with citation checks, memo drafting and due diligence, run as agent teams on the Swarms API with lawyers deciding.

  • Playbook rules become system-prompt lines, so flags come back with the rule and the quoted clause
  • Judges on different models score the draft independently; a split vote is surfaced, never averaged
  • Per-run logs in Swarms Cloud with the inputs, each agent's output and token usage, keyed by matter
Review Drafter · MSA draft 14Paused
  1. Master Services Agreement
  2. 1.Termreading
  3. 2.Termination
  4. 3.Indemnification
  5. 4.Limitation of Liability
  6. 5.Assignment
  7. 6.Governing Law
  8. 7.Data Protection
  9. 8.Non-compete

Agent flags against the playbook; the attorney decides.

Open flags · 0

  • Scroll into view to start the review.

Architecture

Contract review as a council

The drafter produces the candidate review, three judges score it independently for playbook fit, precedent and consistency, and the ruling writer turns the scores into the memo the supervising attorney reads. Watch one agreement go through the council.

swarm_typeCouncilAsAJudgeSimulation paused
CANDIDATEJUDGESRULINGTaskPOST /v1/swarmReview Drafterclaude-sonnet-5-5Playbook Judgegpt-5.4Precedent Judgegemini-2.5-proConsistency Judgedeepseek-v4-proRuling Writerclaude-opus-5-5Review memo200 OK · JSON
  • 01run #1041 started

One candidate, three scores

The drafter's review is scored by judges that never see each other's work, so a missed rule shows up as a playbook finding and an over-reaching fallback as a precedent finding.

Dissent is written down

When the judges disagree, the ruling writer records the disagreement instead of smoothing it over. The attorney sees which flags the council was unsure about first.

A memo, never a redline

The agents quote clauses, cite rules and propose fallbacks. They do not edit the agreement. The reviewing attorney decides what to redline, accept or escalate.

Citations

Every citation checked before an associate reads the draft

Three verifiers on models from different providers check each citation independently: does the authority exist, does the pin cite land on the proposition, and is the proposition stated accurately. The majority call is recorded, a split is sent to the attorney, and the associate confirms against the reporter.

Citation council · memo draft 030/8 checkedPaused

Verified

0 of 8

verified 0needs source 0wrong pin cite 0
  1. Northwind Traders v. Contoso Ltd., 412 F.3d 118, 124 (2d Cir. 2005)checking
  2. Litware, Inc. v. Tailspin Toys, 230 Cal. App. 4th 455, 462 (2014)queued
  3. In re Fabrikam Holdings, 98 B.R. 331, 337 (Bankr. D. Del. 2011)queued
  4. Adventure Works v. Wide World Importers, 719 F. Supp. 2d 901, 909 (S.D.N.Y. 2010)queued
  5. Proseware Corp. v. Woodgrove Bank, 88 A.3d 614, 620 (Del. 2014)queued
  6. Coho Winery v. Alpine Ski House, 455 F.3d 1032, 1040 (9th Cir. 2006)queued
  7. Margie's Travel v. Humongous Insurance, 2017 WL 4418281, at *4 (N.D. Ill. 2017)queued
  8. Trey Research v. Lucerne Publishing, 301 F. Supp. 3d 212, 219 (D. Mass. 2018)queued

Citation 1 · judges vote independently

Northwind Traders v. Contoso Ltd., 412 F.3d 118, 124 (2d Cir. 2005)

  • Verifier A...
  • Verifier B...
  • Verifier C...

Waiting for the council.

NEEDS SOURCE beats a guess

Each verifier is told to answer NEEDS SOURCE when it cannot confirm a citation from the materials it was given. A confident wrong answer from one model is outvoted by the other two and shows up as a dissent.

Three providers, one vote

The verifiers run on models from different providers, so a blind spot shared by one model family does not become the council's answer.

The check reduces work, it does not replace it

The associate still confirms every citation against the reporter before filing. The council's job is to make that pass faster by sorting the citations and showing its reasoning.

Playbook to prompt

How three playbook rules become system-prompt lines

The contracts team writes the rule the way it already does. Each rule becomes a line the drafter follows and the playbook judge scores against, and every flag comes back with the rule id, the quoted clause and the fallback.

RuleAs the playbook writes itSystem-prompt lineWhat the drafter returns
PB-07Limitation of liability: cap at 12 months of fees. Carve-outs only for confidentiality, IP indemnity, gross negligence and wilful misconduct.Flag any liability cap below 12 months of fees and any carve-out beyond confidentiality, IP indemnity, gross negligence or wilful misconduct. Rate high. Quote the clause and propose the 12-month cap as the fallback.Limitation of Liability, PB-07, high. Quoted clause: cap at 3 months of fees. Fallback: 12 months of fees, playbook carve-outs.
PB-09Governing law: Delaware or New York preferred. England and Wales acceptable. Anything else, escalate to the supervising attorney.If governing law is Delaware or New York, no flag. If England and Wales, flag low with no fallback. Any other jurisdiction, flag medium and write ESCALATE in the fallback field.Governing Law, PB-09, medium. Quoted clause: laws of a jurisdiction outside the list. Fallback: ESCALATE.
PB-11Non-compete: we do not accept non-competes binding on us. A non-solicit of employees for up to 12 months is acceptable.Flag any covenant that restricts our business, customers or markets, rate high, and propose deleting it. A non-solicit of employees up to 12 months is within playbook; longer than 12 months, flag medium with 12 months as the fallback.Non-compete, PB-11, high. Quoted clause: 12-month restriction on competing services. Fallback: delete; offer 12-month employee non-solicit.

Use cases

Where legal teams put agents to work

Each card names the Swarms API swarm type it maps to and the agents you would send. In every one, an attorney, associate or paralegal makes the call the agents prepared for, and privilege determinations stay with the attorney.

CouncilAsAJudge

Contract review against a playbook

A drafter reviews every clause against the playbook and quotes the text behind each flag. Three judges score the draft for playbook fit, precedent and internal consistency, and a ruling writer ranks the flags for the reviewing attorney.

  • Review Drafter
  • Playbook Judge
  • Precedent Judge
  • Consistency Judge
  • Ruling Writer
SequentialWorkflow

Clause extraction and abstraction

A locator finds the clauses, an extractor pulls dates, parties, caps and notice periods with the source text, and a writer fills the firm's abstract template. Blank fields stay blank for a paralegal to resolve.

  • Clause Locator
  • Term Extractor
  • Abstract Writer
HeavySwarm

Research memo

A question is broken down, researched, analysed and written up as a memo with a citation for every proposition. The memo goes to the citation council below before an associate reads it.

  • Question Agent
  • Research Agent
  • Analysis Agent
  • Synthesis Agent
MajorityVoting

Citation verification

Three verifiers independently check each citation in a draft for existence, pin cite and whether it supports the proposition. The majority result and every dissent go to the associate, who confirms against the source.

  • Verifier A
  • Verifier B
  • Verifier C
PlannerWorkerSwarm

Data room review

Planners read the index and queue every agreement with the questions diligence needs answered; workers pull from the queue and abstract each document. The deal team reviews the abstracts and the issues list.

  • Index Planner
  • Issues Planner
  • Abstract Worker
  • Abstract Worker
MultiAgentRouter

Discovery document routing

A router classifies each document and sends it to a responsiveness, privilege-candidate or key-document reviewer. Privilege candidates are only flagged; an attorney makes every privilege determination.

  • Router
  • Responsiveness Reviewer
  • Privilege Candidate Reviewer
  • Key Document Reviewer

Swarms Cloud

Every run on the matter file

Runs from the API land in Swarms Cloud with their inputs, each agent's output, token usage and cost. Name runs after the matter and the document, as the batch example does, and the firm can see exactly what was sent, what came back and what it cost per matter.

Swarms Cloudcontract-review-council · CouncilAsAJudgeSimulation paused

Agreements / hour

20

▼ last 30s

p50 latency

9.4s

▲ last 30s

Tokens / min

144.5k

▲ last 30s

Spend / hour

$6.20

▲ last 30s

Every run on the Swarms API appears in Swarms Cloud with its logs, token usage, cost and context use.

Open Swarms Cloud

Code

Run the council from Python, TypeScript or cURL

The Swarms API examples share one request shape; only swarm_type and the agents list change between the review council and the citation vote. The last tab runs a pipeline in-process with the open-source swarms package. Set SWARMS_API_KEY from your Swarms Cloud account.

contract_council.py
import os
from swarms_client import SwarmsClient

client = SwarmsClient(api_key=os.environ["SWARMS_API_KEY"])

# Council as a judge: the drafter produces the candidate review, the judges
# score it, and the ruling writer writes the memo. Nothing is redlined by agents.
PLAYBOOK = """
PB-03 Term: auto-renewal acceptable only with a 60-day opt-out notice.
PB-05 Termination: we require termination for convenience on 90 days notice.
PB-07 Limitation of liability: cap at 12 months of fees; carve-outs limited to
      confidentiality, IP indemnity, gross negligence and wilful misconduct.
PB-09 Governing law: Delaware or New York preferred; England and Wales acceptable.
PB-11 Non-compete: no non-compete binding on us; employee non-solicit up to 12 months.
PB-12 Data protection: breach notice within 72 hours, sub-processor list on request.
"""

response = client.swarms.run(
    name="Contract Review Council",
    description="Clause-by-clause review against the playbook, scored by judges, written as a memo for the attorney.",
    swarm_type="CouncilAsAJudge",
    task=(
        "Review the attached master services agreement (counterparty paper) "
        "against the playbook. For every clause that departs from a rule, quote "
        "the clause, name the rule and propose a fallback position.\n\n"
        + PLAYBOOK
        + "\n\nAGREEMENT TEXT:\n" + open("msa_counterparty_draft.txt").read()
    ),
    agents=[
        {
            "agent_name": "Review Drafter",
            "description": "Produces the candidate clause-by-clause review.",
            "system_prompt": (
                "You are a commercial contracts reviewer. Go through the agreement "
                "clause by clause. For each departure from the playbook, quote the "
                "clause text, cite the playbook rule by id, rate the risk high, "
                "medium or low, and propose a fallback. Say when a clause is silent."
            ),
            "model_name": "claude-sonnet-5-5",
            "max_loops": 1,
        },
        {
            "agent_name": "Playbook Judge",
            "description": "Checks the review against the playbook rules.",
            "system_prompt": (
                "Score the review for completeness against the playbook: every rule "
                "that the agreement touches must have a finding. List missed rules "
                "and false flags, each with the clause text."
            ),
            "model_name": "gpt-5.4",  # judges get stronger models than the drafter
            "max_loops": 1,
        },
        {
            "agent_name": "Precedent Judge",
            "description": "Checks fallbacks against the clause library.",
            "system_prompt": (
                "Score the proposed fallbacks against the firm's standard positions "
                "described in the playbook. Flag any fallback that goes beyond what "
                "the playbook allows."
            ),
            "model_name": "gemini-2.5-pro",
            "max_loops": 1,
        },
        {
            "agent_name": "Consistency Judge",
            "description": "Checks defined terms and cross-references.",
            "system_prompt": (
                "Score the review for internal consistency: defined terms used as "
                "defined, section references that resolve, and risk ratings that "
                "match the playbook's severity."
            ),
            "model_name": "deepseek-v4-pro",
            "max_loops": 1,
        },
        {
            "agent_name": "Ruling Writer",
            "description": "Writes the memo from the judges' scores.",
            "system_prompt": (
                "Write the review memo for the supervising attorney: flags ranked by "
                "risk, each with the quoted clause, the rule and the fallback, then "
                "the judges' dissents. This memo is a draft for a lawyer's review."
            ),
            "model_name": "claude-opus-5-5",  # final writing on the strongest model
            "max_loops": 1,
        },
    ],
    max_loops=1,
)

print(response)
contract_council.sh
curl -X POST https://api.swarms.world/v1/swarm/completions \
  -H "x-api-key: $SWARMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Contract Review Council",
    "description": "Clause-by-clause review against the playbook, scored by judges, written as a memo for the attorney.",
    "swarm_type": "CouncilAsAJudge",
    "task": "Review the master services agreement below against the playbook. PB-07: liability cap at 12 months of fees, carve-outs limited to confidentiality, IP indemnity, gross negligence and wilful misconduct. PB-09: governing law Delaware or New York preferred, England and Wales acceptable. PB-11: no non-compete binding on us. For every departure quote the clause, name the rule and propose a fallback. AGREEMENT TEXT: [paste the agreement here]",
    "agents": [
      {
        "agent_name": "Review Drafter",
        "system_prompt": "You are a commercial contracts reviewer. For each departure from the playbook quote the clause, cite the rule id, rate the risk high, medium or low and propose a fallback. Say when a clause is silent.",
        "model_name": "claude-sonnet-5-5",
        "max_loops": 1
      },
      {
        "agent_name": "Playbook Judge",
        "system_prompt": "Score the review for completeness against the playbook. List missed rules and false flags with the clause text.",
        "model_name": "gpt-5.4",
        "max_loops": 1
      },
      {
        "agent_name": "Precedent Judge",
        "system_prompt": "Score the proposed fallbacks against the standard positions in the playbook. Flag any fallback that goes beyond what the playbook allows.",
        "model_name": "gemini-2.5-pro",
        "max_loops": 1
      },
      {
        "agent_name": "Consistency Judge",
        "system_prompt": "Score the review for internal consistency: defined terms, section references that resolve, risk ratings that match the playbook severity.",
        "model_name": "deepseek-v4-pro",
        "max_loops": 1
      },
      {
        "agent_name": "Ruling Writer",
        "system_prompt": "Write the review memo for the supervising attorney: flags ranked by risk with the quoted clause, rule and fallback, then the judges dissents. This is a draft for a lawyer to review.",
        "model_name": "claude-opus-5-5",
        "max_loops": 1
      }
    ],
    "max_loops": 1
  }'

# "output" is the memo; "usage" has input_tokens, output_tokens and total_tokens.
checkCitations.ts
// Citation verification as a vote: three verifiers check each citation
// independently and the Swarms API returns the majority call per citation.
// The associate confirms every citation against the reporter before filing.
const SWARMS_API = "https://api.swarms.world/v1/swarm/completions"

type Draft = { matter: string; text: string; citations: string[] }

type SwarmResponse = {
  output: unknown
  usage: { input_tokens: number; output_tokens: number; total_tokens: number }
}

const VERIFIER_PROMPT =
  "You verify citations in legal drafts. For each citation return one line: the citation, then " +
  "VERIFIED, NEEDS SOURCE or WRONG PIN CITE, then one sentence. VERIFIED means the authority exists, " +
  "the pin cite points at the quoted proposition and the proposition is stated accurately. If you " +
  "cannot confirm existence from the materials you are given, answer NEEDS SOURCE; never guess."

const verifier = (name: string, model: string) => ({
  agent_name: name,
  system_prompt: VERIFIER_PROMPT,
  model_name: model,
  max_loops: 1,
})

export async function checkCitations(draft: Draft): Promise<{ calls: unknown; tokens: number }> {
  const list = draft.citations.map((c, i) => String(i + 1) + ". " + c).join("\n")

  const res = await fetch(SWARMS_API, {
    method: "POST",
    headers: {
      "x-api-key": process.env.SWARMS_API_KEY!,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      name: "Citation Check " + draft.matter,
      description: "Independent verification of every citation in a draft; majority call per citation.",
      swarm_type: "MajorityVoting",
      task: "Draft text:\n\n" + draft.text + "\n\nCitations to verify:\n" + list,
      agents: [
        verifier("Verifier A", "gpt-5.4"), // three different providers, so one model's blind spot is outvoted
        verifier("Verifier B", "claude-sonnet-5-5"),
        verifier("Verifier C", "gemini-2.5-pro"),
      ],
      max_loops: 1,
    }),
  })

  if (!res.ok) throw new Error("Swarms API " + res.status + ": " + (await res.text()))
  const data = (await res.json()) as SwarmResponse
  return { calls: data.output, tokens: data.usage.total_tokens }
}

// Placeholder parties and reporters; use your own draft and the sources the
// agents should check against.
checkCitations({
  matter: "M-4471",
  text: "A limitation of liability clause is enforced as written between sophisticated parties ...",
  citations: [
    "Northwind Traders v. Contoso Ltd., 412 F.3d 118, 124 (2d Cir. 2005)",
    "Litware, Inc. v. Tailspin Toys, 230 Cal. App. 4th 455, 462 (2014)",
  ],
}).then((r) => console.log(r.calls, r.tokens + " tokens"))
nightly_data_room.py
import json
import os

import requests

BASE = "https://api.swarms.world"
HEADERS = {"x-api-key": os.environ["SWARMS_API_KEY"], "Content-Type": "application/json"}

# Before the nightly data room run: check the credit balance and that the
# models the swarm needs are available, then submit every agreement as one
# batch. Each item becomes its own run in the account's swarm logs, named
# after the matter and the document.
credits = requests.get(f"{BASE}/v1/account/credits", headers=HEADERS, timeout=30).json()
models = requests.get(f"{BASE}/v1/models/available", headers=HEADERS, timeout=30).json()
print("credits:", credits)
print("models:", models)

with open("data_room_index.json") as f:
    documents = json.load(f)  # [{"doc_id": "DR-0412", "title": "...", "text": "..."}, ...]

MATTER = "M-4471"

AGENTS = [
    {
        "agent_name": "Clause Locator",
        "system_prompt": (
            "Locate the term, termination, change of control, assignment, "
            "exclusivity, most-favoured-customer and governing law clauses. Return "
            "the section number and the full clause text for each; write ABSENT "
            "when a clause is not present."
        ),
        "model_name": "gemini-2.5-flash",  # fast, long context, cheap across a data room
        "max_loops": 1,
    },
    {
        "agent_name": "Term Extractor",
        "system_prompt": (
            "From the located clauses extract parties, effective date, term end, "
            "renewal mechanics, notice periods, change of control consequences and "
            "exclusivity scope. Quote the source text for every value."
        ),
        "model_name": "claude-haiku-5-5",
        "max_loops": 1,
    },
    {
        "agent_name": "Abstract Writer",
        "system_prompt": (
            "Fill the diligence abstract template from the extracted terms and list "
            "issues for the deal team. Leave fields blank where the extractor found "
            "nothing. A paralegal and an attorney review every abstract."
        ),
        "model_name": "gpt-5.4-mini",
        "max_loops": 1,
    },
]

batch = [
    {
        "name": f"{MATTER} abstract {doc['doc_id']}",
        "description": "Nightly data room abstraction for the deal team's review.",
        "swarm_type": "SequentialWorkflow",
        "task": f"Document {doc['doc_id']}: {doc['title']}\n\n{doc['text']}",
        "agents": AGENTS,
        "max_loops": 1,
    }
    for doc in documents
]

results = requests.post(
    f"{BASE}/v1/swarm/batch/completions", headers=HEADERS, json=batch, timeout=900
).json()

os.makedirs("abstracts", exist_ok=True)
for doc, result in zip(documents, results):
    with open(f"abstracts/{doc['doc_id']}.json", "w") as out:
        json.dump(result, out, indent=2)
    print(doc["doc_id"], result.get("usage", {}).get("total_tokens"), "tokens")

print(len(results), "abstracts ready for the deal team")
contract_abstract.py
from swarms import Agent, SequentialWorkflow

# The open-source swarms package runs the same pipeline inside your own
# environment, for documents that cannot leave the firm's network.
# pip install swarms

locator = Agent(
    agent_name="Clause Locator",
    system_prompt=(
        "Locate the term, termination, indemnification, limitation of liability, "
        "assignment, governing law, data protection and non-compete clauses. Return "
        "the section number and full clause text for each, or ABSENT."
    ),
    model_name="gemini-2.5-flash",
    max_loops=1,
)

extractor = Agent(
    agent_name="Term Extractor",
    system_prompt=(
        "From the located clauses extract: parties, effective date, initial term, "
        "renewal mechanics, termination rights and notice periods, liability cap and "
        "carve-outs, governing law and forum, breach notice deadline, restrictive "
        "covenants and their duration. Quote the source text for every value."
    ),
    model_name="claude-haiku-5-5",
    max_loops=1,
)

writer = Agent(
    agent_name="Abstract Writer",
    system_prompt=(
        "Fill the firm's contract abstract template from the extracted terms. Leave "
        "a field blank when the extractor found nothing and list it under Open "
        "Items. A paralegal completes the open items and an attorney reviews."
    ),
    model_name="gpt-5.4-mini",
    max_loops=1,
)

workflow = SequentialWorkflow(
    name="Contract Abstract",
    description="Locate, extract and abstract the key terms of one agreement.",
    agents=[locator, extractor, writer],
    max_loops=1,
)

with open("msa_counterparty_draft.txt") as f:
    agreement = f.read()

abstract = workflow.run(
    "Abstract the following master services agreement for the deal file.\n\n" + agreement
)
print(abstract)

The Python SDK (pip install swarms-client) runs the review as a CouncilAsAJudge: the drafter produces a clause-by-clause review against the playbook, three judges on different models score it independently, and the ruling writer produces the memo. The memo is a draft for the supervising attorney, and nothing is redlined by the agents.

Questions legal teams ask

What general counsel, knowledge management and the firm's technology committee ask before an agent reads a contract.

Do the agents give legal advice or make the final call on a contract?

No. The agents flag departures from your playbook with the quoted clause and a proposed fallback, score each other's work and write a memo. The reviewing attorney decides what to redline, what to accept and what to escalate. The prompts in the examples say the output is a draft for a lawyer's review, and no agent edits the agreement.

How does the council stop a fabricated citation reaching a filing?

Three ways. The verifiers are told to answer NEEDS SOURCE when they cannot confirm a citation from the materials they are given, instead of guessing. They run independently on models from different providers, so one model's confident error is outvoted and surfaced as a dissent. And the associate confirms every citation against the reporter: the council reduces the work of checking, it does not replace it.

How do we turn our playbook into something the agents follow?

Each playbook rule becomes a line in a system prompt or in the task text, with its id, the acceptable position and the fallbacks. The drafter cites the rule id on every flag, and the playbook judge scores the review against the full list, so a rule the drafter missed shows up as a judge finding. The table on this page shows three rules written both ways.

How is privileged or confidential material handled?

Send the agents the documents a matter needs and nothing more, and keep privilege determinations with the attorney: the discovery routing use case only flags privilege candidates. The Swarms API keeps a per-run log of the request, each agent's output and usage, so the firm can see exactly what was sent on each matter. Firms with engagement terms or outside counsel guidelines that constrain data handling should talk to us before sending client material, and the open-source swarms package runs the same patterns inside the firm's network.

Talk to sales

Which swarm type fits which legal task?

CouncilAsAJudge when a draft should be scored by independent judges before a lawyer reads it, MajorityVoting when each item needs an agreed call (citations, responsiveness), SequentialWorkflow for locate, extract and abstract pipelines, HeavySwarm for research memos, and PlannerWorkerSwarm when a data room index has to be turned into a queue of documents. All of them take the same agents list.

Swarm types on the Swarms API

Put a reviewed memo in front of your attorneys

Create a Swarms Cloud account, copy the contract review council above, and paste in your own playbook rules. The memo and its run log show up in your account on the first call.

New Swarms Cloud accounts start with $5 in API credits. Enterprise teams can talk to us about volume pricing, data handling and deployment options.