画面録画は、作業全体を説明なしで見せることができます。誰かが受信トレイを開き、送信者を確認し、値を顧客レコードにコピーし、スプレッドシートと比較し、サマリーを送信して次の作業に移る。

その作業は目に見えますが、オートメーションはより厳しいテストに耐えなければなりません。システムが作業を再構築できるか、ステップを落とさず、誤ったアクションを配線せず、後で失敗するような見た目だけのものをインポートしないか。

私は画面分析プロジェクトの n8n 側をその問題を中心に構築しました。ジェネレーターは最終ファイルをテキストの袋として扱いません。検出されたオートメーションを N8NWorkflowN8NNode、および接続オブジェクトに変換し、n8n 互換の JavaScript Object Notation (JSON) を出力します。これによりコードの儀式が増えますが、文字列連結が招きやすいクラスのミスを防ぎます。

1. プラットフォーム語彙を狭く保つ

出力されるすべてのノードタイプは n8n_workflow_generator.pyNodeType から来ます。列挙型は、トリガー、言語モデルノード、ジェネレーターが作成方法を知っているアプリケーション統合をカバーします。プロジェクトが別の n8n ノードを必要とする場合、生成で使用可能になる前にそこに追加します。

これにより編集速度が犠牲になります。迅速なワンオフノードは、プロンプト内で新しい識別子を綴ることで通り抜けることができません。利点は、より明確な失敗です。サポートされていないプラットフォーム名は、インポート可能なファイル内に隠れるのではなく、Python で失敗します。

同じ考え方は n8n_agent_templates.py のエージェント設定にも適用されます。AgentTemplate は利用可能なパターンを命名し、AgentConfig はプロンプト、ツール、統合、トリガー設定、モデル選択、温度、および反復制限を保持します。プロンプトは 1 つのフィールドであり、他のすべてを格納するコンテナではありません。

from __future__ import annotations

from dataclasses import dataclass, field
from enum import Enum
from typing import List


class AgentTemplate(Enum):
    EMAIL_TRIAGE = "email_triage"
    CRM_DATA_SYNC = "crm_data_sync"
    CALENDAR_ASSISTANT = "calendar_assistant"
    DOCUMENT_PROCESSOR = "document_processor"
    COMMUNICATION_ROUTER = "communication_router"
    REPORT_GENERATOR = "report_generator"
    LEAD_QUALIFIER = "lead_qualifier"
    TASK_MANAGER = "task_manager"
    VOICE_ASSISTANT = "voice_assistant"
    MULTI_AGENT_ORCHESTRATOR = "multi_agent_orchestrator"


@dataclass
class AgentConfig:
    name: str
    description: str
    template: AgentTemplate
    system_prompt: str
    tools: List[str] = field(default_factory=list)
    integrations: List[str] = field(default_factory=list)
    triggers: List[str] = field(default_factory=list)
    llm_model: str = "gemini-2.5-flash"
    temperature: float = 0.7
    max_iterations: int = 10

Enter fullscreen mode Exit fullscreen mode

スキーマも制約です。新しいオートメーションが AgentConfig で表現できない概念を必要とする場合、まずモデルを拡張します。これにより実験は遅くなりますが、エクスポートパスを正直に保ちます。

2. JSON の前にオブジェクトを構築する

ジェネレーターの構造化形式は n8n グラフそのものです。ノードと名前付き接続です。2 つ目のプライベートグラフ形式を維持しません。N8NWorkflowN8NNode、および接続レコードは、分析結果と保存された JSON ファイルの間の表現です。

flowchart TD
  analysis[Discovered automation] --> workflow[N8NWorkflow]
  workflow --> nodes[N8NNode objects]
  workflow --> connections[Connection records]
  nodes --> json[n8n JSON export]
  connections --> json
  json --> importer[REST importer]
  importer --> status[Import status]```



その区別は重要です。「このメールを分類する」などの検出されたステップは、ジェネレーターがトリガー、モデル、統合、および接続順序を選択するのに十分なコンテキストを持つ場合にのみ、具体的な n8n ノードにマッピングされます。位置はアイデンティティとは別に計算されるため、キャンバスはノード ID にレイアウトを結びつけることなく読みやすく保たれます。

トレードオフは柔軟性です。決定論的な配置は手動で配置されたキャンバスに匹敵できず、型付き構築は JSON ファイルを直接編集するよりも重いです。生成されたオートメーションの場合、私は完璧な視覚的レイアウトよりも予測可能な検査を好みます。

コアオブジェクトの形状は単純です。



```python
from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Dict, List


@dataclass
class N8NNode:
    id: str
    name: str
    type: str
    position: List[int]
    parameters: Dict[str, Any] = field(default_factory=dict)
    credentials: Dict[str, Any] = field(default_factory=dict)
    type_version: float = 1.0

    def to_dict(self) -> Dict[str, Any]:
        node_dict = {
            "id": self.id,
            "name": self.name,
            "type": self.type,
            "position": self.position,
            "parameters": self.parameters,
            "typeVersion": self.type_version,
        }
        if self.credentials:
            node_dict["credentials"] = self.credentials
        return node_dict

Enter fullscreen mode Exit fullscreen mode

これが JSON を生成コードのように感じさせる部分です。オブジェクトは、シリアル化が行われる前に、アイデンティティ、タイプ、パラメーター、資格情報、バージョン、および位置を所有します。ファイルが存在する時点で、重要な決定はすでに検査可能な Python 構造を通過しています。

3. インポートをデプロイメント状態として扱う

生成はファイルで終了します。操作は、そのファイルが Representational State Transfer (REST) API を通じて n8n に到達したときに始まります。n8n_importer.py では、インポーターの失敗には名前付き例外があり、インポートの進行状況には明示的な状態があります。

from enum import Enum


class N8NError(Exception):
    """Custom exception for n8n API errors."""


class ImportStatus(Enum):
    PENDING = "pending"
    IMPORTING = "importing"
    SUCCESS = "success"
    FAILED = "failed"
    REQUIRES_CREDENTIALS = "requires_credentials"

Enter fullscreen mode Exit fullscreen mode

資格情報の問題と失敗したインポートは異なる回復パスを必要とするため、異なるラベルが付けられます。デプロイフローでは、オートメーションの生成、サポートするエージェントファイルの作成、それらのインポート、および資格情報が処理される間はアクティベーションをオフのままにすることができます。

その分離により利便性は失われます。生成、インポート、資格情報、およびアクティベーションを行う単一のボタンは、デモにはより高速でしょう。本番環境では、これらのアクションを分割することで、部分的な失敗を回復可能にします。

4. 私がテストするテーブル

レイヤー 回答する質問
AgentTemplate どのオートメーションパターンが構築されているか?
AgentConfig どのプロンプト、ツール、統合、トリガー、およびモデル設定がそれを記述するか?
NodeType どの n8n 識別子が出力可能か?
N8NWorkflow / N8NNode どのグラフが JSON になるか?
ImportStatus / N8NError 成果物が n8n に到達したときに何が起こったか?

これは文字列補間よりもコストがかかります。追加の列挙型、データクラス、オブジェクト構築、保存ステップ、およびインポーターレポートです。また、スキーマ変更を明示的にします。画面録画から推論されたオートメーションはすでに不確実性から始まっているため、エクスポートパスはその不確実性を減らすべきだと私は考え、そのコストを支払っています。

ワークフロー JSON は、データを移動し、モデルを呼び出し、作業をルーティングできる時点でコードです。それを生成コードとして扱うことが、検出されたプロセスがインポートされた事故にならないようにする方法です。


🎧 オーディオブックを聴くSpotify · Google Play · すべてのプラットフォーム
🎬 YouTube でビジュアル概要を見る
📖 13 部構成の全シリーズを読む