AI · 09 — Embeddings (meaning as numbers)

What an embedding IS: two sentences that mean the same thing and one that doesn't, turned into vectors by the ◈-wired Embeddings node, compared with cosine similarity in plain JavaScript. The related pair scores high; the stranger scores low.

What’s inside

8 nodes — every type links to its full reference page.

StepNodeType
Three sentences Inject input.inject
Embed A AI Embeddings ai.embeddings
Embed B AI Embeddings ai.embeddings
Embed C AI Embeddings ai.embeddings
Embeddings (local) AI Model ai.model
Join Merge logic.merge
Cosine similarity JavaScript utility.javascript
Scores Console utility.console

Import it

  1. Studio → Import — paste the JSON below (or the URL /docs/templates/ai-09-embeddings-meaning-as-numbers.json).
  2. Or ask the AI Copilot with the JSON pasted after the phrase:
    import this workflow json into a new workflow named "AI · 09 — Embeddings (meaning as numbers)"
  3. Any credentials the nodes need are ${credential.…} references — add them once in Admin → Credentials and the template picks them up. Nothing secret ships in a template.
The workflow document (flowdrome.workflow.v1, 6 node types)
{
  "schemaVersion": "flowdrome.workflow.v1",
  "id": "",
  "name": "AI · 09 — Embeddings (meaning as numbers)",
  "version": "0",
  "status": "draft",
  "nodes": [
    {
      "id": "seed",
      "type": "input.inject",
      "label": "Three sentences",
      "category": "trigger",
      "config": {
        "contentType": "application/json",
        "payload": {
          "a": "The cat sat on the mat.",
          "b": "A feline rested on the rug.",
          "c": "Interest rates rose sharply last quarter."
        }
      },
      "position": {
        "x": 0,
        "y": 0
      }
    },
    {
      "id": "embA",
      "type": "ai.embeddings",
      "label": "Embed A",
      "category": "ai",
      "config": {
        "provider": "ollama",
        "baseUrl": "",
        "apiKey": "",
        "model": "nomic-embed-text",
        "inputMode": "field",
        "inputField": "a",
        "timeoutMs": 120000
      },
      "position": {
        "x": 530,
        "y": 0
      },
      "attachments": {
        "model": "emb"
      }
    },
    {
      "id": "embB",
      "type": "ai.embeddings",
      "label": "Embed B",
      "category": "ai",
      "config": {
        "provider": "ollama",
        "baseUrl": "",
        "apiKey": "",
        "model": "nomic-embed-text",
        "inputMode": "field",
        "inputField": "b",
        "timeoutMs": 120000
      },
      "position": {
        "x": 530,
        "y": 178
      },
      "attachments": {
        "model": "emb"
      }
    },
    {
      "id": "embC",
      "type": "ai.embeddings",
      "label": "Embed C",
      "category": "ai",
      "config": {
        "provider": "ollama",
        "baseUrl": "",
        "apiKey": "",
        "model": "nomic-embed-text",
        "inputMode": "field",
        "inputField": "c",
        "timeoutMs": 120000
      },
      "position": {
        "x": 530,
        "y": 356
      },
      "attachments": {
        "model": "emb"
      }
    },
    {
      "id": "emb",
      "type": "ai.model",
      "label": "Embeddings (local)",
      "category": "ai",
      "config": {
        "provider": "ollama",
        "baseUrl": "",
        "apiKey": "",
        "model": "nomic-embed-text",
        "models": [],
        "temperature": 0.2,
        "maxTokens": 512
      },
      "position": {
        "x": 530,
        "y": 578
      }
    },
    {
      "id": "join",
      "type": "logic.merge",
      "label": "Join",
      "category": "flow",
      "config": {
        "mode": "append",
        "numberInputs": 3
      },
      "position": {
        "x": 1060,
        "y": 34
      }
    },
    {
      "id": "score",
      "type": "utility.javascript",
      "label": "Cosine similarity",
      "category": "script",
      "config": {
        "code": "function cos(x, y) { var d = 0, nx = 0, ny = 0; for (var i = 0; i < x.length; i++) { d += x[i] * y[i]; nx += x[i] * x[i]; ny += y[i] * y[i]; } return d / (Math.sqrt(nx) * Math.sqrt(ny)); }\nvar rows = Array.isArray(input) ? input : [input];\nvar vecs = rows.map(function (r) { return r.embedding; }).filter(Boolean);\nreturn { dims: vecs[0] ? vecs[0].length : 0, sameMeaning: +cos(vecs[0], vecs[1]).toFixed(3), unrelated: +cos(vecs[0], vecs[2]).toFixed(3) };",
        "outputs": [
          "output"
        ]
      },
      "position": {
        "x": 1590,
        "y": 34
      }
    },
    {
      "id": "out",
      "type": "utility.console",
      "label": "Scores",
      "category": "utility",
      "config": {
        "message": "dims={{ $json.dims }}  ·  “cat/mat” vs “feline/rug” = {{ $json.sameMeaning }}  ·  “cat/mat” vs “interest rates” = {{ $json.unrelated }}"
      },
      "position": {
        "x": 2120,
        "y": 34
      }
    }
  ],
  "edges": [
    {
      "id": "e0",
      "sourceNodeId": "seed",
      "sourcePort": "output",
      "targetNodeId": "embA",
      "targetPort": "input"
    },
    {
      "id": "e1",
      "sourceNodeId": "seed",
      "sourcePort": "output",
      "targetNodeId": "embB",
      "targetPort": "input"
    },
    {
      "id": "e2",
      "sourceNodeId": "seed",
      "sourcePort": "output",
      "targetNodeId": "embC",
      "targetPort": "input"
    },
    {
      "id": "e3",
      "sourceNodeId": "embA",
      "sourcePort": "output",
      "targetNodeId": "join",
      "targetPort": "input1"
    },
    {
      "id": "e4",
      "sourceNodeId": "embB",
      "sourcePort": "output",
      "targetNodeId": "join",
      "targetPort": "input2"
    },
    {
      "id": "e5",
      "sourceNodeId": "embC",
      "sourcePort": "output",
      "targetNodeId": "join",
      "targetPort": "input3"
    },
    {
      "id": "e6",
      "sourceNodeId": "join",
      "sourcePort": "output",
      "targetNodeId": "score",
      "targetPort": "input"
    },
    {
      "id": "e7",
      "sourceNodeId": "score",
      "sourcePort": "output",
      "targetNodeId": "out",
      "targetPort": "input"
    }
  ],
  "triggers": [
    {
      "id": "t0",
      "nodeId": "seed"
    }
  ],
  "meta": {
    "snippets": [],
    "source": "template-gallery",
    "description": "What an embedding IS: two sentences that mean the same thing and one that doesn't, turned into vectors by the ◈-wired Embeddings node, compared with cosine similarity in plain JavaScript. The related pair scores high; the stranger scores low."
  }
}

Generated from the verified demo corpus — this exact document seeds and runs on a fresh Flowdrome. Raw JSON: ai-09-embeddings-meaning-as-numbers.json.