當我們要請 AI 分析 Windows 事件檢視器(Event Viewer)或大型專案 Log 時,原始日誌動輒幾千行 XML 或堆疊追蹤(Stack Trace)。
如果把這 3,000 字未經處理的原生資料直接整坨塞進 Prompt,不僅會大幅拉長 AI 推理時間(從 1.6 秒拉長到 8.4 秒),還可能因為雜訊太多導致 AI 產生幻覺或抓不到重點。
今天我們來學習如何用 Node-RED 的 JSONata 表達式 與純 JavaScript 進行前置資料壓縮,把 3,000 字長日誌瞬間瘦身成 100 字關鍵特徵!
本文同步發布於 GitHub: 2026-18th-it-ironman
| 比較項目 | ❌ 原始日誌直接塞入 Prompt | ✅ 前置 JSONata 結構化瘦身 |
|---|---|---|
| 資料長度 | 3,000 ~ 5,000 字元(包含大量 XML 宣告、GUID、用戶 SID) | 約 100 ~ 150 字元(僅保留核心特徵) |
| 推理速度 | 8.4 秒以上(大量無效 Token 處理) | 1.6 秒秒回(速度提升 5 倍!) |
| 診斷準確度 | 容易被冗餘標籤干擾,產生幻覺 | 核心錯誤指名道姓,定位極為精準 |
| 系統開銷 | 消耗大量本機記憶體與訊息傳輸開銷 | 輕量化傳遞,節省記憶體回收(GC)負荷 |

在 Windows 事件檢視器(Application Error / EventID 1000)中,抓出來的原始資料往往長這樣:
{
"EventID": 1000,
"Provider": { "Name": "Application Error" },
"TimeCreated": "2026-08-23T10:00:00Z",
"ProcessName": "Code.exe",
"ProcessId": 15416,
"Message": "Faulting application name: Code.exe, version: 1.85.1.0, time stamp: 0x6579f648\nFaulting module name: ntdll.dll, version: 10.0.22621.2506\nException code: 0xc0000005\nFault offset: 0x000000000001f370\nFaulting process id: 0x3d94\nRawStackData: A7F4B2...[以下省略 3000 字元堆疊資料]"
}
在 Node-RED 中處理資料時,對於資料清洗與結構瘦身,使用 Change 節點搭配 JSONata 具有三大優勢:
undefined,絕不會拋出讓整條 Flow 中斷的 TypeError: Cannot read properties of undefined。拉出一個 change 節點,將規則設定為:
msg.compact_event
{
"event_id": payload.EventID,
"app": payload.ProcessName,
"error_snippet": $substring(payload.Message, 0, 150)
}

$substring(str, start, length):截取文字前 N 個字元。例如 $substring(payload.Message, 0, 150) 保留關鍵異常標頭,過濾冗長 Stack Trace。payload.Message ? $substring(payload.Message, 0, 150) : "無詳細錯誤訊息":三元運算子避免訊息為空時回傳空值。payload.records.{ "time": TimeCreated, "app": ProcessName }:快速將深層陣列物件壓縮為精簡清單。payload.events[Level = "Error"]:一行排除所有無效的 Info / Verbose 等級日誌。在 Function 節點中,用精煉後的欄位建立結構化 Prompt,並設定嚴謹的 --json-schema:
// Function 節點:合成極簡 Prompt
const info = msg.compact_event || {};
const prompt = `Windows 應用崩潰: 程式=${info.app}, 事件ID=${info.event_id}, 描述: ${info.error_snippet}。請給出白話原因與建議修復指令。`;
const schema = {
type: 'object',
properties: {
plain_cause: { type: 'string', description: '白話崩潰原因' },
recommended_cmd: { type: 'string', description: '修復指令' }
},
required: ['plain_cause', 'recommended_cmd']
};
msg.compressedPrompt = prompt;
msg.payload = `agy -p ${JSON.stringify(prompt)} --dangerously-skip-permissions --json-schema ${JSON.stringify(JSON.stringify(schema))} --output-format json`;
return msg;
agy CLI(Exec 節點)拉出一個 exec 節點,執行合成好的 CLI 指令:
msg.payload 傳入完整命令行)。
在後方的 Function 節點加入工業級雙軌解包防線,確保模型輸出的結構化資料安全解析,無論是 structured_output 還是帶有 Markdown 包裹的字串都能完美解析:
// Function 節點:雙軌安全解包
let parsed;
try {
parsed = typeof msg.payload === 'string' ? JSON.parse(msg.payload) : msg.payload;
} catch (e) {
node.error("JSON 解析失敗: " + msg.payload);
return null;
}
// 🛡️ 雙軌解包:優先取出 structured_output,若無則從 response 解包
let result = parsed.structured_output;
if (!result && parsed.response) {
try {
result = typeof parsed.response === 'string' ? JSON.parse(parsed.response) : parsed.response;
} catch (e) {
const match = parsed.response.match(/\{[\s\S]*\}/);
if (match) result = JSON.parse(match[0]);
}
}
msg.payload = result || parsed;
return msg;
最後接上一個 debug 節點,即可在 Node-RED 側邊欄即時看到結構化的秒級診斷成果。
當我們將原本 3,420 字元的日誌壓縮為 142 字元送入後,本機 AI 輸出嚴格符合 Schema 的秒級診斷:
{
"plain_cause": "VS Code (Code.exe) 在呼叫 ntdll.dll 系統核心動態函式庫時發生 0xc0000005 記憶體存取違規 (Access Violation) 崩潰,通常與擴充套件衝突或記憶體指標異常有關。",
"recommended_cmd": "code --disable-extensions"
}
| 指標 | 原始未過濾日誌 | JSONata 瘦身後 | 效益 |
|---|---|---|---|
| 輸入字元數 | 3,420 字元 | 142 字元 | 減少 95.8% |
| 本機 AI 推理耗時 | 8.42 秒 | 1.58 秒 | 提速 5.3 倍 |
| 輸出 JSON 格式精確度 | 82%(偶有額外字串) | 100% 嚴格符合 Schema | 完美解析 |
本案例 flow

今天我們掌握了在資料送入大模型前的「前置瘦身術」,用極低代價換來了高達 5 倍的推理效能提升!