_OpenSource Web4 agent & app starter kit_

# Search by meaning, counted on your own computer

Every element of your node turns its texts into vectors here: one local multilingual model, no OpenAI key, and the texts never leave the computer.

[Connect your element](#connect)
[Under the hood](#hood)

## How a text becomes a vector

#### Your element

Sends its texts: a diary line, a question, the description of a skill. Up to 256 in one call.

#### Embeddings

Checks the node key and passes the texts to the model, one batch at a time.

#### The model

Reads up to 128 tokens of each text, in any of about 50 languages.

#### 384 numbers

Each text comes back as a vector, and texts that mean the same come back close together.

The vectors element, the knowledge graph and the deep memory keep these vectors and find a text by its meaning, whatever words and language the question uses.

## On, asleep only when memory is short

The element starts with the node. With less than 0.5 GB of free memory the node may put it to sleep; the first call or a calendar entry wakes it in seconds, and above 1 GB free it comes back by itself.

## One meaning, one place

Each bar is one of the 384 numbers. «Привет» and «Hello» are one greeting in two languages, so their vectors nearly coincide. «Fix a leaking kitchen faucet» means something else and has almost nothing in common with the greeting. The number next to a row is its cosine with the first row: 1 means the same meaning, 0 means unrelated.

- Привет
- Hello
- Fix a leaking kitchen faucet

These are the vectors of this element’s own test, counted on an Intel Mac. Linux, Windows and Apple silicon give the same numbers.

## What changes for you

| Without it | With the embeddings element |
| --- | --- |
| Search by meaning needs an OpenAI key and a bill for every text | No key and no bill: the model runs on your computer |
| Every text you store goes to an outside service | The texts never leave the computer |
| The model behind an outside API can change without notice | The model file is pinned by its checksum and changes only when the owner decides |
| Vectors counted elsewhere may not match yours | The same text gives the same vector on Linux, Windows and macOS, measured |
| Each element counts vectors its own way | One model and one door for the whole node |

## Beside an OpenAI model

Everything here runs on your own computer: the model file lies in the node, and the texts never go out. This is how it compares with OpenAI's smallest embedding model.

|  | The node's embeddings | OpenAI text-embedding-3-small |
| --- | --- | --- |
| Where it is counted | On your computer | On OpenAI's servers, over the internet |
| Key and bill | None | An OpenAI key; about 62,500 pages per dollar |
| Where your texts go | Nowhere | To OpenAI |
| Vector size | 384 numbers | 1536 numbers |
| Longest text read | 128 tokens | 8192 tokens |

OpenAI's figures: its embeddings guide, developers.openai.com/api/docs/guides/embeddings.

## Connect your element

Any element of the node calls the door on this computer with the node key. It sends up to 256 texts and gets one normalized vector for each, in the same order.

```
curl -s "$EMBEDDINGS_URL/api/embed" \
  -H "X-Node-Key: $SETTINGS_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"texts":["Привет","Hello"]}'

{ "model": "paraphrase-multilingual-MiniLM-L12-v2", "dims": 384,
  "vectors": [[0.0356, 0.0416, …], [0.0312, …]] }
```

`GET /api/embed-status` names the model, its size and whether it is ready. A caller learns the size there and never assumes it.

## Under the hood

| Part | What it is |
| --- | --- |
| The model | `paraphrase-multilingual-MiniLM-L12-v2` from sentence-transformers: 384 numbers, about 50 languages, 128 tokens of each text, mean pooling, normalized vectors |
| The runtime | `onnxruntime-node` 1.21.0 through `@huggingface/transformers` 3.8.1, inside this element’s own process, with no Python |
| The file | 235 MB, downloaded once from this element’s own GitHub release and checked by its sha256 before every load |
| Memory | About 0.8 GB after the load, up to about 1.0 GB while 100 texts are counted |
| Speed | A short text in 6 to 25 ms, 100 long texts in about 8 seconds on a 2016 Intel laptop |
| Changing the model | Every stored vector of the node would have to be counted again, so only the owner decides it |

## Your own builder comes with it

Every element of the node comes with its own Claude Code agent and can get its own Telegram bot. When something in this element should change, write to its bot from your phone, and the agent updates the logic or the design.

The agent works only in its element's folder and never reads the whole node, so each change costs fewer tokens. Your Claude Code subscription pays for it.

- The element's bot is connected in the core, on its «Telegram» page.
- The agent returns a commit; you look at it in «Preview» and accept it or turn it down.
- At the computer, the agent's terminal is in the core, in this element's «Build».

## Open source

Built by Fractera for the [Lagrix](https://lagrix.dev) protocol and for any web2 project that needs search by meaning without an outside service. The code is open under the MIT license: [Fractera/fractera-embeddings-starter](https://github.com/Fractera/fractera-embeddings-starter). The model is [paraphrase-multilingual-MiniLM-L12-v2](https://huggingface.co/sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2) by Nils Reimers and Iryna Gurevych, in the ONNX export by Qdrant, Apache-2.0.

## Questions and answers

**Does anything leave my computer?**
No. The texts, the model and the vectors stay on the computer; no key and no internet are needed.

**When is OpenAI's model the better choice?**
For long texts in one piece: it reads up to 8192 tokens, this model 128. For the node's short texts, a diary line or a question, the local model is enough.

**Are the vectors the same on every computer?**
Yes. The same text gives the same vector on Linux, Windows and macOS; the element checks it itself.