{
  "id": "xVqClqbjOwmWYSfQ",
  "name": "Template 2: Content Pipeline - Reviewer Agent (LLM-as-a-Judge)",
  "tags": [],
  "nodes": [
    {
      "id": "530b0bc5-7e22-4c3c-bc84-40ae2702479d",
      "name": "When Executed by Parent",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        208,
        304
      ],
      "parameters": {
        "inputSource": "passthrough"
      },
      "typeVersion": 1.1
    },
    {
      "id": "c24e4222-13b7-4d38-b30b-68d7faf4fe30",
      "name": "Reviewer Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        448,
        304
      ],
      "parameters": {
        "text": "=Brief:\n{{ $json.brief }}\n\nDraft to review:\n{{ $json.currentDraft }}",
        "options": {
          "systemMessage": "You are an editorial reviewer operating as an LLM-as-a-Judge. Score the draft against the brief on four criteria, each on a 1 to 10 scale:\n\n- accuracy: Does the draft reflect the brief and stay truthful? Are there contradictions or fabricated claims?\n- tone: Does the draft match the brief's intended tone and audience?\n- completeness: Does the draft cover what the brief asked for? Are important points missing?\n- clarity: Is the draft easy to read, well-structured, and free of filler?\n\nCompute overall = the simple average of the four scores, rounded to 2 decimal places.\n\nList specific issues you found and provide concrete revisionNotes the writer can act on. Be direct. If the draft is already strong, return an empty issues array and short revisionNotes.\n\nDo NOT decide pass or fail. That decision is handled by the parent pipeline based on a configurable threshold. Your job is to score and critique honestly.\n\nReturn ONLY valid JSON in this exact shape:\n{\n  \"scores\": {\n    \"accuracy\": 0,\n    \"tone\": 0,\n    \"completeness\": 0,\n    \"clarity\": 0\n  },\n  \"overall\": 0.0,\n  \"issues\": [\"specific issues found\"],\n  \"revisionNotes\": \"concrete guidance for the writer to improve the draft\"\n}"
        },
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "95423975-6666-4b07-913a-64157101df00",
      "name": "OpenRouter - Reviewer",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        352,
        528
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e88b35ff-602a-4d28-b562-1723aa7795ee",
      "name": "Parse Review Output",
      "type": "n8n-nodes-base.code",
      "position": [
        720,
        304
      ],
      "parameters": {
        "jsCode": "// Parse review output, merge with trigger input so state flows through\nconst raw = $input.first().json;\nconst triggerIn = $('When Executed by Parent').first().json;\nlet review;\ntry {\n  const text = typeof raw.output === 'string' ? raw.output : JSON.stringify(raw.output);\n  const m = text.match(/\\{[\\s\\S]*\\}/);\n  review = JSON.parse(m ? m[0] : text);\n  if (!review.scores || typeof review.overall !== 'number') throw new Error('Invalid scoring shape');\n} catch(e) {\n  review = {\n    scores: { accuracy: 0, tone: 0, completeness: 0, clarity: 0 },\n    overall: 0,\n    issues: ['Reviewer output could not be parsed'],\n    revisionNotes: 'The reviewer response was malformed. Treat this as a failed review and escalate or accept the draft as-is.',\n    reviewParseError: e.message\n  };\n}\n\nreturn {\n  json: {\n    ...triggerIn,\n    review: review\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "c8c58c24-1d4b-4119-9459-530d677ed1df",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -448,
        0
      ],
      "parameters": {
        "width": 620,
        "height": 820,
        "content": "## Reviewer Subworkflow (for Content Pipeline)\n\n### How it works\nStandalone subworkflow called by the Content Pipeline parent. Scores the draft and returns revision notes:\n1. **Execute Workflow Trigger** (Passthrough): Receives the full pipeline state (brief, current draft, revisionCount).\n2. **Reviewer Agent** (AI, LLM-as-a-Judge): Scores the draft on accuracy, tone, completeness, and clarity. Computes a weighted overall score and returns specific revision notes.\n3. **Parse + Merge**: Extracts scores, overall score, and revision notes, then returns `{...triggerInput, review: {...}}` so the parent can evaluate.\n\n### Setup\n- Must be saved before the parent can reference it\n- Attach your **LLM credentials** to the Chat Model sub-node\n- Called by the parent after every Writer iteration\n\n### Customization\n- Add or remove scoring dimensions to match your editorial standards\n- Reweight the overall score formula\n- Tighten the rubric for stricter evaluation and more frequent revision loops\n\nThis template is a learning companion to the Production AI Playbook, a series that explores strategies, shares best practices, and provides practical examples for building reliable AI systems in n8n."
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "fb399593-4ebe-4a31-b612-12414fdb0776",
  "connections": {
    "Reviewer Agent": {
      "main": [
        [
          {
            "node": "Parse Review Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter - Reviewer": {
      "ai_languageModel": [
        [
          {
            "node": "Reviewer Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "When Executed by Parent": {
      "main": [
        [
          {
            "node": "Reviewer Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}