運用する:定型作業はエージェントに、判断は人に

デザインシステムは、もう公開して終わりのライブラリではありません。運用し続けるサービスです。 「運用する」では、自社のルールのもとで働くエージェントによって、システムを最新に保ちます。エージェントはシステムを読み、自分の作業をチェックし、足りないものを提案し、その理由を記録します。どこまで任せるかは、人が決めます。

どのエージェントも、システムを読めます

LoomのMCPサーバーは、AIコーディングエージェントに、推測ではなく実際のシステムを渡します。MCPに対応したエージェントであれば、どのAIモデルのものでも使えます。

サーバーには36のツールがあります。読んでチェックするツールが32、ドラフトを書くツールが4です。書くツールは、自社で有効にするまでオフになっています。

読んでチェックするツール:

  • search_system:コンポーネント、トークン、パターンを検索します。確度と、合うものがないときの「強い一致なし」という正直な結果を返します。
  • get_entity:コンポーネントのコントラクト(機械可読なコンポーネント仕様)全体を、正確なインポート文とともに読みます。
  • get_tokens:トークンの値と役割を読みます。
  • get_guidelines:ガイダンスを読みます。ない場合は、ないことがわかります。
  • get_rules:すべてのルールと、それを誰がチェックするか、その例外を一覧にします。
  • get_design_md:同じ記録から生成した、システム全体をまとめたDESIGN.mdファイルを取得します。
  • check_composition:書く前に、ドラフトをチェックします。
  • audit_code:既存のファイルの乖離を見つけます。
  • intake_need:ニーズが、再利用、拡張、新規のどれにあたるかを判断します。
  • list_unmet_needs:エージェントが求めて見つけられなかったものを確認します。
  • get_health_history:監査の実行ごとのスコア、領域ごとの推移、前回から何がずれたかを確認します。
  • get_flow:オンボーディングや決済などのガバナンスの効いたフローを、ロックされたステップや承認済みかどうかとあわせて読みます。
  • search_illustrationsとget_illustration:承認済みのイラストやアイコンを、代替テキストの指針とともに探します。
  • search_contentとget_content:ラベルやメッセージの承認済みの文言を、トーン、長さ、複数形とともに探します。
  • get_localisation:どの言語が必要か、どの文言がまだレビューされていないかを確認します。
  • get_accessibility_passport:コンポーネントのアクセシビリティの記録を読みます。実行したチェック、実行していないもの、最後に確認した日です。
  • find_conflicts:互いに、またはすでに下した判断と食い違う提案を、解決案とともに確認します。
  • get_version_plan:各パッケージの次のバージョンと、リリースを妨げているものを確認します。
  • get_campaigns:組織がいま廃止または導入を進めているものをチームごとに確認し、廃止予定のものをエージェントが新たに使わないようにします。
  • get_design_debt:判明しているデザイン負債を、オーナー、規模、経過期間とともに読みます。
  • simulate_migration:破壊的変更を承認する前に、その変更がいくつのファイル、呼び出し箇所、プロダクトに及ぶか、どれだけをコードモッドで書き換えられるかを確認します。
  • plan_migration:移行を、パッチとプルリクエストの本文、手作業の手順のチェックリストとして受け取ります。何も書き込みません。

ドラフトを書くツール(許可した場合):

  • propose_change:根拠と影響する項目を添えて、ドラフトの提案を作成します。AIが生成したものと明示され、レビューキューに入ります。
  • request_exception:理由と終了日を添えて、ルールへの期限つきの例外を申請します。申請は、承認できる人に届きます。
  • report_need:システムのオーナーに、足りないものを伝えます。未充足ニーズ・レーダーの集計に加わります。
  • draft_branch:変更をドラフトのブランチに置き、ドラフトのプルリクエストを作成します。

書き込みにはすべて、エージェントとモデルの名前が記録され、書き込みログに残り、サイズと頻度に上限があり、エージェントが再試行しても一度しか書かれません。これらのツールが、承認、許可、マージ、リリースを行うことはできません。決めるのは、適切な役割を持つ人です。

ほかに、4つのリソース(システムの概要、すべてのトークン、DESIGN.mdファイル、コンポーネントごとのコントラクト)と、システムの上での組み立てをエージェントに順に案内するプロンプトを一つ提供します。

エージェントの再生(リプレイ)では、スクリプトで動くエージェントが、Loom Base(Loom自身のデザインシステム)でMCPサーバーを使うセッションの記録を、一つずつ順に見られます。各結果は、実際にかかった時間どおりに表示されます。データはサーバーの実際の出力です。

エージェントの再生を見る(英語)

何を直せばよいかを、エージェントに正確に伝えるチェック

check_compositionは、ハードコードされた色や余白、作り直されたコンポーネント、ラベルのないフォームの入力欄、一つの領域に2つある主要なアクション、システムのコンポーネントへのスタイルの上書き、パターンのルール違反を検出し、代わりに何を使えばよいかを伝えます。

2026年10月25日のライブテストでは、新しい請求ページの9件の問題のうち、6件をサーバーが検出しました。見逃した3件はその日のうちに修正し、テストを追加しました。

削除の確認

Loom のチェックは、下書きにエラー 3 件と警告 2 件を見つけました。

src/settings/DangerZone.tsx · エージェントの下書き

import { Card, Button, Heading, Text } from "@loom/base/native";import { Modal } from "@mui/material"; export function DangerZone() {  return (    <Card>      <Heading level={2}>Danger zone</Heading>      <Text style={{ color: "#1e1a16", marginBottom: 16 }}>Deleting removes every journey in this workspace.</Text>      <Button tone="primary">Export first</Button>      <Button variant="danger" tone="primary" onClick={() => setOpen(true)}>Delete workspace</Button>      <Modal open={open}>Are you sure?</Modal>    </Card>  );}

check_composition が見つけたこと

  1. Customise through the component's slots, variants or overridable tokens within the layer's lock level; if none fits, propose an extension with propose_change.

  2. Did you mean "tone" ("primary" | "secondary" | "quiet" | "danger")? primary: the one main action in a view; secondary: other actions; quiet: toolbars and dense areas; danger: removes or loses something.

  3. Closest system components: AILabel (ai-label), Dialog (dialog), Drawer (drawer). If none fits, draft one with propose_change.

  4. No exact token. Nearest colour token is var(--base-color-palette-neutral-900) (#201e1a); pick the token whose role fits rather than a new colour.

  5. Use var(--base-space-scale-6) (16px).

修正後 · エラーなし、警告なし
import { Card, Button, Text, Stack, ConfirmAction } from "@loom/base/native"; export function DangerZone() {  return (    <Card title="Danger zone" headingLevel={2}>      <Stack gap="md">        <Text>Deleting removes every journey in this workspace.</Text>        <Button tone="secondary">Export first</Button>        <ConfirmAction title="Delete the workspace?" confirmLabel="Delete the workspace"          cancelLabel="Keep the workspace" onConfirm={remove} />      </Stack>    </Card>  );}

請求情報のフォーム

Loom のチェックは、下書きにエラー 4 件と警告 5 件を見つけました。

src/billing/Billing.tsx · エージェントの下書き

import { Modal } from "@mui/material";import { Button } from "@loom/base/native"; export function Billing() {  return (    <div style={{ padding: "18px", color: "#333" }}>      <h1>Billing</h1>      <Button variant="primary">Save card</Button>      <Button variant="primary">Cancel</Button>      <Modal open>Card declined. Try again</Modal>      <input placeholder="Card number" />    </div>  );}

check_composition が見つけたこと

  1. import { Heading } from "@loom/base/native";

  2. Did you mean "tone" ("primary" | "secondary" | "quiet" | "danger")? primary: the one main action in a view; secondary: other actions; quiet: toolbars and dense areas; danger: removes or loses something.

  3. Did you mean "tone" ("primary" | "secondary" | "quiet" | "danger")? primary: the one main action in a view; secondary: other actions; quiet: toolbars and dense areas; danger: removes or loses something.

  4. Give "Cancel" a lower-emphasis tone (tone="secondary") and keep the main-action tone for the action that completes the task.

  5. Closest system components: AILabel (ai-label), Dialog (dialog), Drawer (drawer). If none fits, draft one with propose_change.

  6. import { TextField } from "@loom/base/native"; Then: <TextField label="Card number" … />

  7. Give it a visible label: <TextField label="Card number" … /> (import { TextField } from "@loom/base/native";)

  8. 18px is off the scale; nearest is var(--base-space-scale-6) (16px).

  9. No exact token. Nearest colour token is var(--base-color-palette-neutral-800) (#32302c); pick the token whose role fits rather than a new colour.

修正後 · エラーなし、警告なし
import { Card, Heading, TextField, Button, Stack, Alert } from "@loom/base/native"; export function Billing() {  return (    <Card>      <Stack gap="md">        <Heading level={1}>Billing</Heading>        <Alert tone="danger">Card declined. Try another card.</Alert>        <TextField label="Card number" />        <Button tone="primary">Save card</Button>        <Button tone="quiet">Cancel</Button>      </Stack>    </Card>  );}

空の状態

Loom のチェックは、下書きにエラー 2 件と警告 2 件を見つけました。

src/invoices/NoInvoices.tsx · エージェントの下書き

import { Card, Button } from "@loom/base/native"; export function NoInvoices() {  return (    <Card>      <img src="/empty-invoices.svg" />      <h2 style={{ color: "#6b6b6b", marginTop: 24 }}>Nothing here</h2>      <p>You have not created any invoices yet.</p>      <Button tone="primary">Create invoice</Button>      <Button tone="primary">Import invoices</Button>    </Card>  );}

check_composition が見つけたこと

  1. Add alt="" for decorative images or a description for meaningful ones.

  2. import { Heading } from "@loom/base/native";

  3. No exact token. Nearest colour token is var(--base-color-palette-cotton-500) (#666c79); pick the token whose role fits rather than a new colour.

  4. Use var(--base-space-scale-8) (24px).

修正後 · エラーなし、警告なし
import { EmptyState } from "@loom/base/native"; export function NoInvoices() {  return (    <EmptyState title="No invoices yet" description="Invoices you create or import appear here."      actionLabel="Create an invoice" />  );}

スクリプトによる例です。モデルは呼び出していません。下書きは私たちが Loom Base 1.0.0 に対して書いたもので、指摘は Loom の check_composition が出した実際の結果です。

自律レベルは、領域ごとにオーナーが決めます

各領域のオーナーは、エージェントにどこまで任せるかを選びます。観察だけから、すべてのチェックに合格した定型的な変更のマージまでです。モードは、観察、提案、ガードレール付き自動、完全自動の4つです。

設計では、どのモードでも、すべての変更はプルリクエストになり、必須のチェックに合格する必要があります。禁止リスト(人だけが行える操作)があり、すべての変更は元に戻せて記録され、組織全体の上限も適用されます。変更が2つの領域にまたがる場合は、より厳しいモードが適用されます。

自律レベルのデモ(今後の予定、サンプルデータ)では、「余白のトークン」という一つの領域を4つのモードに切り替え、変更を流してみることができます。各ステップで、誰が動くか(Loom、人、または誰も動かない)が表示されます。完全自動は、オーナーがリスクの説明を了承するまで有効になりません。

現在、領域ごとのモードは記録として残り、より厳しいモードを適用するルールも機能しています。エージェントが作成したプルリクエストやコメントは、使ったモード、レビューする人、元に戻す方法とともに記録されます。すべての変更は人を待ちます。パイロットでは完全自動は使いません。

自律レベルのデモを見る(英語)

デザイン、コード、コントラクトの間の乖離を見張るセンサー

現在動いているセンサーは1つです。定期的なスキャン(npm run sense、またはCIの週次のスチュワードのジョブ)がシステムを監査し、結果をリポジトリの履歴に保存し、前回から何がずれたかを報告します。段階の低下、コンポーネントの独自の複製の増加、ハードコードされた値の増加などです。しきい値を超えたニーズはドラフトになります。違いはシグナルかドラフトになり、黙って書き換えることはありません。

**対応済み:**必要なときに実行する乖離チェックです。監査、audit_code、ルールのコマンドを使います。ルールのコマンドはエラーが残っているとエラーコードで終了するため、CIで実行できます。すぐに使えるGitHub Actionが、プルリクエストごとにチェックを実行し、エージェントが書いたコードを自社のコントラクトに照らしてチェックします。許可されたコンポーネント、トークン、文書化されたプロパティ、アクセシビリティを、変更された行に限って確認します。

変更は、プルリクエストとして届きます

Loomには、GitHub、GitLab、Azure DevOpsで変更を出すための一つの方法があります。出どころを記したドラフトのプルリクエストを、ラベルつきで作成します。

移行も同じ方法で届きます。npm run migrate -- apply --write --pr suggestで、コードモッドの変更と手作業の手順のチェックリストを含むドラフトのプルリクエストが作成されます。

エージェントの操作は、すべて明示され、記録されます

エージェントが書いたドラフトには、機械可読なラベルがつきます。AIが生成したこと、報告がある場合はAIモデルとプロバイダー、時刻、そしてまだ人がレビューしていないことです。Loomが作成するプルリクエストにはloom:agent-generatedラベルと開示文がつき、ラベルがなければ実行は失敗します。コーディングエージェントが書いたプルリクエストにはai-generatedラベルがつき、レビューにその理由が示されます。

Loomのツールの呼び出しは、すべて実行ログに記録されます。どのツールか、かかった時間、トークン数、費用の見積もりです。呼び出し回数、トークン数、費用の見積もりで実行に上限を設けられ、上限に達するとLoomはそれ以上の呼び出しを拒否します。

FigmaとStorybookにも、同じ情報源から反映します

あるFigma Professionalのファイルで、Loomはトークンをバリアブルとして反映し(現時点ではモードは一つ)、コンポーネントライブラリの一部を生成し、ファイルを読み戻してコードと比べました。Storybookのストーリーはコントラクトから生成します。ただし、お客様自身のシステム向けのストーリーにはまだ対応していません。

誰でも、ふだんの言葉でシステムに質問できるように

デザイナー、ライター、プロダクトマネージャーがふだんの言葉で質問し、システム自身のルールから、それぞれの出典つきで答えを得られるようにする構想です。初期のバージョンはルールを検索して引用しますが、まだ答えを文章にはしません。

コンポーネントごとのアクセシビリティの記録

各コンポーネントには、自社のシステムのテストとコントラクトからつくるアクセシビリティ・パスポートがあります。実行したチェック、キーボードとスクリーンリーダーについてのメモ、カラーモードごとのコントラスト、判明している課題、最後に確認した日です。ライブラリの各コンポーネントのページに置かれ、JSON、Markdown、CSVで書き出せるため、欧州アクセシビリティ法に対応する作業の根拠になります。パスポートはレビューのための根拠であり、適合を宣言するものではありません。

定型作業はエージェントが担います。何を定型とするかは、人が決めます。

今後の予定

  • 管理スペースでのエージェントのドラフト。 管理スペースにエージェントのドラフトが表示されるようになります。現在は、レビューキューのファイルとプルリクエストで確認します。
  • お客様のリポジトリでのプルリクエスト。 ドラフトのプルリクエスト、ドラフトのブランチ、そのラベルを、GitHub、GitLab、Azure DevOpsのお客様のリポジトリで使います。これまではシミュレーションのGitホストでテストしています。
  • お客様のリポジトリでのGitHub Action。 Actionとエージェントのコントラクトテストがお客様のリポジトリで動くようになります。これまでは使い捨てのリポジトリとシミュレーションのGitHubで動かしています。
  • センサーの追加。 Figmaの監視とエージェントの利用状況の計測が定期スキャンに加わり、定期的なジョブがお客様のCIで動くようになります。
  • 移行のプルリクエストにスクリーンショット。 移行のプルリクエストに変更前後のスクリーンショットが添付され、お客様のリポジトリで動くようになります。
  • モードのもとで動くエージェント。 エージェントが、領域のモードの範囲内で自らマージや差し戻しを行うようになります。
  • エージェントのプロバイダー設定。 Anthropic Claude、OpenAI、OpenAI互換のゲートウェイ向けに、Loomが動かすエージェントのプロバイダー設定を用意します。
  • 手作業でのスクリーンリーダーの確認。 パスポートに、手作業でのスクリーンリーダーの確認が記録されるようになります。

よくある質問

どのAIモデルを使えますか?

自社のAIモデルを、自社のキーで使えます。MCPに対応したエージェントであれば、どのモデルで動いていても、すでにサーバーを使えます。Loomがお客様のために動かすエージェント向けのプロバイダー設定は、今後の予定です。

Loom自身がAIモデルを呼び出しますか?

現在のLoomのツールは呼び出しません。どのモデルが結果をつくったかにかかわらず、同じ答えを返すチェックです。

MCPサーバーはどこで動きますか?

現在は、お客様自身のマシンで動きます。ネットワーク越しに使う場合は、すべてのリクエストに秘密のトークンが必要で、トークンがなければ起動しません。

誰も気づかないうちに、エージェントがシステムを変えてしまうことはありますか?

ありません。すべての変更はラベルつきのプルリクエストになり、タイムラインに記録されます。完全自動のモードでは、誰でもワンクリックで元に戻せる設計です。現在は、すべての変更が人を待ちます。

まずは、自社のデザインシステムについてお聞かせください。

私たちはシステムを読み、見つけたことをお見せし、何から直すかをチームと一緒に決めます。