はじめに:テキスト出力から空間操作へのパラダイムシフト

従来のAIコーディングエージェントは、テキストの生成と編集を主眼に設計されている。コードファイルへの追記、リファクタリング、テストの生成——これらはすべて「文字列の操作」として抽象化できる。しかし、UIプロトタイピングの領域に踏み込むと、単なる文字列操作では扱えない次元が現れる。「このボックスを左に50px動かして」「この四角形の高さを1.5倍に」——こうした指示には、空間上の位置関係、サイズ、色、レイヤー順序といった幾何学的メタデータが不可欠である。

Excalidrawのようなキャンバスベースのツールでは、この空間情報がDOM要素としてではなく、SVGやCanvas上の図形オブジェクトとして管理される。各図形には固有のID、座標、回転角、スタイル属性が割り当てられ、キャンバス全体の状態はこれら図形オブジェクトの集合として表現される。つまり、テキスト編集エージェントが「行」と「列」を単位にしていたのに対し、キャンバス操作では「座標」と「形状」が基本単位になる。この違いが、エージェントの出力空間とキャンバスの幾何学空間をマッピングするブリッジ層の必要性を生み出している。

本記事では、この移行に伴う3つの設計課題——座標系の変換、非構造化データの構造化、エージェントとの双方向通信——に焦点を当てる。Drawgentのようなツールは、単なるラッパーではなく、LLMが出力する自然言語や簡略化されたJSONと、Excalidrawが要求する厳密な図形オブジェクト構造の間に立つ変換層として機能する可能性がある。この変換層の設計判断を理解することは、自らのプロジェクトで類似のブリッジを実装する場合の指針となる。

Drawgentのアーキテクチャ概要:Rustバイナリが担う役割

Drawgentは、Claude Code、Codex、またはopencodeをExcalidrawキャンバスに接続する単一のRustバイナリとして実装されている。この「単一バイナリ」という設計は、デプロイの簡素さだけでなく、エージェントCLIとキャンバスの間に立つ中間層の遅延を最小化するというパフォーマンス上の意図も含まれている。

ソースコードの言語構成を見ると、Rustが大半を占め、JavaScriptやCSSが補助的な役割を果たしている。この偏りには明確な設計判断がある。キャンバス上の図形操作は、座標の計算、変換行列の適用、バウンディングボックスの衝突判定など、頻繁な数値処理を伴う。これらの処理をRustで実装することで、ガベージコレクションによる停止やバウンダリチェックのオーバーヘッドを排除できる可能性がある。さらに、エージェントとの通信は標準入出力やローカルソケットを介したプロセス間通信であり、そのパース処理もRustの所有権モデルによってメモリ安全性が保証される。

JavaScriptとCSSの部分は、ExcalidrawキャンバスとのDOM連携やUI表示部分に割り当てられている。ExcalidrawはWebブラウザ上で動作するため、最終的な図形の描画やユーザー操作の捕捉はJavaScript層で行う必要がある。Rustがビジネスロジックとデータ変換の中心を担い、JavaScriptがブラウザとの境界を担うというハイブリッド構成である。

flowchart LR
    A["エージェントCLI"] -->|"自然言語指示"| B["Drawgent (Rustバイナリ)"]
    B -->|"構造化図形コマンド"| C["Excalidrawキャンバス"]
    C -->|"キャンバス状態 (JSON)"| B
    B -->|"プロンプト形式のコンテキスト"| A

この図に示すように、Drawgentは双方向の変換を行う。エージェントからキャンバスへ向かう方向では、自然言語の指示をExcalidrawが解釈できる図形オブジェクトのJSONに変換する。逆方向では、キャンバスの現在の状態をLLMが解釈可能な形式に圧縮してプロンプトに埋め込む。この往復のたびに座標系の変換と情報選択が発生するため、変換処理の性能が全体の応答速度に影響を与える可能性がある。

セットアップの深層:アダプターと環境依存性の管理

drawgent setupコマンドは、エージェントCLIの検出、ログイン状態の確認、ACP(Agent Communication Protocol)ブリッジの準備、ヘッドレスChromeの起動環境の構築を行い、最終的にconfig.tomlを生成する。この一連の処理が単一コマンドに集約されているのは、ユーザーが各エージェントの個別設定を把握する必要なく、キャンバス接続まで到達できるようにするためである。

ここで重要な技術的制約が現れる。Claude CodeとCodexとの接続にはNode.js 18以上のnpm環境が必須であり、アダプターは~/.cache/drawgent/adapters配下にインストールされる。このアダプターパターンは、各エージェントの仕様の違いを隔離する設計である。Claude Codeが標準入出力でJSON Linesをやり取りするのに対し、Codexは異なるプロトコルを使う場合がある。これらの違いをDrawgent本体に実装すると、エージェント側の仕様変更のたびにコアロジックを修正する必要が生じる。アダプターにカプセル化することで、本体は抽象化されたインターフェースのみを参照すればよい。

ヘッドレスChromeがセットアップに含まれる理由もここにある。Excalidrawキャンバスの状態を正確に読み書きするには、ブラウザのDOMやCanvasコンテキストへのアクセスが必要であり、そのための安定したランタイムとしてNode.js環境が利用されている。ヘッドレスChromeはGUIを表示せずにDOMを操作できるため、自動化パイプラインに組み込みやすい。

エージェントNode.js要件アダプターインストール先備考
Claude Code≥ 18 (npm)~/.cache/drawgent/adaptersACPブリッジ経由で接続
Codex≥ 18 (npm)~/.cache/drawgent/adaptersACPブリッジ経由で接続
opencode—~/.cache/drawgent/adapters対応エージェントとして接続可能

アダプターを~/.cache/配下に置く判断には、バージョン管理と隔離の意図がある。~/.config/やプロジェクト配下ではなくキャッシュディレクトリに置くことで、Git管理の対象外となり、環境間の差異を最小限に抑えられる。また、drawgent setupの再実行でアダプターが更新される場合、プロジェクトのソースコードには影響を与えない。この設計は、エージェントのアップグレードが頻繁に起こる環境において特に有効である。

課題1:座標系の変換と幾何学的マッピング

LLMが「この四角を右に50px動かして」と出力した場合、DrawgentがそれをExcalidrawの図形座標系に適用するまでに、少なくとも2段階の座標変換が発生する。1段階目はエージェントの出力する相対座標(「右に50px」)をキャンバス上の絶対座標に変換する処理、2段階目はキャンバスのビューポート座標(ユーザーが今見ている画面座標)とワールド座標(図形が実際に存在する座標)の間のマッピングである。

原点とスケールの不一致

Excalidrawの図形オブジェクトは、x, y, width, height, angleなどのプロパティを持つ。ここで問題になるのは、LLMが「中心」を基準に位置を推論する傾向がある一方、Excalidrawの座標系は図形の左上を基準にしている点である。さらに、キャンバスのズームレベルが100%でない場合、ユーザーが視覚的に「50px」と認識する距離と、ワールド座標上の50pxは一致しない。

ブリッジ層では、このズレを吸収するために以下のような変換パイプラインを設計する必要がある。

// ビューポート座標 → ワールド座標の変換(概念例)
// viewport: ユーザーが見ている画面のオフセットとスケール
fn viewport_to_world(
    vx: f64, vy: f64,
    pan_x: f64, pan_y: f64,
    zoom: f64
) -> (f64, f64) {
    let wx = (vx - pan_x) / zoom;
    let wy = (vy - pan_y) / zoom;
    (wx, wy)
}

// 相対移動の適用(ワールド座標上)
fn apply_relative_move(
    elem_x: f64, elem_y: f64,
    dx: f64, dy: f64
) -> (f64, f64) {
    (elem_x + dx, elem_y + dy)
}

このコードは擬似コードであり、実際のDrawgentの実装とは異なる。しかし、設計上のポイントは明確である。移動(translate)と拡大縮小(scale)を分離して処理し、angle(回転)が適用されている場合は回転行列による変換を先に適用する必要がある。これらの順序を誤ると、回転済み図形への相対移動が意図しない方向に適用される。

ビューポート依存の落とし穴

最も頻繁に発生するバグは、ズームレベルが変化した後にエージェントが指示を出した場合に、図形が意図した位置に移動しないケースである。これは、ビューポート座標をワールド座標に変換する際に現在のzoom値を参照しているため、zoomが変更された瞬間に同一の指示でも結果が変わる。対策として、エージェントへのプロンプトには常にワールド座標で現在の図形位置を通知し、ビューポート座標をプロンプトに含めない設計が安全である。

stateDiagram-v2
    S1["エージェントの自然言語指示\n(例: 右に50px)"] --> S2["相対座標の抽出\n(dx=50, dy=0)"]
    S2 --> S3["ワールド座標への変換\n(pan/zoomを補正)"]
    S3 --> S4["回転補正\n(angleが0以外の場合)"]
    S4 --> S5["Excalidraw図形オブジェクトに適用\n(x, yを更新)"]
    S5 --> S6["キャンバス再描画"]

この変換パイプラインの各段階でエラーが蓄積すると、複数回の操作後に図形が意図した位置から大きくずれる。テストでは、ズーム100%・200%・50%、panあり・なし、angle 0°・45°・90°の組み合わせを網羅的に検証することが推奨される。

課題2:非構造化データから構造化JSONへの逆変換

Excalidrawのキャンバス状態は、各図形要素のID、type(rectangle, ellipse, arrow, text, frameなど)、位置・サイズ、スタイル(strokeColor, fillStyle, strokeWidth)、レイヤー順序(z-index相当の配列順)を含むJSON配列として表現される。このJSONは数十個の図形が重なると数千行に達し、LLMのコンテキストウィンドウにそのまま投入するのは現実的ではない。

キャンバス状態の要約戦略

DrawgentがLLMにキャンバス状態を伝える際、以下のような情報階層を設計する必要がある。

  • 必須情報: 図形のID、type、x, y, width, height。これがないと位置指定が不可能。
  • 推奨情報: strokeColor、fillStyle。配色の指示を出すために必要。
  • 省略可情報: 個別のバインド(arrowの接続先)、frameのネスト構造、boundElementsの完全なマッピング。

この階層化の判断基準は、LLMが「次の操作を決定するために必要な最小情報」である。例えば、ユーザーが「赤い四角を青に変えて」と指示した場合、LLMはどの四角が赤いかを識別するためにstrokeColorが必要だが、その四角のboundElements(どの矢印が接続されているか)は不要である。

逆変換:指示から図形JSONへ

LLMが「(200, 300)に100x80の四角形を作成」と出力した場合、DrawgentはこれをExcalidrawの要素JSONに変換する。ここで注意すべきは、Excalidrawの図形には一意のID(通常はナノ秒ベースのタイムスタンプやUUID)が必須であり、Drawgentがこれを生成する必要があることである。また、arrowやlineの場合はstartBinding, endBindingなどの接続情報も含まれるため、単なる座標だけでは不十分な場合がある。

// LLM出力からExcalidraw要素への変換(概念例)
// 実際のExcalidrawスキーマとは異なる可能性あり
fn create_element_from_instruction(instr: &Instruction) -> Element {
    match instr.shape {
        ShapeType::Rectangle => Element {
            id: generate_id(),
            type: "rectangle".to_string(),
            x: instr.x,
            y: instr.y,
            width: instr.width,
            height: instr.height,
            stroke_color: instr.color.unwrap_or("#1e1e1e"),
            ..default()
        },
        ShapeType::Arrow => {
            // 接続先の解決が必要(IDによる参照)
            resolve_bindings(instr, &canvas_state)
        }
    }
}

情報の損失が最も問題になるのは、レイヤー順序である。ExcalidrawではJSON配列のインデックスが描画順序(下の要素が先)を決定する。LLMに「この矢印を四角形の手前に移動して」と指示された場合、Drawgentは配列内の位置を再計算する必要がある。しかし、LLMには配列インデックスを直接指定させるのは不自然であり、「手前」「奥」といった相対的な表現を解釈するロジックをブリッジ層に実装する方が実用的である。

プロンプトサイズのトレードオフとしては、図形数が多くなるほど要約の粒度を粗くせざるを得ない。一つの戦略として、ユーザーが現在選択している図形の近傍(一定距離以内)の要素のみ詳細に送信し、それ以外はIDとtypeのみで送信する方式が考えられる。これにより、プロンプトサイズを一定以下に抑えつつ、局所的な操作には十分なコンテキストを提供できる。

課題3:エージェントとの双方向通信とステート管理

DrawgentはACP(Agent Communication Protocol)ブリッジを通じて、エージェントCLIとExcalidrawキャンバスの間でリアルタイムにデータをやり取りする。この双方向通信の設計において、最も難しいのは「LLMの応答待ち時間」と「ユーザーの即時操作」が並行して発生する際の状態整合性である。

非同期処理と状態競合

LLMが数十秒かけて思考し、出力を返す間に、ユーザーがキャンバス上で図形をドラッグして移動させた場合、LLMが返した指示は古いキャンバス状態を前提としている。このまま適用すると、ユーザーが移動させた図形が元の位置に戻ったり、意図しない位置に新しい図形が作成されたりする。

Drawgentがこの問題を扱うための設計判断は、以下のように整理できる。

  • キューイング: エージェントからの指示を即座に適用せず、キューに積んで順序立てて処理する。これにより、複数指示の同時到着時の適用順序が保証される。
  • 状態スナップショット: 各指示を適用する直前にキャンバス状態のスナップショットを保存し、失敗時にロールバック可能にする。
  • 競合検出: 指示が参照している図形IDが、適用時点で既に削除されていた場合、その指示をスキップするかユーザーに確認を求める。

Rustが選ばれる理由:データ競合のコンパイル時検出

双方向通信では、エージェントからの応答を受信するスレッドと、ユーザー操作を処理するスレッドがキャンバス状態に同時にアクセスする。Rustの所有権システムは、このデータ競合をコンパイル時に検出するため、実行時のデッドロックやデータ破損のリスクを構造的に排除できる。JavaScriptで同等の安全性を確保するには、MutexやActorモデルを手動で実装する必要があり、バグの発生率が上がる。

sequenceDiagram
    participant U as ユーザー
    participant C as Excalidrawキャンバス
    participant D as Drawgent(Rust)
    participant A as エージェントCLI

    U->>C: 図形をドラッグ
    C->>D: 状態変更イベント
    D->>D: キャンバス状態をJSONにシリアライズ
    D->>A: コンテキスト付きプロンプト送信
    A->>A: LLMによる推論(非同期)
    A->>D: 指示JSONを受信
    D->>D: キューに追加・競合検出
    D->>C: 図形オブジェクトを適用
    C->>U: キャンバス再描画

このシーケンスの中で、Dの「競合検出」が最も設計判断を要する箇所である。単純なタイムスタンプ比較では、LLMが参照していた図形がユーザーによって削除されたケースを捕捉できない。図形IDをキーとした存在チェックと、参照された座標周辺の状態変更履歴の照合を組み合わせることで、適用可否を判定するロジックが実用的である。

ロールバックの実装では、Excalidraw自体がundo/redo機構を持つが、Drawgentが適用した操作とユーザーの操作を区別してundoできるようにするため、Drawgent側の適用履歴を別途管理する必要がある。これにより、「エージェントの直前の操作を取り消す」というユーザー操作が、ユーザー自身の操作のundoと混同されない。

実装パターン:アダプターのインターフェース定義と差分ハンドリング

Claude Code、Codex、opencodeといったエージェントは、それぞれ出力フォーマットや通信プロトコルが異なる。テキストストリームで出力するものもあれば、構造化されたJSONを返すものもある。この差異をDrawgent本体に直接実装すると、新エージェントの追加たびにコアロジックの修正が避けられなくなる。そこでアダプターパターンが採用され、各エージェント固有のプロンプトテンプレートと出力パースロジックがカプセル化されている。

アダプターインターフェースの定義

Drawgent本体がアダプターに要求するインターフェースは、大きく分けて「キャンバス状態の送信」と「エージェント出力の受信・パース」の2つに収束する。Rustで表現すると、以下のようなトレイトに相当する。

// アダプターが実装すべきインターフェース(概念例)
trait AgentAdapter {
    /// キャンバス状態をエージェントが解釈可能な形式に変換して送信
    fn send_canvas_state(&self, state: &CanvasState) -> Result<(), AdapterError>;

    /// エージェントの出力を受信し、統一的な図形操作コマンドに正規化
    fn receive_instruction(&self) -> Result<ShapeCommand, AdapterError>;

    /// エージェントの接続状態を確認
    fn is_connected(&self) -> bool;
}

このトレイトの設計で意識しているのは、メソッドの粒度を「1回の往復」に揃えている点である。送信側ではExcalidrawのJSON状態をエージェントが解釈可能な形式に変換し、受信側ではエージェントの出力を統一的な図形操作コマンドに正規化する。この正規化の段階で、エージェント固有の冗長な出力(思考過程のテキストや確認の問いかけなど)をフィルタリングすることで、Drawgent本体のキューイング処理に与えるノイズを抑制できる。

差分ハンドリング:フル状態とインクリメンタル更新

キャンバス状態をエージェントに送信する際、毎回フルJSONを送信するとプロンプトサイズが膨張する。特に図形数が数十に達するキャンバスでは、このコストが推論の正確性を損なう要因になる。そこで、前回の送信時からの変更分(差分)のみをインクリメンタルに送信する方式が有効である。

差分の単位は図形IDである。アダプターは前回の送信時に送信した図形IDの集合を保持し、今回のキャンバス状態と比較することで、追加・削除・変更の3種類に分類する。変更の判定には、位置・サイズ・スタイルの各フィールドを比較し、閾値を超える変化がある場合にのみ「変更」としてマークする。これにより、ユーザーが図形をわずかにドラッグしただけでエージェントにフル状態を再送信する事態を回避できる。

// 差分の分類(概念例)
enum ElementDiff {
    Added(Element),
    Removed { id: String },
    Modified { id: String, changed_fields: Vec<Field> },
    Unchanged,
}

fn compute_diff(
    prev: &HashMap<String, Element>,
    current: &CanvasState
) -> Vec<ElementDiff> {
    // 追加: currentにありprevにない
    // 削除: prevにありcurrentにない
    // 変更: 両方に存在するがフィールド値が閾値以上異なる
    // 不変: 両方に存在し変化なし
    todo!()
}

拡張性の実効性を測る基準として、新アダプターの作成時にDrawgent本体のソースコードを1行も変更せずに済むかどうかがある。アダプターパターンが正しく機能しているなら、この条件を満たすはずである。逆に、新エージェントの追加で本体の修正が必要になる場合は、抽象化の境界線が不適切である可能性が高く、インターフェースの再設計を考慮すべきサインである。

落とし穴:セキュリティと権限管理

DrawgentがヘッドレスChromeを介してExcalidrawキャンバスにアクセスする構成は、機能面では便利である一方で、セキュリティモデルの観点で注意を要する。ブラウザ環境で動作する以上、CORSポリシーやSame-Origin Policyの影響を受ける可能性があり、特にローカル以外のエンドポイントからキャンバス状態を読み書きする場合、これらの制約がボトルネックになることがある。

エージェント出力の信頼境界

より本質的なリスクは、エージェントが生成する指示自体が予期しない内容を含む可能性がある点にある。LLMの出力は確率的であり、プロンプトインジェクションやハルシネーションによって、意図しない図形の作成や既存図形の破壊的な変更が発生し得る。Drawgentがキャンバスへの書き込み権限を直接持つ構成では、エージェントの出力がそのままキャンバスに反映されるため、このリスクが直接的にユーザーの作業成果物に影響する。

対策として設計上考慮すべきは、適用前の検証レイヤーの導入である。エージェントから受信した図形操作コマンドを、適用前に以下のようなチェックに通すことで、破壊的な操作を回避できる。第一に、操作対象の図形IDが現在のキャンバスに存在するかの存在チェック。第二に、座標値がキャンバスの合理域内にあるかの範囲チェック。第三に、一度の応答で適用される操作件数が閾値を超えていないかの異常検知。これらのチェックはRustの型システムやResult型を活用することで、コンパイル時と実行時の両方で安全性を担保できる。

機密情報の取り扱い

drawgent setupが生成するconfig.tomlには、エージェントの認証情報やログイン状態が含まれる可能性が高い。このファイルが平文で保存されている場合、同一マシンの他のプロセスやユーザーによって読み取られるリスクがある。ファイルパーミッションを600(所有者の読み書きのみ)に制限するのは最低限の対策であり、さらにAPIキーをOSのキーチェーンや環境変数に委譲し、config.tomlには参照情報だけを残す設計も検討に値する。特にチーム開発環境では、設定ファイルが誤ってバージョン管理システムにコミットされる事故が頻発するため、.gitignoreへの登録とプレコミットフックによる検知を併用する運用が推奨される。

運用と拡張:カスタムアダプターとプロンプトエンジニアリング

Drawgentのアーキテクチャがアダプターパターンを採用していることの運用上の恩恵は、社内の独自LLMや社内ツールへの接続が原理的に可能である点にある。公開されているエージェントCLIに限定されないこの設計は、データが社外に出せない環境や、特定のプロンプト仕様でしか動かない内部モデルを統合する場合に特に有効である。

カスタムアダプター作成の実務的な手順

カスタムアダプターを作成する際の核心は、対象エージェントの出力フォーマットに対するパースロジックの調整にある。多くのLLMは、構造化出力を要求しても自由記述のテキストを返すことがある。この場合、出力の中に埋め込まれたJSONブロックを正規表現やパーサーで抽出し、Drawgentが期待する図形操作コマンドのスキーマにマッピングする処理が必要になる。このマッピングの堅牢性を高めるには、抽出に失敗した場合のフォールバック(例:「パース不能な出力を受け取った」旨をキャンバス上に通知図形として表示する)を実装するとよい。サイレントに失敗すると、ユーザーはエージェントが応答しなかったのか、出力が破損したのかを区別できなくなる。

プロンプトエンジニアリングとコンテキスト最適化

キャンバスの状態をLLMに正しく理解させるためには、送信するコンテキストの内容設計が成果に直結する。Excalidrawの生JSONは、図形1つにつき数十のフィールド(ID、タイプ、位置、サイズ、色、線幅、角丸、レイヤー順序など)を含むため、図形数が数十に達するとプロンプトサイズが急速に膨張する。この制約に対し、以下の戦略が有効である。

  • 情報の階層化:LLMに送信するJSONから、操作に直接関係しないメタデータ(作成日時、最終更新者など)を除去し、ID・タイプ・位置・サイズ・色のみを残す。
  • 相対記述の採用:絶対座標ではなく、「図形Aの右に50px間隔で図形B」といった相対的な関係で状態を記述し、座標値の桁数を削減する。
  • 操作パターンのテンプレート化:「矩形作成」「線分引伸」「グループ化」のように頻出する操作を、プロンプト内でショートカット記法として定義し、毎回フルJSONを生成させる必要をなくす。

これらの最適化は、LLMのコンテキストウィンドウの制約だけでなく、推論の正確性にも寄与する。ノイズの少ない構造化されたコンテキストを与えることで、LLMが操作対象を誤認する確率が低下する。特に図形が密集する領域では、IDと位置の対応関係を明示的に提示しないと、LLMが隣接する図形を混同して操作対象を誤るケースが報告されている。

まとめ:GUI自動化の未来とDrawgentの位置づけ

Drawgentは、LLMの出力空間(テキスト)とキャンバスの幾何学空間(座標・形状・スタイル)の間にブリッジを架ける単一のRustバイナリとして実装されている(Drawgentの解説記事)。ソースコードの構成は、計算集約的な座標変換と状態管理をRustに、ブラウザとのDOM連携をJavaScriptに割り当てるハイブリッドアーキテクチャを反映している。

本記事で扱った3つの設計課題――座標系の変換、非構造化データの構造化、エージェントとの双方向通信――は、いずれも「LLMはテキストを扱うが、キャンバスは幾何学を扱う」という根本的な非対称性から生じる。この非対称性を吸収するブリッジ層の設計品質が、最終的なプロトタイピング体験の良し悪しを決定する。特に、座標変換の正確性と双方向通信の競合処理は、ユーザーが「エージェントが自分の意図を正確に理解している」と感じるかどうかの分かれ目になる。

今後の発展として期待される方向性には、以下の2つが挙げられる。第一に、より高度な幾何学演算のサポートである。図形の回転、曲線(ベジェ曲線)の制御点操作、図形間の制約関係(平行・垂直・等間隔)の維持など、現在の単純な平行移動・拡大縮小を超えた操作が求められる場面は多い。第二に、複数キャンバス間の連携である。システム全体像を1枚のキャンバスに、詳細なフローを別のキャンバスに配置し、エージェントがそれらを横断的に操作できれば、大規模なプロトタイピングの生産性がさらに向上する。

エンジニアがこれらの設計判断を自らのプロジェクトに適用する際に重要なのは、「LLMの出力を信頼しない」ことを前提に設計することである。エージェントの出力は常に検証・フィルタリングの対象であり、キャンバスへの書き込みは可逆(undo可能)であるべきである。この原則を守ることが、GUI自動化の信頼性を担保する最小条件となる。

関連記事

参考

本記事は海外の技術トレンド「Drawgent: Coding agent on a live Excalidraw canvas」(Hacker News)で話題のテーマをもとに、両儀システムソリューションズが独自に解説したものです。