# Search by meaning

> How nexxus turns knowledge entries, document content and conversations into embeddings so the AI Assistant finds things by what they mean. Choose the embedding model, import documents, reindex, switch it off, and know the limits.

Tom Keller asks the AI Assistant: "How many days off do I get on a four-day week?" The employee handbook does not contain that sentence. It has a section called "Leave entitlement with reduced working hours". A search for words would miss it. A search by meaning finds it, because both talk about the same thing.

For that, nexxus turns text into **embeddings**: long lists of numbers (vectors) that place texts with similar meaning close to each other. A German question then finds an English document, "PDF broken" finds "PDF upload failure", and a paraphrase finds the original. This page explains what nexxus embeds, which model does the work, and what you can control.

## How it works

<Flow
  steps={[
    { icon: 'file-text', title: 'Text arrives', text: 'A knowledge entry is saved or a document is uploaded to Files.' },
    { icon: 'scissors', title: 'Split', text: 'Documents are split into sections at their headings.', tone: 'neutral' },
    { icon: 'scatter-chart', title: 'Embed', text: 'The embedding model turns each section into a vector.', tone: 'cyan' },
    { icon: 'database', title: 'Store', text: 'nexxus keeps the vectors in PostgreSQL with pgvector.', tone: 'lavender' },
    { icon: 'search', title: 'Find', text: 'The AI Assistant compares a question with the vectors and checks rights.' },
  ]}
  caption="The embedding model runs at your AI provider. The vectors stay in your nexxus database."
/>

## What gets embedded

| Content | When | Who can find it |
|---|---|---|
| Entries in <Ui>Knowledge</Ui> (name, description and content) | After every save. Sections imported from a document only when you run <Ui>Generate embeddings</Ui>. | Everyone the entry is visible to: <Ui>Personal</Ui> (only the creator), <Ui>Business unit</Ui> (the unit and its sub-units) or <Ui>Company</Ui> (everyone) |
| The content of documents in Files | When a document is uploaded, when a new version is saved, and when a draft is turned into a version | Only people who may at least view the document. nexxus checks this per document on every search. |
| A running summary of each conversation | Whenever the summary changes | Only the avatar the conversation was held with, and only for the person who held it |

The conversation summaries are what lets an avatar remember earlier conversations ("what did we agree with Nordwind AG about the relaunch?"). Knowledge and documents are what most people mean by search.

## How the AI Assistant searches

**Knowledge** is searched in two ways at once: by meaning (vector similarity) and by words (PostgreSQL full-text search). nexxus merges the two result lists by rank, so an exact error message and a loose paraphrase both find their entry. If the embedding provider is down, the word search still answers.

Entries that actually helped in answers get a boost in later searches. That boost fades by one percent per day without use, so knowledge that nobody needs any more sinks back.

Knowledge search runs automatically in every conversation where the connector <Ui>Company knowledge</Ui> is active. It is installed and active by default. If someone switches it off in a conversation, the AI Assistant does not search knowledge there. See [Connectors](/plugins/overview/).

**Document content** is searched by meaning only. The AI Assistant over-fetches candidates, drops every section from a document the person may not view, and returns the rest.

## Before you start

- A provider with an embedding model is connected and active. See [Connect your AI](/setup/connect-ai/).
- To choose the model you need the permission block <Ui>AI Providers</Ui> with <Ui>Write</Ui>. To switch embeddings on or off you need the admin role.

## Choose the embedding model

The embedding model must produce vectors with exactly **1536 dimensions**, because that is the size of the vector columns in the database. OpenAI's `text-embedding-3-small` does. Models that can shorten their output, such as `text-embedding-3-large`, also work, because nexxus asks for 1536.

If you select nothing, nexxus uses `text-embedding-3-small` through your OpenAI provider. Without an OpenAI provider, select a model explicitly, or nothing gets embedded.

<Steps>

1. Open <MenuPath to="AI > Set up AI > AI Providers" /> and click the provider that offers the embedding model.

2. Click <Ui>Synchronise models</Ui> if you have not done so since the provider added the model. The tab <Ui>Embeddings</Ui> appears as soon as the provider has at least one embedding model.

3. Open <Ui>Embeddings</Ui> and turn on <Ui>Use</Ui> for the model. If another provider holds the selection, the tab tells you and your choice replaces it.

   <Screenshot src={shot_ai_embeddings_tab} url="/ai-providers/openai" alt={"The Embeddings tab with the selected embedding model"} caption={"One embedding model applies to the whole workspace."} />

4. Click <Ui>Save</Ui>. If this changes the model your workspace embeds with, nexxus asks first: <Ui>Switch embedding model?</Ui> Confirm with <Ui>Switch and recompute</Ui>.

   <Screenshot src={shot_ai_embeddings_switch_dialog} url="/ai-providers/openai" alt={"The confirmation before switching the embedding model"} caption={"After the switch, nexxus recalculates every vector."} />

</Steps>

Before it saves, nexxus embeds a short test text with the new model. If the provider has no usable key or the vectors have the wrong size, the save is refused and the message tells you why (see [When something goes wrong](#when-something-goes-wrong)). Nothing changes in that case.

## When the model changes, everything is recalculated

Vectors from two different models cannot be compared. So when the effective embedding model of your workspace changes, nexxus throws away every stored vector and calculates all of them again from the stored text, for knowledge entries and for document sections. The documents are not read again; only the vectors are new.

This happens when you select another model, when you delete the provider that held the selection, and when you switch that provider off. Until the recalculation is through, search by meaning finds less. It costs one embedding call per knowledge entry and per document section, which you see on the usage page if the model has a price.

## Import documents into Knowledge

Uploading a handbook to Files makes it searchable for the people who may see it. To make it part of the company knowledge instead, with its own visibility and the boost for useful entries, import it into <Ui>Knowledge</Ui>.

<Steps>

1. Open <MenuPath to="AI > Work with AI > Knowledge" />.

2. Click <Ui>Import document</Ui> and pick the file.

3. A dialog asks for the <Ui>Category for the imported sections</Ui>. The default is <Ui>General</Ui>. Enter something that groups the sections, for example "HR", and click <Ui>Import</Ui>.

   <Screenshot src={shot_ai_knowledge_import} url="/ai-knowledge" alt={"The import dialog asking for a category"} caption={"The category groups the sections of the imported document."} />

4. A message confirms that the import has started. The sections appear in the list after a short while, with the type <Ui>Document section</Ui>.

5. Click <Ui>Generate embeddings</Ui>. nexxus embeds every entry that has no vector yet. The message "Bulk vectorization started for 12 items" (with your number) confirms it, or "All knowledge items are already vectorized" if there is nothing to do.

</Steps>

Each entry shows on its detail page whether it is <Ui>Vectorised</Ui> or <Ui>Not vectorised</Ui>, and under <Ui>Retrieval statistics</Ui> how often the AI Assistant found it and used it.

<Screenshot src={shot_ai_knowledge_list} url="/ai-knowledge" alt={"The knowledge list with its action bar"} caption={"Import document and Generate embeddings sit in the action bar at the bottom."} />

:::tip[Rules that always apply]
An entry with <Ui>Always in the prompt</Ui> set to <Ui>In every prompt</Ui> goes into every conversation, whether search finds it or not. Use that only for short rules everyone must follow. Long entries in every prompt make each answer slower and more expensive, and that is what search by meaning is there to avoid.
:::

## Reindex

| Situation | What to do |
|---|---|
| You changed the embedding model | Nothing. nexxus recalculates all vectors on its own. |
| Knowledge entries show <Ui>Not vectorised</Ui> | Click <Ui>Generate embeddings</Ui> in <Ui>Knowledge</Ui>. |
| A document in Files changed | Nothing. Every new version is split and embedded again. |
| Documents were uploaded before content search existed | Your operator can start the backfill: `POST /api/dms-document/reindex-content` indexes every document of the workspace that has no sections yet. It runs in the background and skips documents that are done. |
| Documents were uploaded while embeddings were switched off | Their sections exist, but without vectors. They get vectors when a new version is saved or when the embedding model changes. |

## Turn embeddings off

Some companies do not want any text to go to an embedding provider. You can switch embeddings off for your workspace.

<Steps>

1. Open <MenuPath to="Administration > Operations > System configuration" />.

2. In the section <Ui>AI embeddings</Ui>, set <Ui>Enable embeddings (vectorisation)</Ui> to <Ui>Off</Ui>.

   <Screenshot src={shot_ai_system_config_embeddings} url="/system-config" alt={"The system configuration sections for embeddings and AI costs"} caption={"Switched off, no text goes to an embedding provider."} />

3. Click <Ui>Save</Ui>. The setting applies within a few seconds, no restart needed.

</Steps>

What changes when embeddings are off:

- No text leaves for embedding. Knowledge entries and document sections are still stored, without vectors.
- A recalculation that is running stops at the next entry.
- Knowledge search keeps working through its word search.
- The AI Assistant's search inside document content finds nothing, because it works by meaning only.
- Avatars recall earlier conversations through word search only.

Switching back on calculates nothing by itself. Use <Ui>Generate embeddings</Ui> for knowledge entries.

:::note[Locked by the operator]
If your operator has switched embeddings off for the whole installation (`AI_EMBEDDINGS_ENABLED=false`), the system configuration shows a warning that starts with "Embeddings are locked by operations" and the switch cannot be turned on. Your saved setting applies again once the lock is lifted.
:::

## Look at the vectors

Admins can open <MenuPath to="AI > Set up AI > Vector Viewer" /> to see the vector columns of chat summaries, document text and knowledge entries: how many rows your organisation has in each and how many of them already carry a vector. Rows and hits show only what you may see elsewhere in the app, so document text only from documents you may open. The tab <Ui>Search</Ui> runs a <Ui>Similarity Search</Ui>: enter a <Ui>Search Text</Ui>, choose <Ui>Max Results</Ui> and click <Ui>Search</Ui>. Each hit shows its <Ui>Similarity</Ui>. That is a quick way to check whether a new embedding model finds what you expect.

<Screenshot src={shot_ai_vector_viewer} url="/vectorViewer" alt={"The Vector Viewer with a similarity search"} caption={"A quick check whether the embedding model finds what you expect."} />

## What happens behind the scenes

- **Extraction.** nexxus sends documents to a Docling service, which extracts the text, with OCR for scanned pages. Your operator chooses which Docling service is used (setting `docling.api.url`). If documents must not leave your network, run Docling yourself.
- **Splitting.** Sections start at every heading. A section is closed after about 2000 characters and continues with the same heading marked "(continued)". Fragments under 50 characters are dropped.
- **Through the gateway.** nexxus never calls the embedding provider directly. It asks the AI gateway, which uses your workspace's selected model and key.
- **Failures do not block work.** If embedding fails for one entry or section, nexxus saves it anyway without a vector, and the next run of <Ui>Generate embeddings</Ui> or the next new version tries again.
- **Storage.** PostgreSQL with the pgvector extension. Knowledge entries and document sections live in separate tables on purpose: document content is only ever returned after a rights check per document.

## Limits

- The vector size is fixed at 1536. An embedding model with another size cannot be selected. That rules out many small models you might run on your own server.
- Conversations from before an avatar had a memory get no vector afterwards. Word search still finds them.
- A switch of the embedding model costs one embedding call per entry and section of the whole workspace.
- Chat, voice and image generation do not depend on embeddings. Switching embeddings off only affects search.

## When something goes wrong

| Message or symptom | Cause and fix |
|---|---|
| Saving fails with "Embedding API error: Embedding model ... returns 768 dimensions, the vector store needs 1536." | The model produces vectors of the wrong size. Choose a model with 1536 dimensions. |
| Saving fails with a message that contains `No usable provider` | The provider of that model is switched off or has no key. Check <Ui>Provider active</Ui> and <Ui>Credentials</Ui>. |
| The Vector Viewer search says "Embeddings sind deaktiviert" (embeddings are switched off) | Embeddings are off in the system configuration or locked by the operator. |
| Imported sections never appear | Docling could not convert the file. The reason is in the server log; try another format or ask your operator. |
| Many entries stay <Ui>Not vectorised</Ui> after <Ui>Generate embeddings</Ui> | Embedding calls fail. Check the embedding provider with <Ui>Test connection</Ui>, and check that embeddings are switched on. |
| Search finds less than before | A model switch is still recalculating. Wait, and check the share of rows with vectors in the Vector Viewer. |
| The AI Assistant finds nothing inside documents | Embeddings are off, the document was uploaded while they were off, or the person may not view the document. |

## Next steps

<CardGrid>
  <LinkCard title="Connect your AI" description="Providers, models and the other model purposes." href="/setup/connect-ai/" />
  <LinkCard title="Working with the AI Assistant" description="How sources show up under the AI Assistant's answers." href="/use/assistant/" />
  <LinkCard title="Files" description="Where documents live and who may see them." href="/use/files/" />
</CardGrid>