Tracecat 自動化最佳實踐
若為 Slack 導向的自動化,請使用 /skill:tracecat-slackbot-best-practices。在 Tracecat 工作區聊天中,請先載入 /skill:tracecat-workspace-chat;其主機專用的工具對應會覆蓋下列外部 MCP 步驟。隨需參考文件:圖形結構、表達式、run-python、資料表、觸發器輸入、案例觸發器、秘密、代理輸出、代理預設、工作流程編輯。
工作流程
針對外部 Tracecat MCP 連線,應基於即時上下文開始,而非憑空猜測:
- 使用
list_workspaces探索工作區。 - 需要 DSL 語法或範例時,閱讀
tracecat://platform/dsl-reference。 - 使用
get_workflow_authoring_context取得動作結構、變數及秘密。 - 對於現有工作流程,使用
get_workflow,然後進行針對性的edit_workflow修補——詳見 工作流程編輯。在新增或編輯任何run_if、depends_on或join_strategy之前,請先呼叫get_workflow_graph(若主機有提供),並讀取所有上游動作及其gated_by列表。 - 使用
validate_workflow進行驗證,必要時執行草稿或已發布版本,然後透過list_workflow_executions與get_workflow_execution檢查失敗情況。
其他主機可能提供不同的工具介面。請遵循其適配器,而不是機械性地為這些裸 MCP 名稱加上前綴。
請釐清會改變工作流程合約的生產選擇:工作區、整合/供應商、秘密來源、發布/執行行為、破壞性副作用、核准或驗收標準。若需求已足夠明確,則可直接進行。
圖形結構
在撰寫前先勾勒出圖形結構,並盡可能保持接近一條線。偏好線性而非平行,並以可讀性為優先,而非完全連通:邊數越少是關鍵指標。
depends_on是執行順序,而非資料線路。 一個動作可以從任何祖先(不限於直接父節點)讀取ACTIONS.<ref>.result——驗證會檢查該 ref 是否存在於工作流程中,但不要求其為父節點。僅在動作必須等待時才加入邊,絕不為了讓值可及而加入。- 只做一次閘控。 某個動作上的
run_if也會跳過其下游鏈上的所有動作,因此絕不在下游重複它。一條鏈上每個動作都帶有相同的TRIGGER.enabled && ...防護是錯誤的;只有第一個動作需要它。下游動作只有在其引入新條件時才擁有自己的run_if,且應獨立撰寫。例外情況是合併,而這是個陷阱:一個有多個父節點的任務不會因為其中一個父節點存活而被強制跳過,但預設的join_strategy: all要求每個父節點都必須被造訪過,因此一個被跳過的分支會使合併無法到達,並導致工作流程失敗。請改用join_strategy: any,或在合併處重複該分支的條件,使其先自我跳過。 - 預設為單一鏈。僅在確實需要獨立工作且值得並行執行時才分支,並僅在後續動作需要多個分支結果時才重新合併。
- 單一父節點是常態。超過一個則表示有意的合併——請有目的地選擇
join_strategy。 - 保持每個
run_if簡短:一個可讀的比較式,用於一個新條件。過長的&&/||鏈通常只是在重述上游閘控,或應屬於較早的轉換步驟。 - 一般工作流程保持在約 20 個節點以下,代理工作流程保持在約 6 個節點以下。偏好可讀的由上而下流程,依流程閱讀順序排列,並使用人類可讀的 ref。Tracecat MCP 會在動作或邊變更時自動格式化畫布,因此請省略
layout而非手動放置節點。
請參閱 圖形結構,了解已修改的過度連線重寫、合併策略、錯誤邊,以及為什麼 scatter 不是分支。
動作優先順序
選擇最能勝任工作的特定動作:
- 整合動作 (
tools.<integration_slug>.*):用於所呼叫的產品。在撰寫 API 呼叫前,先使用簡短的產品或動作名稱子字串搜尋list_actions(例如query="okta"),或瀏覽已知的tools.<integration_slug>命名空間。搜尋會比對字面子字串,而非獨立的關鍵字。當第一頁缺少合適的動作時,請在has_more為 true 時跟隨next_cursor。使用get_action_context檢查候選動作,並比較其所需的憑證與參數。 - 核心動作:對於沒有整合動作的產品或端點,使用
core.http_request/core.http_paginate;core.transform.*用於資料塑形;core.table.*/core.cases.*用於平台資料。 core.script.run_python:僅用於沒有任何動作能涵蓋的獨立步驟。當整合或 HTTP 動作可以進行 API 呼叫時,絕不要從 Python 中呼叫 API。
絕不要憑空發明 tools.* 名稱。若一個通用請求適用於多個整合功能,請先列出候選項目。
在代理與 Python 之間選擇
根據工作的類型來決定,並將整個工作流程的最佳化目標設為可維護性與可讀性——用最少的動作和最少的程式碼完成工作。
- 代理工作 → 使用代理 (
ai.agent/ai.preset_agent)。任何需要判斷、調查、路由、增強選擇、摘要、撰寫訊息或發佈到 Slack 的工作。將工具授予預設的actions許可清單或技能的metadata.tools,然後信任代理使用它們。偏好代理、提示和技能——它們以遠少於確定性節點圖形的移動部件來承載創造性思考。 - 確定性資料處理 → 使用 Python (
core.script.run_python)。轉換、標準化、編輯、合併及將資料列批次寫入表格。這正是 Python 的用途——它不是壞味道。一個清晰的run_python動作勝過將相同工作分散到許多節點。API 呼叫不屬於資料處理:它們應放在整合或core.http_*動作中(請參閱動作優先順序)。
壞味道在於將 Python 用於代理的部分——例如從腳本中撰寫或發送代理的 Slack 訊息,而不是給代理 Slack 工具。
提示大小防護: 將行為推向提示,直到合理的大小。當單一提示變得過大而難以閱讀時,應分解為子代理或技能,而不是擴張成單一巨型提示。
代理優先自動化
當使用者要求代理工作流程、代理預設,或說要使用代理時,讓代理成為工作的主要擁有者。給它所需的工具,並信任它進行調查、決定、路由、撰寫訊息和採取行動。預設採用精簡形狀:觸發器 -> 重塑/編輯 -> 更新事件記錄 -> ai.agent(或 ai.preset_agent)。
在代理執行前先持久化標準化的事件。當事件來自 SIEM、日誌平台、SaaS webhook 串流、稽核軌跡或雲端服務時,先將標準化的負載與審查狀態儲存在 Tracecat 資料表中,並使用確定性的更新操作。這為重試、重複 webhook 和重播提供了持久的真相來源。將代理指向已儲存的資料列,讓工作流程(而非代理)擁有事件的第一個持久記錄。
確定性節點的存在價值在於其精簡、直接且易於稽核,以及執行代理不應擁有的工作:在代理看到資料前編輯秘密、標準化結構、更新事件資料列、使用重複檢查保護昂貴的代理執行、準備有界限的批次,或檢查點持久狀態。將判斷、路由、增強、訊息撰寫、軟性核准決定及最終通知行為保留在代理中。當核准問題本身需要判斷時,讓代理決定或草擬請求。
兩種不同的機制涵蓋風險,且它們不與預設擁有的工具衝突。對於工作流程本身執行的不可逆外部影響,使用確定性閘控——圖形決定該節點是否執行。對於代理持有的風險工具,在預設上使用每工具 tool_approvals:代理保留該工具,但在該特定呼叫通過之前,執行會暫停等待人工核准。
偏好一個指示良好的代理或可重複使用的預設,而非許多小型確定性節點。代理的工具通常位於預設的 actions 許可清單上,或當多個代理共享該群組時,位於附加技能的 metadata.tools 上。這樣一來,代理在工作區聊天和每個呼叫它的工作流程中都擁有相同的工具。指示承載行為而非權限:輸出合約、Slack 風格、重複規則、租戶邊界及允許的副作用應放在預設指示中,代理會讀取這些指示而非儲存庫檔案。當代理需要某個工具時,在那裡授予狹義的工具通常勝過將相同的呼叫包裝在工作流程動作中。
ai.preset_agent 節點通常只攜帶 preset 和 user_prompt,加上可選的 instructions 附加內容以提供執行特定上下文。它的 actions 參數會取代該次執行的預設及其技能的註冊工具,而不是新增——MCP 工具仍保持附加,空列表則被忽略——因此它適用於在測試或評估中嘗試使用不同工具集的預設。留在發佈工作流程中的列表也會丟棄預設技能貢獻的註冊工具,這很少是作者想要的。
編寫代理指示時,使用目標、上下文和原因,而非禁止。一條籠統的規則可能會取消代理已被授予的工具:某個呼叫者附加了「僅使用提供的證據」,結果代理跳過了它已被授予工具的唯一政策查詢。將硬性規則保留給不可逆或對外的動作,並將 tool_approvals 或確定性閘控放在這些動作之後,而不是依賴提示的措辭。
預設的執行時期比 list_actions 顯示的擁有更多能力:真實的 shell 和檔案工具、Python、curl、jq 和 DuckDB。在添加工作流程輔助程式來補償假定的限制之前,請檢查預設/執行時期上下文——請參閱代理預設。
撰寫預設
- 對於代理工作流程,將大部分行為推到代理提示/預設中。對於事件驅動的工作流程,在代理之前進行單一的重塑/編輯/更新操作通常是正確的確定性邊界。
- 使用
ai.agent/ai.preset_agent進行代理工作;使用產品的tools.*動作(或沒有對應動作時的core.http_request)進行確定性 API 呼叫;使用core.script.run_python進行確定性資料工作,且僅在已排除內聯表達式、run_if或core.transform.*動作之後——請參閱表達式和 run-python。 - 對於大量資料表寫入,當資料列已塑形完成時(每批次最多 1000 列),偏好一個原生的
core.table.insert_rows動作。若需要塑形、分塊或混合資料表/案例寫入,則使用帶有匯入輔助工具和有限批次的core.script.run_python,而非分散許多資料庫支援的動作。 - 除非使用者明確接受廣泛的網路能力,否則不要將
core.http_request交給代理。將確定性 HTTP 放在工作流程圖形或嚴格限定範圍的子流程中。 - 僅在存在真正的編排邊界、可重複使用的子工作流程、獨立的執行歷史、核准、長時間運行的動作或獨立的檢查點時,才分割為子流程。使用
core.workflow.execute並偏好workflow_alias而非硬編碼的 ID。子流程批量預設:loop_strategy: batch、batch_size: 32、fail_strategy: isolated、wait_strategy: wait(僅在父節點不需要子節點結果時使用detach)。 - 保持 run-python 和代理輸出精簡:下游資料列、摘要計數、有界限的錯誤樣本。
- 偏好可重複使用的代理預設而非內聯
ai.agent,並使用model物件而非已棄用的頂層model_name/model_provider——請參閱代理預設。
常見錯誤
- 將 Python 用於代理的部分——撰寫或發佈代理的 Slack 訊息,或在腳本中進行路由/判斷呼叫。代理擁有訊息撰寫、發佈(透過 Slack 工具)和判斷;Python 擁有確定性資料處理。
- 過度連接圖形:從每個產生者到每個消費者都建立邊。從祖先讀取並保持一條鏈(請參閱圖形結構)。
- 在鏈中重複
run_if,重述祖先已強制的條件。跳過會自行傳播——只在頂端進行一次閘控,並僅在下游動作引入自身的新條件時才給予run_if(請參閱圖形結構)。 - 工作流程動作名稱並非 MCP 工具名稱。使用 MCP 工具(如
create_workflow)來管理工作流程,而動作名稱(如core.http_request)僅在工作流程 YAML 內部使用。 - 憑空發明
tools.*動作名稱。使用list_actions發現動作,然後使用get_action_context檢查精確的結構。 - 當存在合適的
tools.*動作時,從core.script.run_python(requests、httpx)或裸core.http_request呼叫產品的 API。先搜尋並翻閱list_actions以尋找該產品。 - 使用
for_each進行一般迴圈管理,或使用 scatter/gather 進行資料密集的批次處理、過濾、合併或資料表寫入。預設使用 scatter 進行工作流程層級的迴圈;僅在下游步驟需要合併結果時才加入 gather,否則省略。對於超過 10 個分散的資料庫支援資料表/案例動作要特別小心,這可能會耗盡 Postgres 連線槽。Scatter 的可選間隔可以錯開工作,但它不會批次處理資料庫寫入;使用一個core.table.insert_
…
[已截斷以利翻譯]