螢幕錄製可以呈現整個工作,但無法說明其背後邏輯。有人開啟收件匣、檢查寄件者、將某個值複製到客戶記錄、與試算表比對、傳送摘要,然後繼續下一步。
這些工作清晰可見,但自動化仍須通過更嚴苛的測試:系統能否在不遺漏步驟、不接錯動作、不匯入看似正確卻在後續失效的內容下,還原該工作?
我在螢幕分析專案的 n8n 部分,就是為了因應這個問題而建置。產生器不將最終檔案視為一袋文字,而是將發現的自動化轉換為 N8NWorkflow、N8NNode 以及連線物件,再輸出 n8n 相容的 JavaScript Object Notation (JSON)。這增加了程式碼的規範,但能捕捉字串組裝容易引入的一類錯誤。
1. 維持平台詞彙範圍狹小
每個輸出的節點類型都來自 n8n_workflow_generator.py 中的 NodeType。此列舉涵蓋產生器知道如何建立的觸發器、語言模型節點,以及應用程式整合。當專案需要另一個 n8n 節點時,我會先在此處新增,再讓產生器使用。
這會犧牲編輯速度。無法透過提示中拼寫新識別字,快速插入一次性節點。換來的優點是更明確的失敗:不支援的平台名稱會在 Python 中失敗,而非隱藏在可匯入的檔案中。
相同的概念也適用於 n8n_agent_templates.py 中的代理設定。AgentTemplate 命名可用的模式;AgentConfig 則承載提示、工具、整合、觸發偏好、模型選擇、temperature 與迭代限制。提示只是一個欄位,而非其他一切的容器。
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 圖形本身:節點加上具名連線。它不會維護第二種私有圖形格式。N8NWorkflow、N8NNode 與連線記錄,就是分析結果到儲存 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 時發生了什麼? |
這比字串插值成本更高:額外的列舉、資料類別、物件建構、儲存步驟,以及匯入報告。它也讓結構變更更明確。我願意支付這個成本,因為從螢幕錄製推斷出的自動化本就帶有不確定性;匯出路徑應該降低這種不確定性。
當 Workflow JSON 能夠移動資料、呼叫模型並路由工作時,它就是程式碼。將它視為產生的程式碼,是我讓發現的流程不變成匯入意外的方法。
🎧 收聽有聲書 — Spotify · Google Play · 所有平台
🎬 在 YouTube 觀看視覺總覽
📖 閱讀完整的 13 部分系列
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.