Od jakiegoś czasu testuję nową funkcję Guardrails w n8n.
Podczas testów natrafiłem na problem, którym warto się podzielić.
Problem - przekazywanie obiektu do Guardrails
Kiedy przekazujesz obiekt do noda Guardrails, nie działa to zgodnie z oczekiwaniami. Przede wszystkim Guardrails nie obsługuje obiektów. Obsługuje tylko ciągi znaków (stringi). Możesz jednak przekazać cały obiekt do Guardrails, przekształcając go w string za pomocą JSON.stringify() i zostanie przetworzony jako ciąg znaków.
Przygotujmy początkowy workflow
Zacznijmy od początkowego workflow:

Jak widać, mamy prosty workflow z Manual Trigger, Set fields i nodem Guardrails. Node Guardrails jest skonfigurowany do sanityzacji tekstu wejściowego.
Node Set fields jest skonfigurowany do ustawienia obiektu wejściowego.
Node Set fields zwraca JSON jak poniżej:
[
{
"content": "Content with emails adam@adam.com and my friends email kate@kate.com ",
"receiverEmail": "agnes@agnes.com ",
"senderEmail": "pete@pete.com"
}
]
Chcemy mieć pewność, że każdy email z listy jest zanonimizowany. Więc adam@adam.com, kate@kate.com, agnes@agnes.com, pete@pete.com powinny zostać zanonimizowane i zmienione na <EMAIL_ADDRESS>.
Rozwiązanie
Aby to zrobić, musisz skonfigurować node Guardrails do sanityzacji przekształconego w string obiektu. Konfiguracja jest pokazana poniżej:

Przekształcenie obiektu w string w N8N przy użyciu JavaScript
Musimy przekazać obiekt przekształcony w string do noda Guardrails. Możemy to zrobić używając noda Set fields i funkcji JSON.stringify().
{{ JSON.stringify($('Set Fields').all()) }}
Powyższe wyrażenie zwróci obiekt przekształcony w string z noda Set fields.
Teraz skupmy się na nodzie Guardrails. Po przekazaniu obiektu przekształconego w string do noda Guardrails, zostanie on przetworzony jako ciąg znaków i zwróci zasanityzowany string jak poniżej:
[
{
"guardrailsInput": "[{\"json\":{\"content\":\"Content with emails <EMAIL_ADDRESS> and my friends email <EMAIL_ADDRESS> \",\"receiverEmail\":\"<EMAIL_ADDRESS> \",\"senderEmail\":\"<EMAIL_ADDRESS>\"},\"pairedItem\":{\"item\":0}}]",
"checks": [
{
"name": "personalData",
"triggered": true,
"info": {
"analyzerResults": [
{
"entityType": "EMAIL_ADDRESS",
"text": "adam@adam.com"
},
{
"entityType": "EMAIL_ADDRESS",
"text": "kate@kate.com"
},
{
"entityType": "EMAIL_ADDRESS",
"text": "agnes@agnes.com"
},
{
"entityType": "EMAIL_ADDRESS",
"text": "pete@pete.com"
}
]
}
}
]
}
]
To, na czym musimy się skupić, to pole guardrailsInput. Zawiera ono zasanityzowany string. Możemy go użyć do przywrócenia oryginalnego obiektu. Dlatego musimy go sparsować używając funkcji JSON.parse() w nodzie Code.
Parsowanie obiektu przekształconego w string w N8N
Node Code jest skonfigurowany do parsowania obiektu przekształconego w string za pomocą funkcji JSON.parse(), jak widać na poniższym obrazku:

Wyrażenie node Code:
const parsedObject = JSON.parse($input.first().json.guardrailsInput)
return parsedObject
Po sparsowaniu obiektu możemy go użyć do przywrócenia oryginalnego obiektu jak poniżej:
[
{
"content": "Content with emails <EMAIL_ADDRESS> and my friends email <EMAIL_ADDRESS> ",
"receiverEmail": "<EMAIL_ADDRESS> ",
"senderEmail": "<EMAIL_ADDRESS>"
}
]
Finalny workflow N8N
Aby sprawdzić finalny workflow, możesz skopiować poniższy JSON (lub skopiować go z pliku w repozytorium: https://github.com/pjsikora/n8n-workflows/blob/main/guardrails-pass-an-object) i zaimportować go do swojej instancji n8n (nie musisz zapisywać go do pliku i importować - po prostu skopiuj i wklej do edytora n8n).
{
"nodes": [
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "0b205824-ec65-4728-a035-ad465f5d7821",
"name": "content",
"value": "=Content with emails adam@adam.com and my friends email kate@kate.com ",
"type": "string"
},
{
"id": "692047aa-abed-454b-95d0-d11ef4bfdeae",
"name": "receiverEmail",
"value": "=agnes@agnes.com ",
"type": "string"
},
{
"id": "d89760e3-9326-4714-a05a-8e97677aac2e",
"name": "senderEmail",
"value": "pete@pete.com",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
-32,
48
],
"id": "64c28287-4ba4-4e57-90d0-62d180bd91a1",
"name": "Set Fields",
"executeOnce": true
},
{
"parameters": {
"operation": "sanitize",
"text": "={{ JSON.stringify($('Set Fields').all()) }}",
"guardrails": {
"pii": {
"value": {
"type": "all"
}
}
}
},
"type": "@n8n/n8n-nodes-langchain.guardrails",
"typeVersion": 1,
"position": [
192,
48
],
"id": "619d36b1-3b34-4760-831b-d6b4bb06bc18",
"name": "Check for PII"
},
{
"parameters": {
"jsCode": "const parsedObject = JSON.parse($input.first().json.guardrailsInput)\n\nreturn parsedObject"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
400,
48
],
"id": "23ec4b56-7b77-426e-b77a-b1206d0fb5fb",
"name": "Parse"
},
{
"parameters": {},
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
-256,
48
],
"id": "d04278fc-cb75-4c26-a3bf-5aba3bc16828",
"name": "When clicking 'Execute workflow'"
}
],
"connections": {
"Set Fields": {
"main": [
[
{
"node": "Check for PII",
"type": "main",
"index": 0
}
]
]
},
"Check for PII": {
"main": [
[
{
"node": "Parse",
"type": "main",
"index": 0
}
]
]
},
"Parse": {
"main": [
[]
]
},
"When clicking 'Execute workflow'": {
"main": [
[
{
"node": "Set Fields",
"type": "main",
"index": 0
}
]
]
}
},
"pinData": {},
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "2295c029f4cb86c8f849f9c87dade323734dc279619eb9e2704f8473c381e4d1"
}
}







