高度なワークフロー向けの自動生成 GUI: Applied Intuitionのシナリオエディター
コードエディターから直感的な GUI へ: Applied Intuition のエンジニアリングチームは、データスキーマから動的なユーザーインターフェースを自動生成する高度なシステムを構築しました。彼らのスケーラブルなノーコードワークフロー変革の背景にあるアーキテクチャ上の判断と技術的解決策を解説します。

自動運転車の開発分野が進化するにつれ、強力でありながら使いやすいソフトウェアツールの必要性がますます高まっています。Applied Intuitionのプラットフォームは、主要な自動車メーカー向けに設計され、当初はコード中心のインターフェースを通じてエンジニアが複雑なシナリオを設計・シミュレートできる堅牢なシナリオエディターを提供していました。パワーユーザーや開発者は、コードエディターを使用するか、シーンに直接インタラクトすることで、WebGL でレンダリングされた 3D シーン内で動的なシナリオを設計・シミュレートできます。
このシナリオエディターは強力で、顧客の多様なユースケースに対応可能でした。しかし、急速に拡大する多様な顧客基盤に対応するため、より直感的でコード不要のワークフローが不可欠であることが明らかになりました。課題は、元のコードベースツールの精度と機能の豊富さを維持しつつ、動的なデータモデルに適応可能なグラフィカルユーザーインターフェース (GUI) を簡単に作成することでした。
本記事では、開発者向けのシナリオエディターを、動的でヒューリスティックベースの自動生成 GUI へと変革するプロセスを解説します。スケーラブルで維持可能なノーコードインターフェースを構築する際に下したアーキテクチャ上の決定、技術的課題、および重要な教訓を詳細に説明します。この経験は、複雑なソフトウェアシステムにおいて機能性とアクセシビリティのバランスを追求するプロダクトマネージャー、エンジニア、デザイナーにとって有益な洞察を提供します。

エージェントを含むシナリオ例
当初、私たちはテキストエディターから始まり、パワーユーザー向けにカスタマイズ性と柔軟性を提供していました。しかし、より広範で技術的な知識が不足するユーザー層にもツールをアクセスしやすくする必要性に気づきました。初期のGUIワークフローは、コードベースのワークフローのような精度や機能の豊富さに欠けていました。さらに、ユーザー体験の悪さに加え、レガシー GUI は維持が困難で、一貫した体験に統合されていませんでした。

この問題を解決するため、私たちはコードベースのワークフローのすべての機能を提供しつつ、使いやすさやパフォーマンスを犠牲にしない GUI ワークフローを作成しました。

主要な要件を超えて、以下の追加の考慮事項も考慮する必要があります:
この実現のため、当社は Google Protocol Buffer(protobuf)メッセージから自動的に GUI を生成する強力なライブラリを構築しました。このシステムは protobuf descriptor 内の各フィールドタイプに最適化された UI コンポーネントを自動的に生成し、ユーザーが GUI を通じてデータとシームレスにインタラクションし編集できるようにします。基盤となるアーキテクチャは、明確な役割分担を基に複数層で構成されており、各層が特定の責任を担っています。

protobuf descriptor の例
この protobuf から GUI への生成ライブラリを構築するには、フロントエンドで protobuf descriptor を直接アクセスする必要がありましたが、これはデフォルトでは不可能でした。フロントエンドに protobuf descriptor をロードするため、ビルド時にプロトコルバッファの JSONSchema 表現を生成する Go ライブラリ(protoc-gen-jsonchema)を使用しました。JSONSchema は JSONSchema 仕様に準拠した JSON ファイルであるため、フロントエンドに直接インポート可能です。
ここでの巧妙な点は、エンジニアが protobuf メッセージ定義(例:フィールドの追加)に変更を加えると、ビルドシステムが自動的にこの変更を検出し、フロントエンドが消費する JSONSchema を更新する点です。これにより、 protobuf 記述子という単一の真実のソースを維持できます。

結果の JSON スキーマ
JSONSchema が存在する場合は、それをフロントエンドに読み込み Protobuf descriptor のグラフ表現である「Protobuf descriptor グラフ」を構築します。
最下位層では、すべての Protobuf メッセージをインデックス化し、フィールド名や型、oneofフィールドの選択オプション、追加メタデータなどの Protobuf メッセージ定義に関する情報を提供する Protobuf 記述子グラフを開発しました。このレイヤーは基盤層として機能し protobuf スキーマを信頼性が高く一貫した方法で解釈する手段を提供します。このレイヤーをスキーマ解釈に専念させることで、上位のアプリケーションロジックやUI要件の変更に影響を受けず、安定性を維持できます。

Protobuf メッセージとフィールド記述子ノード(メタデータと接続付き)
Descriptor グラフのモジュール性により、シナリオエディター以外のユースケースにも適用可能です。例えば、 protobuf メッセージのフィールド名と、enumおよびoneofフィールドのオプションを検査することで、コードエディターの自動補完機能を強化することができました。また、プロトブフのフィールドオプションに基づいて、特定のフィールドが非推奨かどうかを検査し、これらの非推奨なシミュレーション機能の使用を防止するために、オートコンプリートから非表示にすることができました。さらに protobuf のコメントで生成された説明を検査することで、各フィールドごとにホバードキュメントを提供することもできました。
この基盤の上に、Protobuf メッセージツリー層は各フィールドまたはメッセージノードの現在の値を格納します。これはコアデータモデルとして機能し、ユーザーの操作を反映し、UI と基盤データ間の同期を維持します。状態管理をこの層に分離することで、データの格納方法や処理方法の変更がアーキテクチャの他の部分に影響を与えないため、システムの保守性が向上しました。
Protobuf descriptor グラフと同様に、このレイヤーのモジュール構造により、この自動生成ライブラリに依存せずに、同じ基盤データモデルを参照する多様なUIコンポーネントを作成できます。つまり、コンポーネントに値を埋めて生成するには、意図した状態を Protobuf メッセージツリー(データモデル)に更新するだけです。

各ノードには、そのノードにのみ関連するデータが状態として格納されています。
最上位のレイヤーは Proto GUI ツリーで、データとスキーマ情報をユーザーインターフェースのレンダリング用に設計された形式に変換します。このレイヤーでは、フィールドとメッセージのグループ化、再構成、整理のための抽象化を導入し、ユーザーフレンドリーで柔軟な UI を作成します。関心事の分離により、製品と UI の決定(例: フィールドのグループ化方法や表示するコンポーネントの選択)は、このレイヤーに隔離されます。この設計により UI の変更時に下位層の修正を最小限に抑え、予期しない副作用のリスクを低減し、開発サイクルを加速します。
最後に、Proto GUI Editor React コンポーネントは Proto GUI Tree を消費し、実際の UI を動的に生成します。このモジュール構造により、基礎的なデータ処理ロジックを変更せずに UI の改善を迅速に反復し、ユーザー体験を最適化できます。

GUI ノードとその対応する React コンポーネントが組み合わさって、組織構造とユーザーインターフェースを決定します。
このフレームワークの構築に投資する前に、自社で構築するか、既存のライブラリを再利用するかが適切かどうかを慎重に検討しました。検討した主要なライブラリは react-json-schema-form でした。当初は当社のユースケースの大部分に適合するように見えたものの、要件に応じたスケーラビリティの面で最終的に不十分でした。主な制限事項は、当社の複雑なシナリオ言語の核心である再帰的なスキーマ定義に対応できない点でした。さらに、このライブラリは JSON スキーマ全体を事前に読み込むため、特定のサブセクションのみをレンダリングする必要がある当社のユースケースにおいて、パフォーマンス上の課題を引き起こしました。サブセクションをレンダリングしつつ他の部分を折りたたんだままにできない点は、当社の要件に合致しませんでした。
また、react-json-schema-form は設定の柔軟性や拡張性に制限がありました。シナリオエディターでは、フィールドとメッセージのレンダリングと表示方法に対して高い制御が必要でした。ライブラリの API は、カスタムバリデーション、動的再配置、ユーザー体験の最適化などの機能実装を制限する制約を課していました。最終的に、これらの制限が、スケーラビリティ、柔軟性、およびシナリオエディターの独自の要件に特化したソリューションを自社で開発する要因となりました。
この新しい GUI エディターは、シナリオエディターだけでなく、チャート設定用の GUI エディターや一般ユーザー設定用のエディターなど、多くの他のエディターにも基盤として機能しています。現在も、エンジニアの生産性を維持しつつ、すべての製品の使いやすさとアクセシビリティをさらに向上させるため、このフレームワークの改善を継続しています。
複雑な技術分野向けに革新的でユーザーフレンドリーなインターフェースの構築に情熱をお持ちの方を Applied Intuition では積極的に採用しています!当社のキャリアページ(careers page)でフロントエンドエンジニアリングのポジションを閲覧し、自動運転開発の未来を共に作っていきませんか。
Software Engineer
Peter Cardenas is a Software Engineer at Applied Intuition focused on frontend platform and dev tooling. He previously served as a Founding Engineer at Ladder, where he led and mentored a team of engineers building web and mobile applications. He holds a BS in Computer Science from the University of Texas at Austin.
Engineering Manager
Anthony Liu is an Engineering Manager at Applied Intuition focused on building platforms that accelerate the development of intelligent vehicles. He previously served as an Engineering Manager at Meta, where he led teams working on AI infra and consumer-facing products across Meta's family of apps. He holds a BS in Management Science & Engineering from Stanford University.
Engineering Manager
Rami Manna is an Engineering Manager at Applied Intuition with a background spanning software engineering, natural language processing, and AI research. He holds a BS and MEng in Computer Science from MIT, where he also conducted research in speech and natural language processing at MIT CSAIL. He previously served as CTO of Lean On Me, a confidential peer support platform operating at universities across the United States.