> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orq.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Knowledge & Memory

> Build internal and external knowledge bases for RAG, and add persistent memory stores to ground AI agents in domain data and conversation history.

**Orq.ai** provides three approaches to backing an agent with persistent knowledge:

<CardGroup cols={3}>
  <Card title="Knowledge Bases" icon="database" href="#knowledge-bases">
    Upload and index documents for retrieval-augmented generation. Ground model responses in your domain data.
  </Card>

  <Card title="External Knowledge Bases" icon="plug" href="#external-knowledge-bases">
    Connect your own vector database via a standard API. Keep data management on your infrastructure.
  </Card>

  <Card title="Memory Stores" icon="brain" href="#memory-stores">
    Entity-scoped long-term memory that persists across sessions. Enables personalization and context continuity.
  </Card>
</CardGroup>

All three can be attached to an Agent to build richer, context-aware experiences:

<CardGroup cols={2}>
  <Card title="Connect Knowledge Bases to Agents" icon="robot" href="/docs/agents/build#connect-knowledge-bases">
    Attach a Knowledge Base so the agent queries it automatically when relevant.
  </Card>

  <Card title="Connect Memory Stores to Agents" icon="robot" href="/docs/agents/build#connect-memory-stores">
    Give the agent persistent per-entity memory across conversations.
  </Card>
</CardGroup>

## Use-cases

All three solutions store information that an agent can retrieve, but they serve different purposes depending on where the data lives and how it changes.

**[Knowledge Bases](#knowledge-bases)** index documents you upload into **Orq.ai**. The platform handles embeddings, chunking, and retrieval. Use them when you have documents to ingest and want a fully managed RAG pipeline.

**[External Knowledge Bases](#external-knowledge-bases)** connect to a vector database you already operate. **Orq.ai** calls your API at query time and passes the results to the model. Use them when your data cannot leave your infrastructure, or when you already have an embedding pipeline.

**[Memory Stores](#memory-stores)** store arbitrary text per entity, such as a user or session. Documents accumulate over time and are retrieved semantically on each interaction. Use them when your agent needs to remember what a specific person said or did in a previous conversation.

|                              | [Knowledge Base](#knowledge-bases) | [External Knowledge Base](#external-knowledge-bases) | [Memory Store](#memory-stores)           |
| ---------------------------- | ---------------------------------- | ---------------------------------------------------- | ---------------------------------------- |
| **Data hosted by**           | Orq.ai                             | Your infrastructure                                  | Orq.ai                                   |
| **Document upload**          | Via Studio or API                  | Managed externally                                   | Via API per entity                       |
| **Embeddings**               | Managed by Orq.ai                  | Managed externally                                   | Managed by Orq.ai                        |
| **Search config**            | Full control                       | Delegated to your API                                | Automatic                                |
| **Reranking**                | Supported                          | Post-processing                                      | Not applicable                           |
| **Agentic RAG**              | Supported                          | Supported                                            | Not applicable                           |
| **Metadata filtering**       | Full support                       | Depends on your API                                  | Via entity metadata                      |
| **Scoped per entity**        | No                                 | No                                                   | Yes                                      |
| **Persists across sessions** | Yes (static content)               | Yes (static content)                                 | Yes (accumulates over time)              |
| **Best for**                 | Domain documents, FAQs, policies   | Existing vector DBs                                  | User history, preferences, session state |

***

## Knowledge Bases

A Knowledge Base is a database that provides relevant, specific information for an LLM to retrieve at query time. Knowledge can include domain-specific or business-specific information, ensuring the details surfaced to models are both correct and accurate.

### Create a Knowledge Base

<Tabs>
  <Tab title="AI Studio" icon="https://mintcdn.com/orqai/My16MDKJXrKALEHC/images/logos/ai-studio-round.svg?fit=max&auto=format&n=My16MDKJXrKALEHC&q=85&s=ac04dd509320d58ab9701cb6d6137733" width="100" height="100" data-path="images/logos/ai-studio-round.svg">
    Use the `+` button in a chosen [Project](/docs/projects) and select **Knowledge Base > Internal**.

    Press **Create Knowledge**. The following modal appears:

    <Frame caption="Enter a unique Key used to reference your Knowledge Base within Prompts and Deployments. Choose an Embedding Model for knowledge search.">
      <img src="https://mintcdn.com/orqai/x_6IXnot9ETOc_0g/images/docs/73c85744ed55dec5af1da825f903f2fa209d6e3af0d5c4d0618373c9db666193-Screenshot_2024-10-02_at_12.33.56.png?fit=max&auto=format&n=x_6IXnot9ETOc_0g&q=85&s=ac7aab60eae839062e4f6293ef8d44e5" alt="Enter a unique Key used to reference your Knowledge Base within Prompts and Deployments. Choose an Embedding Model for knowledge search." width="2376" height="1172" data-path="images/docs/73c85744ed55dec5af1da825f903f2fa209d6e3af0d5c4d0618373c9db666193-Screenshot_2024-10-02_at_12.33.56.png" />
    </Frame>

    <Warning>
      You can only create a Knowledge Base once you have activated an embedding model within the [AI Router](/docs/model-garden/overview).
    </Warning>
  </Tab>

  <Tab title="API & SDK" icon="code">
    Use the [Create a Knowledge API](/reference/knowledge-bases/create-a-knowledge).

    Required inputs:

    * `key`: the name used to reference the Knowledge Base
    * `embedding_model`: formatted as `supplier/model_name`, for example `cohere/embed-english-v3.0`. Find embedding models in the [AI Router](/docs/model-garden/overview) by filtering for `Model Type = Embedding`.
    * `path`: the Project and folder, formatted as `project/path`, for example `Default/Production`

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request POST \
           --url https://api.orq.ai/v2/knowledge \
           --header 'accept: application/json' \
           --header 'content-type: application/json' \
           --header 'authorization: Bearer <API_KEY>' \
           --data '
      {
        "key": "<key>",
        "embedding_model": "<model>",
        "path": "<path>",
        "type": "internal"
      }
      '
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      from orq_ai_sdk import Orq
      import os

      with Orq(
          api_key=os.getenv("ORQ_API_KEY", ""),
      ) as orq:

          res = orq.knowledge.create(request={
              "key": "key",
              "embedding_model": "supplier/model",
              "path": "project/path",
              "type": "internal"
          })

          print(res)
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      import { Orq } from "@orq-ai/node";

      const orq = new Orq({
        apiKey: process.env["ORQ_API_KEY"] ?? "",
      });

      const result = await orq.knowledge.create({
        key: "key",
        embeddingModel: "supplier/model",
        path: "project/path",
        type: "internal",
      });

      console.log(result);
      ```
    </CodeGroup>

    Save the `knowledge_id` returned from the response.
  </Tab>
</Tabs>

### Datasource and Chunking

A source represents a document loaded within the Knowledge Base. Documents are parsed and split into chunks that models search and retrieve at query time.

#### Create a Datasource

<Tabs>
  <Tab title="AI Studio" icon="https://mintcdn.com/orqai/My16MDKJXrKALEHC/images/logos/ai-studio-round.svg?fit=max&auto=format&n=My16MDKJXrKALEHC&q=85&s=ac04dd509320d58ab9701cb6d6137733" width="100" height="100" data-path="images/logos/ai-studio-round.svg">
    Select **Add Source** to upload a document. Supported formats: TXT, PDF, DOCX, CSV, XML.

    <img src="https://mintcdn.com/orqai/x_6IXnot9ETOc_0g/images/docs/6da0ab7-iScreen_Shoter_-_Google_Chrome_-_240815131837.jpg?fit=max&auto=format&n=x_6IXnot9ETOc_0g&q=85&s=f952ba35d4fd0555688caf10ef3ac9b9" alt="Create a Datasource" width="1712" height="661" data-path="images/docs/6da0ab7-iScreen_Shoter_-_Google_Chrome_-_240815131837.jpg" />

    <Warning>
      A single source document must be a maximum of 10MB.
    </Warning>

    Once your document has been processed, the following summary is displayed:

    <Frame caption="See details of the data parsed into your Knowledge Base and estimate the cost of retrieval.">
      <img src="https://mintcdn.com/orqai/E8L3R46ivX7g9-QI/images/docs/c2013f3-Screenshot_2024-08-15_at_12.40.15.png?fit=max&auto=format&n=E8L3R46ivX7g9-QI&q=85&s=6e6dd566c2ac9622cdfb6c0c56ebba13" alt="See details of the data parsed into your Knowledge Base and estimate the cost of retrieval." width="2268" height="532" data-path="images/docs/c2013f3-Screenshot_2024-08-15_at_12.40.15.png" />
    </Frame>
  </Tab>

  <Tab title="API & SDK" icon="code">
    The most common workflow is uploading a file before creating a datasource. Use the [Upload a file API](/reference/files/upload-a-file).

    <Warning>
      The maximum file size is 10MB.
    </Warning>

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request POST \
           --url https://api.orq.ai/v2/files \
           --header 'accept: application/json' \
           --header 'authorization: Bearer <API_KEY>' \
           --header 'content-type: multipart/form-data' \
           --form file='@file_path'
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      from orq_ai_sdk import Orq
      import os

      with Orq(
          api_key=os.getenv("ORQ_API_KEY", ""),
      ) as orq:

          res = orq.files.create(file={
              "file_name": "example.file",
              "content": open("example.file", "rb"),
          })

          print(res)
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      import { Orq } from "@orq-ai/node";
      import { openAsBlob } from "node:fs";

      const orq = new Orq({
        apiKey: process.env["ORQ_API_KEY"] ?? "",
      });

      const result = await orq.files.create({
        file: await openAsBlob("example.file"),
      });

      console.log(result);
      ```
    </CodeGroup>

    Save the `file_id` returned from the response, then create a datasource with the [Create a datasource API](/reference/knowledge-bases/create-a-new-datasource).

    Required fields: `knowledge_id`, `display_name`, and optionally `file_id` to pre-populate the datasource.

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request POST \
           --url https://api.orq.ai/v2/knowledge/knowledge_id/datasources \
           --header 'accept: application/json' \
           --header 'authorization: Bearer <API_KEY>' \
           --header 'content-type: application/json' \
           --data '
      {
        "display_name": "name",
        "file_id": "file_id"
      }
      '
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      from orq_ai_sdk import Orq
      import os

      with Orq(
          api_key=os.getenv("ORQ_API_KEY", ""),
      ) as orq:

          res = orq.knowledge.create_datasource(knowledge_id="knowledge_id",
                                                file_id="file_id",
                                                display_name="name")

          print(res)
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      import { Orq } from "@orq-ai/node";

      const orq = new Orq({
        apiKey: process.env["ORQ_API_KEY"] ?? "",
      });

      const result = await orq.knowledge.createDatasource({
        knowledgeId: "knowledge_id",
        requestBody: {
          displayName: "name",
          fileId: "file_id",
        },
      });

      console.log(result);
      ```
    </CodeGroup>

    Save the `datasource_id` returned from the response.
  </Tab>
</Tabs>

#### Add Chunks to a Datasource

<Tabs>
  <Tab title="API & SDK" icon="code">
    Use the [Create chunk API](/reference/knowledge-bases/create-chunks-for-a-datasource) to manually add chunks to a datasource.

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request POST \
         --url https://api.orq.ai/v2/knowledge/<knowledge_id>/datasources/<datasource_id>/chunks \
         --header 'accept: application/json' \
         --header 'authorization: Bearer <API_KEY>' \
         --header 'content-type: application/json' \
         --data '
      [
        {
          "text": "Your chunk content here.",
          "metadata": {
            "source": "manual",
            "topic": "example"
          }
        }
      ]
      '
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      from orq_ai_sdk import Orq
      import os

      with Orq(api_key=os.getenv("ORQ_API_KEY", "")) as orq:
          res = orq.knowledge.create_chunks(
              knowledge_id="<knowledge_id>",
              datasource_id="<datasource_id>",
              request_body=[{
                  "text": "Your chunk content here.",
                  "metadata": {
                      "source": "manual",
                      "topic": "example"
                  }
              }]
          )
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      import { Orq } from "@orq-ai/node";

      const orq = new Orq({ apiKey: process.env["ORQ_API_KEY"] ?? "" });

      await orq.knowledge.createChunks({
        knowledgeId: "<knowledge_id>",
        datasourceId: "<datasource_id>",
        requestBody: [{
          text: "Your chunk content here.",
          metadata: {
            source: "manual",
            topic: "example",
          },
        }],
      });
      ```
    </CodeGroup>
  </Tab>
</Tabs>

#### View Datasource Chunks

<Tabs>
  <Tab title="API & SDK" icon="code">
    Use the [List all chunks API](/reference/knowledge-bases/list-all-chunks-for-a-datasource) to inspect chunks in a datasource.

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request GET \
           --url https://api.orq.ai/v2/knowledge/<knowledge_id>/datasources/<datasource_id>/chunks \
           --header 'accept: application/json' \
           --header 'authorization: Bearer <API_KEY>'
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      from orq_ai_sdk import Orq
      import os

      with Orq(
          api_key=os.getenv("ORQ_API_KEY", ""),
      ) as orq:

          res = orq.knowledge.list_chunks(knowledge_id="<id>", datasource_id="<id>", status="completed")

          print(res)
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      import { Orq } from "@orq-ai/node";

      const orq = new Orq({
        apiKey: process.env["ORQ_API_KEY"] ?? "",
      });

      const result = await orq.knowledge.listChunks({
        knowledgeId: "<id>",
        datasourceId: "<id>",
        status: "completed",
      });

      console.log(result);
      ```
    </CodeGroup>
  </Tab>
</Tabs>

#### Chunk Strategy

<Tabs>
  <Tab title="AI Studio" icon="https://mintcdn.com/orqai/My16MDKJXrKALEHC/images/logos/ai-studio-round.svg?fit=max&auto=format&n=My16MDKJXrKALEHC&q=85&s=ac04dd509320d58ab9701cb6d6137733" width="100" height="100" data-path="images/logos/ai-studio-round.svg">
    <Note>
      When using the **AI Studio**, you only have access to the following chunk strategies. For more options, see the API & SDK tab.
    </Note>

    <Frame caption="Choose a chunking option when uploading a file in the Knowledge Base">
      <img src="https://mintcdn.com/orqai/JYIeZDVhIg6sts6D/images/chunking-strategy-ai-studio.png?fit=max&auto=format&n=JYIeZDVhIg6sts6D&q=85&s=92a4f709f38c0c63de4ca9e8d1a2fe6a" alt="Choose a chunking option when uploading a file in the Knowledge Base" width="722" height="415" data-path="images/chunking-strategy-ai-studio.png" />
    </Frame>

    <AccordionGroup>
      <Accordion title="Default" icon="wand-magic-sparkles">
        Automatically set chunk and preprocessing rules. Recommended for unfamiliar users.
      </Accordion>

      <Accordion title="Advanced" icon="sliders">
        **Maximum Chunk Length**: Defines the maximum size of each chunk. Larger size means more information per chunk.

        **Chunk Overlap**: Defines the number of characters overlapping neighboring chunks. Higher values increase redundancy between chunks but improve the likelihood that relevant information is returned to models.
      </Accordion>
    </AccordionGroup>

    <Tip>
      Use the sidebar to preview chunks using the chosen chunking strategy.
    </Tip>
  </Tab>

  <Tab title="API & SDK" icon="code">
    Use the [Chunking API](/reference/chunking/parse-text) to prepare content for datasource ingestion before adding chunks manually.

    **Common parameters:**

    * `text` (required): the text content to chunk
    * `strategy` (required): `token`, `sentence`, `recursive`, `semantic`, or `agentic`
    * `metadata` (optional, default: `true`): include metadata per chunk (start\_index, end\_index, token\_count)
    * `return_type` (optional, default: `"chunks"`): `"chunks"` (with metadata) or `"texts"` (plain strings)

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request POST \
           --url https://api.orq.ai/v2/chunking \
           --header 'accept: application/json' \
           --header 'authorization: Bearer ORQ_API_KEY' \
           --header 'content-type: application/json' \
           --data '
      {
        "strategy": "semantic",
        "text": "Your text content here...",
        "chunk_size": 55,
        "embedding_model": "openai/text-embedding-3-small"
      }
      '
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      import { Orq } from "@orq-ai/node";

      const orq = new Orq({
        apiKey: process.env["ORQ_API_KEY"] ?? "",
      });

      const result = await orq.chunking.parse({
        text: "Your text content here...",
        metadata: true,
        strategy: "semantic",
        chunkSize: 256,
        threshold: 0.8,
        embeddingModel: "openai/text-embedding-3-small",
        mode: "window",
        similarityWindow: 1,
      });

      console.log(result);
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      from orq_ai_sdk import Orq
      import os

      with Orq(
          api_key=os.getenv("ORQ_API_KEY", ""),
      ) as orq:

          res = orq.chunking.parse(request={
              "text": "Your text content here...",
              "metadata": True,
              "strategy": "semantic",
              "chunk_size": 256,
              "threshold": 0.8,
              "embedding_model": "openai/text-embedding-3-small",
              "mode": "window",
              "similarity_window": 1,
          })

          print(res)
      ```
    </CodeGroup>

    The response returns a `chunks` array. Each chunk contains `id`, `text`, `index`, and optional `metadata` (start\_index, end\_index, token\_count).

    <Tip>
      Chunks can be then uploaded to an existing Datasource using the [Add Chunk to Datasource API](/reference/knowledge-bases/create-chunks-for-a-datasource).
    </Tip>

    **Chunk Settings and Strategies**

    Larger chunks hold more information but increase token use and generation cost.

    <AccordionGroup>
      <Accordion title="Token" icon="hashtag">
        Splits text into chunks based on token count. Best for ensuring chunks fit within LLM context windows and maintaining consistent chunk sizes for embedding models.

        | Parameter       | Description                                | Default |
        | --------------- | ------------------------------------------ | ------- |
        | `chunk_size`    | Maximum tokens per chunk                   | 512     |
        | `chunk_overlap` | Number of tokens to overlap between chunks | 0       |
      </Accordion>

      <Accordion title="Sentence" icon="align-left">
        Splits text at sentence boundaries while respecting token limits. Ideal for maintaining semantic coherence and readability.

        | Parameter                 | Description                                 | Default |
        | ------------------------- | ------------------------------------------- | ------- |
        | `chunk_size`              | Maximum tokens per chunk                    | 512     |
        | `chunk_overlap`           | Number of overlapping tokens between chunks | 0       |
        | `min_sentences_per_chunk` | Minimum number of sentences per chunk       | 1       |
      </Accordion>

      <Accordion title="Recursive" icon="layer-group">
        Recursively splits text using a hierarchy of separators (paragraphs, sentences, words). Versatile general-purpose chunker that preserves document structure.

        | Parameter                  | Description                          | Default                   |
        | -------------------------- | ------------------------------------ | ------------------------- |
        | `chunk_size`               | Maximum tokens per chunk             | 512                       |
        | `separators`               | Hierarchy of separators to use       | `["\n\n", "\n", " ", ""]` |
        | `min_characters_per_chunk` | Minimum characters allowed per chunk | 24                        |
      </Accordion>

      <Accordion title="Semantic" icon="brain">
        Groups semantically similar sentences using embeddings. Excellent for maintaining topic coherence and context within chunks.

        | Parameter           | Description                               | Default  |
        | ------------------- | ----------------------------------------- | -------- |
        | `chunk_size`        | Maximum tokens per chunk                  | 512      |
        | `embedding_model`   | Embedding model for similarity (required) | -        |
        | `dimensions`        | Number of dimensions for embedding output | -        |
        | `threshold`         | Similarity threshold (0-1) or "auto"      | "auto"   |
        | `mode`              | Chunking mode: "window" or "sentence"     | "window" |
        | `similarity_window` | Window size for similarity comparison     | 1        |
      </Accordion>

      <Accordion title="Agentic" icon="robot">
        AI-powered intelligent chunking that uses an LLM to determine optimal split points. Best for complex documents requiring intelligent segmentation.

        | Parameter                  | Description                                 | Default |
        | -------------------------- | ------------------------------------------- | ------- |
        | `model`                    | LLM model to use for chunking (required)    | -       |
        | `chunk_size`               | Maximum tokens per chunk                    | 1024    |
        | `candidate_size`           | Size of candidate splits for LLM evaluation | 128     |
        | `min_characters_per_chunk` | Minimum characters allowed per chunk        | 24      |
      </Accordion>

      <Accordion title="Fast" icon="bolt">
        High-performance SIMD-optimized byte-level chunking. Best for large files (>1MB) where speed and memory efficiency are critical. 2x faster and 3x less memory than token-based chunking.

        | Parameter          | Description                                                      | Default  |
        | ------------------ | ---------------------------------------------------------------- | -------- |
        | `target_size`      | Target chunk size in bytes                                       | 4096     |
        | `delimiters`       | Single-byte delimiters to split on (e.g., `"\n.?!"`)             | `"\n.?"` |
        | `pattern`          | Multi-byte pattern for splitting (e.g., `"▁"` for SentencePiece) | -        |
        | `prefix`           | Attach delimiter to start of next chunk                          | false    |
        | `consecutive`      | Split at START of consecutive delimiter runs                     | false    |
        | `forward_fallback` | Search forward if no delimiter found backward                    | false    |

        <Note>
          **When to use Fast:** Large files (>1MB), high-throughput ingestion, memory-constrained environments.

          **When NOT to use Fast:** When you need precise token counts for embedding models, small documents where speed isn't critical, or when semantic boundaries matter more than byte boundaries.
        </Note>
      </Accordion>
    </AccordionGroup>

    **Strategy Selection Guide**

    | Use Case                       | Recommended Strategy            |
    | ------------------------------ | ------------------------------- |
    | Large files (>1MB)             | Fast: 2x faster, 3x less memory |
    | RAG with precise tokens        | Token or Recursive              |
    | Semantic search                | Semantic                        |
    | Complex document understanding | Agentic                         |
    | General purpose                | Recursive                       |
  </Tab>
</Tabs>

#### Chunk Metadata

Each chunk in a Knowledge Base can carry a metadata object: a set of key-value pairs that describe the chunk's origin, topic, or any custom attribute relevant to your use case.

Metadata lets you store all your content in a single Knowledge Base while still scoping retrieval to exactly the right subset of chunks at query time.

Common use cases:

* **Multi-tenant RAG**: tag chunks by `client_id` to isolate results per customer.
* **Source filtering**: filter by `filetype` or `source` to restrict results to PDFs, support tickets, or a specific data feed.
* **Topic scoping**: tag chunks by `topic` or `category` and filter queries to stay on a single subject.

<Tabs>
  <Tab title="AI Studio" icon="https://mintcdn.com/orqai/My16MDKJXrKALEHC/images/logos/ai-studio-round.svg?fit=max&auto=format&n=My16MDKJXrKALEHC&q=85&s=ac04dd509320d58ab9701cb6d6137733" width="100" height="100" data-path="images/logos/ai-studio-round.svg">
    Open a chunk from the datasource view to access the **Edit Chunk** panel. The panel has three sections:

    * **Text**: the chunk content.
    * **Metadata**: a JSON editor pre-filled with the current metadata, or `{}` if none has been set.
    * **Enabled**: toggle to enable or disable the chunk.

    Edit the metadata JSON directly and save. The metadata object must be valid JSON with all values as strings, numbers, or booleans. Nested arrays or objects are not supported.

    <Frame caption="Metadata needs to be Valid JSON">
      <img src="https://mintcdn.com/orqai/RNkp7gDDeUt4OnKW/images/kb-metadata.gif?s=80d4ac015d43f1fe65d4cbff4d39ee2d" alt="Metadata needs to be Valid JSON" width="800" height="798" data-path="images/kb-metadata.gif" />
    </Frame>
  </Tab>

  <Tab title="API & SDK" icon="code">
    Pass an optional `metadata` object when creating chunks. Metadata values must be primitive types: strings, numbers, or booleans.

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request POST \
         --url https://api.orq.ai/v2/knowledge/<knowledge_id>/datasources/<datasource_id>/chunks \
         --header 'accept: application/json' \
         --header 'authorization: Bearer <API_KEY>' \
         --header 'content-type: application/json' \
         --data '
      [
        {
          "text": "Acme Corp signed a 3-year enterprise contract in Q1 2025.",
          "metadata": {
            "client_id": "acme_corp",
            "source": "contracts",
            "filetype": "pdf",
            "page_number": 3
          }
        }
      ]
      '
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      from orq_ai_sdk import Orq
      import os

      with Orq(api_key=os.getenv("ORQ_API_KEY", "")) as orq:
          res = orq.knowledge.create_chunks(
              knowledge_id="<knowledge_id>",
              datasource_id="<datasource_id>",
              request_body=[{
                  "text": "Acme Corp signed a 3-year enterprise contract in Q1 2025.",
                  "metadata": {
                      "client_id": "acme_corp",
                      "source": "contracts",
                      "filetype": "pdf",
                      "page_number": 3
                  }
              }]
          )
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      import { Orq } from "@orq-ai/node";

      const orq = new Orq({ apiKey: process.env["ORQ_API_KEY"] ?? "" });

      await orq.knowledge.createChunks({
        knowledgeId: "<knowledge_id>",
        datasourceId: "<datasource_id>",
        requestBody: [{
          text: "Acme Corp signed a 3-year enterprise contract in Q1 2025.",
          metadata: {
            client_id: "acme_corp",
            source: "contracts",
            filetype: "pdf",
            page_number: 3,
          },
        }],
      });
      ```
    </CodeGroup>

    **Metadata constraints:**

    * Use metadata for concise, discrete filter attributes to maximize search performance.
    * Avoid placing large text blobs in metadata. Long strings result in slower queries.
    * Keep each field's data type consistent. Non-coercible values are discarded and omitted from the chunk.
  </Tab>
</Tabs>

#### Data and PII Cleanup

<Tabs>
  <Tab title="AI Studio" icon="https://mintcdn.com/orqai/My16MDKJXrKALEHC/images/logos/ai-studio-round.svg?fit=max&auto=format&n=My16MDKJXrKALEHC&q=85&s=ac04dd509320d58ab9701cb6d6137733" width="100" height="100" data-path="images/logos/ai-studio-round.svg">
    Modify the data loaded within your sources to clean or anonymize it. Toggle on each cleanup option within the **Data Cleanup** panel.

    <img src="https://mintcdn.com/orqai/x_6IXnot9ETOc_0g/images/docs/358ebb7-iScreen_Shoter_-_Google_Chrome_-_240815132041.jpg?fit=max&auto=format&n=x_6IXnot9ETOc_0g&q=85&s=0111ff51bda3d58356c8c2be90bc898c" alt="Data and PII Cleanup" width="1471" height="529" data-path="images/docs/358ebb7-iScreen_Shoter_-_Google_Chrome_-_240815132041.jpg" />

    | Option                   | Description                                           |
    | ------------------------ | ----------------------------------------------------- |
    | **Delete emails**        | Removes email addresses from chunk content            |
    | **Delete credit cards**  | Removes credit card numbers from chunk content        |
    | **Delete phone numbers** | Removes phone numbers from chunk content              |
    | **Clean bullet points**  | Normalizes bullet point formatting                    |
    | **Clean numbered lists** | Normalizes numbered list formatting                   |
    | **Clean unicode**        | Removes or normalizes non-standard unicode characters |
    | **Clean dashes**         | Removes or normalizes dash characters                 |
    | **Clean whitespaces**    | Removes excess whitespace from chunk content          |
  </Tab>

  <Tab title="API & SDK" icon="code">
    Pass `chunking_cleanup_options` inside `chunking_options` when creating a datasource to clean or anonymize source content before it is chunked and indexed.

    | Option                 | Description                                           |
    | ---------------------- | ----------------------------------------------------- |
    | `delete_emails`        | Removes email addresses from chunk content            |
    | `delete_credit_cards`  | Removes credit card numbers from chunk content        |
    | `delete_phone_numbers` | Removes phone numbers from chunk content              |
    | `clean_bullet_points`  | Normalizes bullet point formatting                    |
    | `clean_numbered_list`  | Normalizes numbered list formatting                   |
    | `clean_unicode`        | Removes or normalizes non-standard unicode characters |
    | `clean_dashes`         | Removes or normalizes dash characters                 |
    | `clean_whitespaces`    | Removes excess whitespace from chunk content          |

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request POST \
           --url https://api.orq.ai/v2/knowledge/knowledge_id/datasources \
           --header 'accept: application/json' \
           --header 'authorization: Bearer <API_KEY>' \
           --header 'content-type: application/json' \
           --data '
      {
        "display_name": "name",
        "file_id": "file_id",
        "chunking_options": {
          "chunking_configuration": {
            "type": "default"
          },
          "chunking_cleanup_options": {
            "delete_emails": true,
            "delete_credit_cards": true,
            "delete_phone_numbers": true,
            "clean_bullet_points": true,
            "clean_numbered_list": true,
            "clean_unicode": true,
            "clean_dashes": true,
            "clean_whitespaces": true
          }
        }
      }
      '
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      from orq_ai_sdk import Orq
      import os

      with Orq(
          api_key=os.getenv("ORQ_API_KEY", ""),
      ) as orq:

          res = orq.knowledge.create_datasource(
              knowledge_id="knowledge_id",
              file_id="file_id",
              display_name="name",
              chunking_options={
                  "chunking_configuration": {
                      "type": "default"
                  },
                  "chunking_cleanup_options": {
                      "delete_emails": True,
                      "delete_credit_cards": True,
                      "delete_phone_numbers": True,
                      "clean_bullet_points": True,
                      "clean_numbered_list": True,
                      "clean_unicode": True,
                      "clean_dashes": True,
                      "clean_whitespaces": True
                  }
              }
          )

          print(res)
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      import { Orq } from "@orq-ai/node";

      const orq = new Orq({
        apiKey: process.env["ORQ_API_KEY"] ?? "",
      });

      const result = await orq.knowledge.createDatasource({
        knowledgeId: "knowledge_id",
        requestBody: {
          displayName: "name",
          fileId: "file_id",
          chunkingOptions: {
            chunkingConfiguration: {
              type: "default",
            },
            chunkingCleanupOptions: {
              deleteEmails: true,
              deleteCreditCards: true,
              deletePhoneNumbers: true,
              cleanBulletPoints: true,
              cleanNumberedList: true,
              cleanUnicode: true,
              cleanDashes: true,
              cleanWhitespaces: true,
            },
          },
        },
      });

      console.log(result);
      ```
    </CodeGroup>
  </Tab>
</Tabs>

### Embedding Models

An embedding model is a machine learning tool that transforms complex, high-dimensional data into simpler, numerical values that machines can understand, enabling semantic search.

Configure which embedding model to use to query the Knowledge Base from the **Knowledge Settings** panel.

<Frame caption="You need to have activated Embedding models within the AI Router.">
  <img src="https://mintcdn.com/orqai/E8L3R46ivX7g9-QI/images/docs/c956357-Screenshot_2024-08-15_at_12.47.07.png?fit=max&auto=format&n=E8L3R46ivX7g9-QI&q=85&s=f62ba972f3aa4433745c487a0c108b26" alt="You need to have activated Embedding models within the AI Router." width="2360" height="1252" data-path="images/docs/c956357-Screenshot_2024-08-15_at_12.47.07.png" />
</Frame>

### Agentic RAG

Incorporates AI agents into the RAG pipeline to orchestrate its components and perform additional actions beyond simple information retrieval, overcoming the limitations of a non-agentic pipeline.

Enable the **Agentic RAG** toggle in **Knowledge Settings**, then select a **Model** to use. The chosen model drives two actions:

* **Document Grading**: ensures only relevant chunks are retrieved.
* **Query Refinement**: rewrites the query if needed to improve retrieval quality.

<Frame caption="Enable Agentic RAG in Knowledge Base Settings. Configure the related model after enabling.">
  <img src="https://mintcdn.com/orqai/x_6IXnot9ETOc_0g/images/docs/0c3263dba985695146e7ff6ffe7388873e9ae574dd9c8f781abd266152a45a15-image.png?fit=max&auto=format&n=x_6IXnot9ETOc_0g&q=85&s=63b5912f792fba603fd414fe850600d1" alt="Enable Agentic RAG in Knowledge Base Settings. Configure the related model after enabling." width="2249" height="1645" data-path="images/docs/0c3263dba985695146e7ff6ffe7388873e9ae574dd9c8f781abd266152a45a15-image.png" />
</Frame>

<AccordionGroup>
  <Accordion title="Example: Query Refinement" icon="sparkles">
    See the screenshot below on how the input query gets refined.

    **Input query**: `is my suitcase too big?` is reformulated to `luggage size requirements and restrictions for carry-on and checked baggage`

    <img src="https://mintcdn.com/orqai/E8L3R46ivX7g9-QI/images/docs/a60752b564eaad351da2ea0f57305442a08d0bced932b7c9b61a580f1a6648c5-image.png?fit=max&auto=format&n=E8L3R46ivX7g9-QI&q=85&s=1cf058c94ede79c2daecb066bb746578" alt="Agentic RAG" width="3110" height="1547" data-path="images/docs/a60752b564eaad351da2ea0f57305442a08d0bced932b7c9b61a580f1a6648c5-image.png" />
  </Accordion>
</AccordionGroup>

### Search Modes

Different Search modes are available for Information to be found in Knowledge Bases:

<AccordionGroup>
  <Accordion title="Vector Search" icon="vector-square">
    Vector search is the fastest method of searching through a database built with your Knowledge Sources. The system takes the user query and looks for the text segments most similar to their vector representations.

    The search returns the preprocessed chunks from the sources most similar and relevant to the user's query.
  </Accordion>

  <Accordion title="Keyword Search" icon="font">
    Keyword Search retrieves relevant results by indexing the entire content and searching for segments containing the words from the user's query.
  </Accordion>

  <Accordion title="Hybrid Search" icon="shuffle">
    Hybrid search uses both Vector and Keyword search, then combines results and returns the most relevant chunks to the model.
  </Accordion>
</AccordionGroup>

**Search Settings**

<AccordionGroup>
  <Accordion title="Chunk limit" icon="list-ol">
    Sets the number of chunks most similar to the user's question to return.
  </Accordion>

  <Accordion title="Threshold" icon="sliders">
    Controls the relevance of results on a scale from 0 to 1. Results scoring below the threshold are excluded from retrieval.

    The closer to 1, the more relevant and narrow the results will be.

    <Warning>
      Setting too high a threshold can yield little to no results.
    </Warning>
  </Accordion>
</AccordionGroup>

### Rerank Model

Reranking invokes a model that analyzes your initial query and the results fetched by the Knowledge Base search. The model scores and ranks the chunks by similarity to the user query, ensuring the most relevant results are returned.

<Frame caption="Choose a rerank model within your Knowledge Base settings by clicking on the model name.">
  <img src="https://mintcdn.com/orqai/E8L3R46ivX7g9-QI/images/docs/ce2abb6-Screenshot_2024-08-16_at_11.40.02.png?fit=max&auto=format&n=E8L3R46ivX7g9-QI&q=85&s=1815794687917b306154c4ae7e74e14f" alt="Choose a rerank model within your Knowledge Base settings by clicking on the model name." width="970" height="274" data-path="images/docs/ce2abb6-Screenshot_2024-08-16_at_11.40.02.png" />
</Frame>

<Warning>
  To use reranking, you must enable at least one Reranking model within the [AI Router](/docs/model-garden/overview).
</Warning>

## Search a Knowledge Base

Once your Knowledge Base is populated, you can query it in several ways.

<Tabs>
  <Tab title="AI Studio" icon="https://mintcdn.com/orqai/My16MDKJXrKALEHC/images/logos/ai-studio-round.svg?fit=max&auto=format&n=My16MDKJXrKALEHC&q=85&s=ac04dd509320d58ab9701cb6d6137733" width="100" height="100" data-path="images/logos/ai-studio-round.svg">
    <AccordionGroup>
      <Accordion title="Test via the Studio" icon="flask">
        Test your Knowledge Base search directly in the AI Studio using the built-in search panel.

        <Steps>
          <Step title="Open Knowledge Settings">
            Navigate to your Knowledge Base and click **Knowledge Settings**.
          </Step>

          <Step title="Enter your search query">
            Type your query in the **Search query** field in the right panel.
          </Step>

          <Step title="View results">
            Results appear below showing:

            * Document name (e.g., "Logistics FAQ.docx")
            * Relevance score for each chunk (e.g., 0.49, 0.48)
            * Chunk content preview
          </Step>
        </Steps>

        <Frame caption="See all results and chunks at a glance">
          <img src="https://mintcdn.com/orqai/XAjVUaP8j8yU-Men/images/kb-search-studio.png?fit=max&auto=format&n=XAjVUaP8j8yU-Men&q=85&s=e47393863675d5f582853582d4224707" alt="See all results and chunks at a glance" width="984" height="1148" data-path="images/kb-search-studio.png" />
        </Frame>

        <Tip>
          Experiment with different search modes and threshold values to find the optimal configuration for your use case. Lower thresholds return more results but may include less relevant chunks.
        </Tip>
      </Accordion>

      <Accordion title="Integrate to a Deployment" icon="rocket">
        Attach a Knowledge Base to a [Deployment](/docs/deployments/overview) to automatically retrieve relevant chunks on every call.

        1. Open the Deployment's configuration and go to **Knowledge Bases**.
        2. Select <Icon icon="circle-plus" /> **Knowledge Base** and choose your Knowledge Base.
        3. Set the query type:
           * **Last User Message**: the user's latest message is used as the search query automatically.
           * **Query**: use a predefined query. You can make it dynamic with an input variable such as `{{query}}`.
        4. Reference the retrieved chunks in your prompt with the `{{knowledge_base_key}}` syntax. If not explicitly referenced, the chunks are appended to the end of the system message.

        <Info>
          To learn more, see [Using a Knowledge Base in a Deployment](/docs/deployments/creating#knowledge-base).
        </Info>
      </Accordion>

      <Accordion title="Integrate to an Agent" icon="robot">
        Add a Knowledge Base as context to an [Agent](/docs/agents/build). Unlike Deployments, the Agent only queries the Knowledge Base when it determines it is necessary, using the `query_knowledge_base` tool automatically.

        1. In the Agent configuration, go to the **Context** section and click **Add context**.
        2. Select your Knowledge Base.
        3. In the Agent's **Instructions**, explicitly tell it to use the Knowledge Base. For example:

        > "First use `retrieve_knowledge_bases` to see what knowledge sources are available, then use `query_knowledge_base` to find relevant information before answering."

        <Tip>
          The Knowledge Base description must be explicit so the Agent can identify the right source to query.
        </Tip>

        <Info>
          To learn more, see [Knowledge Bases with Agents](/docs/agents/build#connect-knowledge-bases).
        </Info>
      </Accordion>

      <Accordion title="Use in Prompts" icon="text">
        To add a Knowledge Base in a [Prompt](/docs/prompts/overview), open the **Knowledge Base** tab in the Configuration screen and select **Add a Knowledge Base**.

        <Frame caption="Select which Knowledge Base to include by clicking on the key. Press Save when done.">
          <img src="https://mintcdn.com/orqai/EqUGDI2og-dnTmDI/images/docs/5c84241-iScreen_Shoter_-_Google_Chrome_-_240815131408.jpg?fit=max&auto=format&n=EqUGDI2og-dnTmDI&q=85&s=d5e51f45c2081f91eb5c09bf632b60be" alt="Select which Knowledge Base to include by clicking on the key. Press Save when done." width="1266" height="333" data-path="images/docs/5c84241-iScreen_Shoter_-_Google_Chrome_-_240815131408.jpg" />
        </Frame>

        Choose whether the Knowledge Base type is **Last User Message** or **Query**. This defines how the Knowledge Base will be queried.

        Use the `{{key}}` syntax in your prompt, where `key` is the key of your Knowledge Base.

        <Frame caption="Your Knowledge Base is correctly referenced when its key appears in blue.">
          <img src="https://mintcdn.com/orqai/8ublVIDMeb653NWy/images/docs/19b1937-iScreen_Shoter_-_Google_Chrome_-_240815131622.jpg?fit=max&auto=format&n=8ublVIDMeb653NWy&q=85&s=277c68243550e991dd1676b90646d22c" alt="Your Knowledge Base is correctly referenced when its key appears in blue." width="1226" height="186" data-path="images/docs/19b1937-iScreen_Shoter_-_Google_Chrome_-_240815131622.jpg" />
        </Frame>

        **Last User Message**: the user message is used as a query to retrieve the relevant chunks.

        <Frame caption="An example of using a Knowledge Base in Orq.ai">
          <img src="https://mintcdn.com/orqai/8ublVIDMeb653NWy/images/docs/0f3466a-playgroundrag.jpg?fit=max&auto=format&n=8ublVIDMeb653NWy&q=85&s=b253b5d4460cb1f0ec28b20b4b9b6bfc" alt="Playground with the apple knowledge base attached, showing a user question about Apple green bonds and an assistant response citing retrieved context." width="2646" height="1152" data-path="images/docs/0f3466a-playgroundrag.jpg" />
        </Frame>

        **Query**: your predefined query is used to retrieve the relevant chunks.

        Within a [Deployment](/docs/deployments/overview) context, make the query dynamic by using an input variable in the query field.

        <Frame caption="Use the input variable {{query}} reachable through the invoke call as an input, letting you dynamically define the Knowledge Base query at runtime.">
          <img src="https://mintcdn.com/orqai/EqUGDI2og-dnTmDI/images/docs/855fa5b52c7b6e5160814822b62a30ba678df2488e87a6ffbe83cc441bde10be-iScreen_Shoter_-_Google_Chrome_-_241024154104.png?fit=max&auto=format&n=EqUGDI2og-dnTmDI&q=85&s=6301bb842349c76c87a7fcd39940ef99" alt="Use the input variable {{query}} reachable through the invoke call as an input, letting you dynamically define the Knowledge Base query at runtime." width="2787" height="1481" data-path="images/docs/855fa5b52c7b6e5160814822b62a30ba678df2488e87a6ffbe83cc441bde10be-iScreen_Shoter_-_Google_Chrome_-_241024154104.png" />
        </Frame>
      </Accordion>
    </AccordionGroup>
  </Tab>

  <Tab title="API & SDK" icon="code">
    Query a Knowledge Base directly using the [Search Knowledge Base API](/reference/knowledge-bases/search-knowledge-base).

    **Basic Search**

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --location 'https://api.orq.ai/v2/knowledge/KNOWLEDGE_BASE_ID/search' \
      --header 'Content-Type: application/json' \
      --header 'Authorization: Bearer $ORQ_API_KEY' \
      --data '{
          "query": "What are the benefits of machine learning?"
      }'
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      from orq_ai_sdk import Orq
      import os

      client = Orq(api_key=os.getenv("ORQ_API_KEY"))

      results = client.knowledge.search(
          knowledge_id="KNOWLEDGE_BASE_ID",
          query="What are the benefits of machine learning?"
      )
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      import { Orq } from '@orq-ai/node';

      const orq = new Orq({
        apiKey: process.env.ORQ_API_KEY,
      });

      const results = await orq.knowledge.search({
        knowledgeId: 'KNOWLEDGE_BASE_ID',
        query: 'What are the benefits of machine learning?'
      });
      ```
    </CodeGroup>

    **Filter by Metadata**

    Pass a `filter_by` object to restrict results to chunks whose metadata matches specified conditions.

    **Supported filter operators** (MongoDB-inspired, no `$` prefix):

    | Filter | Description              | Example                              |
    | ------ | ------------------------ | ------------------------------------ |
    | `eq`   | Equal to                 | `{"page_id": {"eq": "page_x1i2j3"}}` |
    | `ne`   | Not equal to             | `{"page_id": {"ne": "page_x1i2j3"}}` |
    | `gt`   | Greater than             | `{"edition": {"gt": 2019}}`          |
    | `gte`  | Greater than or equal to | `{"edition": {"gte": 2020}}`         |
    | `lt`   | Less than                | `{"edition": {"lt": 2022}}`          |
    | `lte`  | Less than or equal to    | `{"edition": {"lte": 2020}}`         |
    | `in`   | In array                 | `{"page_id": {"in": ["a", "b"]}}`    |
    | `nin`  | Not in array             | `{"page_id": {"nin": ["a", "b"]}}`   |
    | `and`  | Logical AND              | `{"and": [{...}, {...}]}`            |
    | `or`   | Logical OR               | `{"or": [{...}, {...}]}`             |

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --location 'https://api.orq.ai/v2/knowledge/<knowledge_id>/search' \
      --header 'Content-Type: application/json' \
      --header 'Authorization: Bearer $ORQ_API_KEY' \
      --data '{
          "query": "What are the contract renewal terms?",
          "filter_by": {
              "client_id": { "eq": "acme_corp" },
              "source": { "eq": "contracts" }
          },
          "search_options": {
              "include_metadata": true,
              "include_scores": true
          }
      }'
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      from orq_ai_sdk import Orq
      import os

      client = Orq(api_key=os.getenv("ORQ_API_KEY"))

      client.knowledge.search(
          knowledge_id="<knowledge_id>",
          query="What are the contract renewal terms?",
          filter_by={
              "client_id": {"eq": "acme_corp"},
              "source": {"eq": "contracts"},
          },
          search_options={
              "include_metadata": True,
              "include_scores": True,
          },
      )
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      import { Orq } from '@orq-ai/node';

      const orq = new Orq({
        apiKey: process.env['ORQ_API_KEY'] ?? '',
      });

      orq.knowledge.search({
        knowledgeId: '<knowledge_id>',
        query: 'What are the contract renewal terms?',
        filterBy: {
          client_id: { eq: 'acme_corp' },
          source: { eq: 'contracts' },
        },
        searchOptions: {
          includeMetadata: true,
          includeScores: true,
        },
      });
      ```
    </CodeGroup>

    <Callout icon="hat-chef" color="#7ecece">
      See knowledge base search used end-to-end in a real application. Read our cookbooks [Multilingual FAQ Bot](/docs/tutorials/multilingual-faq-bot) and [Third-Party Vector DBs](/docs/tutorials/using-thirdparty-vectordbs-with-orq).
    </Callout>
  </Tab>

  <Tab title="MCP" icon="https://mintcdn.com/orqai/i7ZhKI7LFRfXU7ox/images/logos/mcp.svg?fit=max&auto=format&n=i7ZhKI7LFRfXU7ox&q=85&s=cef7916eb5fe1f6bb97541398d3f7639" width="16" height="16" data-path="images/logos/mcp.svg">
    Use the [Orq MCP server](/docs/integrations/code-assistants/mcp) to find and manage knowledge bases from an AI code assistant.

    **Find an existing knowledge base:**

    ```prompt wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
    Search for knowledge bases in my workspace
    ```

    The assistant uses `search_entities` with `type: "knowledge"` to locate knowledge bases by name or key.

    ***

    **Delete a knowledge base:**

    ```prompt wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
    Delete the knowledge base with ID "old-docs"
    ```

    The assistant uses `delete_entity` with `type: "knowledge"` and the knowledge base ID.
  </Tab>
</Tabs>

<Callout icon="hat-chef" color="#7ecece">
  See knowledge base retrieval in a complete application. Read our cookbooks [Multilingual FAQ Bot](/docs/tutorials/multilingual-faq-bot) and [Customer Support Chat](/docs/tutorials/buildingcustomersupportchatwithaigateway).
</Callout>

### Retrieval Traces and Logs

When using a Knowledge Base within [Playground](/docs/playground/overview), [Experiment](/docs/experiments/overview), [Deployment](/docs/deployments/overview), or [Agent](/docs/agents/build), traces are generated containing details of how Knowledge Bases were accessed.

<Tabs>
  <Tab title="Traces">
    To find Traces, go to the [Traces](/docs/observability/traces) tab in the **AI Studio**.

    <Frame caption="Traces show the full breakdown of queries made to the knowledge base, including results and scores">
      <img src="https://mintcdn.com/orqai/rMTLh8EBv2VU3F9e/images/knowledge-base-query-trace.png?fit=max&auto=format&n=rMTLh8EBv2VU3F9e&q=85&s=20df26e93aadda10d2156e10fb94044a" alt="Traces show the full breakdown of queries made to the knowledge base, including results and scores" width="1547" height="1220" data-path="images/knowledge-base-query-trace.png" />
    </Frame>

    Retrieval Spans show the following:

    * **Query**: the query used to retrieve relevant chunks.
    * **Documents**: the retrieved chunks, ordered by relevance score.
  </Tab>

  <Tab title="Logs">
    To find logs, go to the **Logs** tab within the module you're using, then select a log entry to open the detail panel.

    <img src="https://mintcdn.com/orqai/E8L3R46ivX7g9-QI/images/docs/9a5ffdcd38fc119c596047b7ea60f6794810a1662290d2d8833174595dc6c396-image.png?fit=max&auto=format&n=E8L3R46ivX7g9-QI&q=85&s=9315b130de675186133fb1e0228959aa" alt="Traces show the full breakdown of queries made to the knowledge base, including results and scores" width="2281" height="1498" data-path="images/docs/9a5ffdcd38fc119c596047b7ea60f6794810a1662290d2d8833174595dc6c396-image.png" />

    The right side of the screen shows the **Retrievals** section, which details the Knowledge Base used and how it was queried.

    * **Query**: the query used to retrieve relevant chunks.
    * **Documents**: the retrieved chunks, ordered by relevance score.

    **User Message Augmentation**

    On the left side of the panel, you can see how the Knowledge Base variable is modified with retrieval results highlighted in blue. These blue parts are the retrieval results injected into the user message, which the model uses to respond to the user query.

    <Info>
      Using the highlighted text, you can verify that the query is correct and that the expected chunks are loaded into the message.
    </Info>
  </Tab>
</Tabs>

***

## External Knowledge Bases

To connect to an external Knowledge Base, click the `+` button on the desired [Project](/docs/projects/overview) and select **Knowledge Base > External**.

<Frame caption="Choose External when connecting your Knowledge Base">
  <img src="https://mintcdn.com/orqai/b6ozrSlyXhbX5ZBF/images/external-knowledge-base-connect-2026.png?fit=max&auto=format&n=b6ozrSlyXhbX5ZBF&q=85&s=fe575af4dedbf7a18f28cbccf9d3a6c0" alt="Choose External when connecting your Knowledge Base" width="594" height="196" data-path="images/external-knowledge-base-connect-2026.png" />
</Frame>

The following modal opens to configure the external knowledge base.

<Frame caption="Configuration Modal">
  <img src="https://mintcdn.com/orqai/214zKCMvFji_srtp/images/connect-external-kb.png?fit=max&auto=format&n=214zKCMvFji_srtp&q=85&s=5ed5c55a1ffc96cd27c65f9fed1308c5" alt="Connect External Kb" title="Connect External Kb" className="mx-auto" style={{ width:"67%" }} width="615" height="685" data-path="images/connect-external-kb.png" />
</Frame>

| Field           | Description                                                                         | Example                          |
| --------------- | ----------------------------------------------------------------------------------- | -------------------------------- |
| **Key**         | Unique identifier, alphanumeric with hyphens/underscores                            | `external_kb`                    |
| **Description** | Description of the knowledge base                                                   | `External Knowledge Base`        |
| **Name**        | Display name                                                                        | `External Knowledge Base Name`   |
| **API URL**     | URL to search the knowledge base, must be HTTPS                                     | `https://api.example.org/search` |
| **API Key**     | Authentication API key. **Orq.ai** will use Bearer Authentication to call your API. | `<API_KEY>`                      |

<Info>
  orq.ai includes the API Key in the `Authorization: Bearer <API_KEY>` header when calling your endpoint.
</Info>

<Info>
  API keys are encrypted using workspace-specific keys (AES-256-GCM).
</Info>

Select **Connect** to finalize.

### API Payloads

Example payloads for the request and response expected from your external API:

<Accordion title="Request Payload" icon="arrow-up-to-dotted-line" iconType="regular">
  ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
  {
    "query": "<string>",
    "top_k": 50,
    "threshold": 0.5,
    "filter_by": {},
    "search_options": {
      "include_vectors": true,
      "include_metadata": true,
      "include_scores": true
    },
    "rerank_config": {
      "model": "cohere/rerank-multilingual-v3.0",
      "threshold": 0,
      "top_k": 10
    }
  }
  ```
</Accordion>

<Accordion title="Response Payload" icon="arrow-down-to-dotted-line">
  ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
  {
    "matches": [
      {
        "id": "<string>",
        "text": "<string>",
        "vector": [123],
        "metadata": {},
        "scores": {
          "rerank_score": 123,
          "search_score": 123
        }
      }
    ]
  }
  ```
</Accordion>

<Info>
  The API must respond like a standard Knowledge Base search. See our [Search API](/reference/knowledge-bases/search-knowledge-base) for the expected payload format.
</Info>

### Example Implementations

<Accordion title="Python Implementation" description="An Example Python Server for External Knowledge Base" icon="python">
  <Steps>
    <Step title="Get the Code" icon="github">
      Clone the [Python example Server](https://github.com/orq-ai/orq-cookbooks/tree/main/knowledge-bases/external-knowledge-bases/external-knowledge-bases-python)
    </Step>

    <Step title="Install Dependencies" icon="terminal">
      ```
      pip install -r requirements.txt
      ```
    </Step>

    <Step title="Run the Server" icon="rocket">
      ```
      uvicorn main:app --reload
      ```
    </Step>

    <Step title="Test the API" icon="server">
      The API is running at `http://localhost:8000`

      Dynamic Documentation is available at `http://localhost:8000/docs`
    </Step>
  </Steps>
</Accordion>

<Accordion title="Node.js Implementation" description="An Example Node Server for External Knowledge Base" icon="node">
  <Steps>
    <Step title="Get the Code" icon="github">
      Clone the [Node example Server](https://github.com/orq-ai/orq-cookbooks/tree/main/knowledge-bases/external-knowledge-bases/external-knowledge-bases-node)
    </Step>

    <Step title="Install Dependencies" icon="terminal">
      ```
      npm install
      ```
    </Step>

    <Step title="Run the Server" icon="rocket">
      ```
      npm run dev
      ```
    </Step>

    <Step title="Test the API" icon="server">
      The API is running at `http://localhost:8000`

      Dynamic Documentation is available at `http://localhost:8000/doc`
    </Step>
  </Steps>
</Accordion>

### Integrate Vector Database Providers

**Orq.ai** supports providers like **Weaviate** and **Pinecone**, as both platforms expose REST APIs that conform to the expected payload format.

<Expandable title="Weaviate">
  **Configuration in Orq.ai:**

  * **API URL**: `https://your-cluster.weaviate.cloud/v1/graphql`
  * **API Key**: Your Weaviate API key
</Expandable>

<Expandable title="Pinecone">
  **Configuration in Orq.ai:**

  * **API URL**: `https://$INDEX_HOST/records/namespaces/$NAMESPACE/search`
  * **API Key**: Your Pinecone API key
</Expandable>

### Troubleshoot Common Errors

| Scenario              | Error Message                                               |
| --------------------- | ----------------------------------------------------------- |
| HTTP instead of HTTPS | "External knowledge base URL must use HTTPS protocol"       |
| Local/private IP      | "External knowledge base URL cannot point to local network" |
| API unreachable       | "Failed to verify external knowledge base connectivity"     |
| API timeout (>50s)    | "External API request timed out"                            |

**Cannot connect to external API**

1. Verify your API endpoint is publicly accessible via HTTPS.
2. Check your API logs for incoming requests from orq.ai IP addresses.
3. Verify your firewall/security groups allow inbound HTTPS traffic.

**API key authentication failing**

1. Verify the API key is correct and has not expired.
2. Check that your API expects Bearer authentication in the `Authorization` header.
3. Confirm your API key has the necessary permissions to perform searches.

**No results returned or poor quality results**

1. Verify your API returns the expected response format (see Response Payload above).
2. Check that `scores.search_score` values are between 0 and 1.
3. Test with different `threshold` values (lower threshold = more results).
4. If using reranking, ensure both `search_score` and `rerank_score` are provided.
5. Verify your external vector database has sufficient indexed documents.

**Slow response times**

1. Monitor your external API response times.
2. Consider implementing caching for frequently searched queries.
3. Optimize your vector database indexes.
4. Check if your external API is rate limiting requests.

### Configure your External Knowledge Base

<Info>
  Datasource configuration is not accessible within External Knowledge Bases, as data is hosted outside of Orq.ai.
</Info>

The available configurations are:

* [Agentic RAG](#agentic-rag)
* Search retrieval parameters: [Chunk Limit, Search Threshold](#search-modes)
* [Rerank Model](#rerank-model)

<Tip>
  For detailed configuration options, see [Embedding Models](#embedding-models), [Agentic RAG](#agentic-rag), [Search Modes](#search-modes), and [Rerank Model](#rerank-model) above. All settings apply to both internal and external Knowledge Bases.
</Tip>

<Check>
  **Your External Knowledge Base is connected:**

  * Use it just like any other Knowledge Base. See [Search a Knowledge Base](#search-a-knowledge-base).
  * Your knowledge base can also be used with [Agents](/docs/agents/build). See [Connect Knowledge Bases](/docs/agents/build#connect-knowledge-bases).
  * Your API is called at runtime when the model needs to perform a search.
</Check>

***

## Memory Stores

**Memory Stores** provide persistent storage for agent memories, allowing agents to retain and retrieve information across conversations and sessions. Unlike Knowledge Bases, Memory Stores are entity-scoped: each Memory within a store is tied to a specific entity (a user, session, or any object you define), enabling personalized, per-entity recall.

Only **long-term memory** is currently supported: stored information persists indefinitely with no automatic expiration.

To use a Memory Store with an Agent, see [Connect Memory Stores](/docs/agents/build#connect-memory-stores).

### Architecture

```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}}
graph TD
    A[Memory Stores] --> B[Memory 1]
    A --> C[Memory 2]

    B --> E[Document 1.1]
    B --> F[Document 1.2]
    B --> G[Document 1.3]

    C --> H[Document 2.1]
    C --> I[Document 2.2]
    C --> J[Document 2.3]

    classDef storeClass fill:#0F172A,stroke:#3B82F6,stroke-width:3px,color:#FFFFFF
    classDef memoryClass fill:#1E293B,stroke:#8B5CF6,stroke-width:2px,color:#FFFFFF
    classDef documentClass fill:#334155,stroke:#10B981,stroke-width:2px,color:#FFFFFF

    class A storeClass
    class B,C memoryClass
    class E,F,G,H,I,J documentClass
```

| Concept             | Description                                                                  |
| ------------------- | ---------------------------------------------------------------------------- |
| **Memory Store**    | Top-level container organizing all memories for a use case                   |
| **Memory**          | An entity within the store (e.g., a specific user, customer, or session)     |
| **Memory Document** | The actual content item stored within a Memory, embedded for semantic search |

### Create a Memory Store

<Tabs>
  <Tab title="AI Studio" icon="https://mintcdn.com/orqai/My16MDKJXrKALEHC/images/logos/ai-studio-round.svg?fit=max&auto=format&n=My16MDKJXrKALEHC&q=85&s=ac04dd509320d58ab9701cb6d6137733" width="100" height="100" data-path="images/logos/ai-studio-round.svg">
    Head to a Project, use the <Icon icon="plus-large" /> button, and select **Knowledge > Memory Store**.

    <Frame caption="Select Knowledge > Memory Store.">
      <img src="https://mintcdn.com/orqai/YkiLqBFAkQ-me6zI/images/creating-memory-stores.png?fit=max&auto=format&n=YkiLqBFAkQ-me6zI&q=85&s=9d46109f75e6023d4ce7a4aa1c6a5567" alt="Creating Memory Stores" width="598" height="453" data-path="images/creating-memory-stores.png" />
    </Frame>

    The following modal opens:

    <Frame caption="Enter the Memory Store information.">
      <img src="https://mintcdn.com/orqai/5o4pjgq0txuAlCto/images/memory-store-create.png?fit=max&auto=format&n=5o4pjgq0txuAlCto&q=85&s=a8c891a69bde4002de85d1d5aabf96c4" alt="Memory Store Create" width="619" height="576" data-path="images/memory-store-create.png" />
    </Frame>

    <Warning>
      Ensure the description is thorough, as Agents use it to identify the correct Memory Store:

      * **Good example**: "Customer communication preferences, contact times, and support tier information for personalized outreach"
      * **Bad example**: "Customer data"

      <Expandable title="Example Agent instruction">
        When a customer shares their communication preferences or contact information:

        1. Extract key details (preferred contact method, time windows, support tier)
        2. Store in the "customer\_preferences" Memory Store
        3. Use clear, descriptive language
      </Expandable>
    </Warning>
  </Tab>

  <Tab title="API & SDK" icon="code">
    Use the [Create Memory Store API](/reference/memory-stores/create-memory-store).

    Required inputs:

    * `key`: unique identifier for the store (immutable after creation)
    * `path`: the Project and folder (e.g., `default`)
    * `embedding_config.model`: embedding model for semantic search (e.g., `cohere/embed-v4.0`)

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request POST \
           --url https://api.orq.ai/v2/memory-stores \
           --header 'accept: application/json' \
           --header 'authorization: Bearer <ORQ_API_KEY>' \
           --header 'content-type: application/json' \
           --data '
      {
        "key": "customer_information",
        "description": "Store for customer interaction history and preferences",
        "path": "default",
        "embedding_config": {
          "model": "cohere/embed-v4.0"
        }
      }'
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      from orq_ai_sdk import Orq
      import os

      client = Orq(api_key=os.environ["ORQ_API_KEY"])

      store = client.memory_stores.create(request={
          "key": "customer_information",
          "description": "Store for customer interaction history and preferences",
          "path": "default",
          "embedding_config": {
              "model": "cohere/embed-v4.0"
          }
      })
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      import { Orq } from '@orq-ai/node';

      const client = new Orq({
        apiKey: process.env.ORQ_API_KEY,
      });

      await client.memoryStores.create({
        key: 'customer_information',
        description: 'Store for customer interaction history and preferences',
        path: 'default',
        embeddingConfig: {
          model: 'cohere/embed-v4.0',
        },
      });
      ```
    </CodeGroup>

    <Info>
      The `key` is immutable and must be unique within your workspace. It cannot be changed after creation.
    </Info>
  </Tab>
</Tabs>

### Manage Memories and Documents

A **Memory** represents a specific entity within a Memory Store, identified by an `entity_id`. Each Memory holds **Documents**: the actual text content embedded for semantic search.

<Tabs>
  <Tab title="AI Studio" icon="https://mintcdn.com/orqai/My16MDKJXrKALEHC/images/logos/ai-studio-round.svg?fit=max&auto=format&n=My16MDKJXrKALEHC&q=85&s=ac04dd509320d58ab9701cb6d6137733" width="100" height="100" data-path="images/logos/ai-studio-round.svg">
    **Create an Entity**

    Once a Memory Store is created, select **Add Entity**, enter an ID for the entity, and press **Save**.

    <Frame caption="Choose a clear identifier to find entities later.">
      <img src="https://mintcdn.com/orqai/5o4pjgq0txuAlCto/images/memory-add-entity-studio.png?fit=max&auto=format&n=5o4pjgq0txuAlCto&q=85&s=27f4e3d5a885a07dfaa6ee86d046c81a" alt="Memory Add Entity Studio" width="657" height="279" data-path="images/memory-add-entity-studio.png" />
    </Frame>

    **View Memories**

    Select an entity to see all Memory Documents stored for it. Each document shows the date it was recorded. Use date filters to narrow results.

    <Frame caption="Use the date filters to find memories in an entity.">
      <img src="https://mintcdn.com/orqai/5o4pjgq0txuAlCto/images/memory-store-date-filter.png?fit=max&auto=format&n=5o4pjgq0txuAlCto&q=85&s=527e1fd9dc512c6b08952c3724cee361" alt="Memory Store Date Filter" width="691" height="393" data-path="images/memory-store-date-filter.png" />
    </Frame>

    **Add a Memory Document**

    Use **Add Memory** to manually add a Memory Document to an entity. Fill in the content and press **Add Memory**.

    <Info>
      Memories are best managed dynamically through the API. See the API & SDK tab for programmatic access.
    </Info>
  </Tab>

  <Tab title="API & SDK" icon="code">
    **Create a Memory (entity)**

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request POST \
           --url https://api.orq.ai/v2/memory-stores/customer_information/memories \
           --header 'accept: application/json' \
           --header 'authorization: Bearer <ORQ_API_KEY>' \
           --header 'content-type: application/json' \
           --data '
      {
        "entity_id": "customer_456",
        "metadata": {
          "type": "customer",
          "segment": "premium",
          "region": "north_america",
          "status": "active"
        }
      }'
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      memory = client.memory_stores.create_memory(
          memory_store_key="customer_information",
          entity_id="customer_456",
          metadata={
              "type": "customer",
              "segment": "premium",
              "region": "north_america",
              "status": "active"
          }
      )

      print(f"Created memory with ID: {memory._id}")
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      const memory = await client.memoryStores.createMemory({
        memoryStoreKey: 'customer_information',
        requestBody: {
          entityId: 'customer_456',
          metadata: {
            type: 'customer',
            segment: 'premium',
            region: 'north_america',
            status: 'active',
          },
        },
      });

      console.log(`Created memory with ID: ${memory._id}`);
      ```
    </CodeGroup>

    **Add a Memory Document**

    Documents hold the text content that agents can retrieve. Each document is embedded automatically when created.

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request POST \
           --url https://api.orq.ai/v2/memory-stores/customer_information/memories/<memory_entity_id>/documents \
           --header 'accept: application/json' \
           --header 'authorization: Bearer <ORQ_API_KEY>' \
           --header 'content-type: application/json' \
           --data '
      {
        "text": "Customer prefers email communication. Best contact window: 2-4 PM EST. Premium support subscriber."
      }'
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      document = client.memory_stores.create_document(
          memory_store_key="customer_information",
          memory_entity_id=memory._id,
          text="Customer prefers email communication. Best contact window: 2-4 PM EST. Premium support subscriber."
      )

      print(f"Created document with ID: {document._id}")
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      const document = await client.memoryStores.createDocument({
        memoryStoreKey: 'customer_information',
        memoryEntityId: memory._id,
        requestBody: {
          text: 'Customer prefers email communication. Best contact window: 2-4 PM EST. Premium support subscriber.',
        },
      });

      console.log(`Created document with ID: ${document._id}`);
      ```
    </CodeGroup>

    **Update a Memory Document**

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request PATCH \
           --url https://api.orq.ai/v2/memory-stores/customer_information/memories/<memory_entity_id>/documents/<document_id> \
           --header 'accept: application/json' \
           --header 'authorization: Bearer <ORQ_API_KEY>' \
           --header 'content-type: application/json' \
           --data '
      {
        "text": "Customer strongly prefers email. Contact window: 2-4 PM EST weekdays. Premium support subscriber since Jan 2024."
      }'
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      client.memory_stores.update_document(
          memory_store_key="customer_information",
          memory_entity_id="<memory_entity_id>",
          document_id="<document_id>",
          text="Customer strongly prefers email. Contact window: 2-4 PM EST weekdays. Premium support subscriber since Jan 2024."
      )
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      await client.memoryStores.updateDocument({
        memoryStoreKey: 'customer_information',
        memoryEntityId: '<memory_entity_id>',
        documentId: '<document_id>',
        requestBody: {
          text: 'Customer strongly prefers email. Contact window: 2-4 PM EST weekdays. Premium support subscriber since Jan 2024.',
        },
      });
      ```
    </CodeGroup>

    **Delete a Memory Document**

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request DELETE \
           --url https://api.orq.ai/v2/memory-stores/customer_information/memories/<memory_entity_id>/documents/<document_id> \
           --header 'accept: application/json' \
           --header 'authorization: Bearer <ORQ_API_KEY>'
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      client.memory_stores.delete_document(
          memory_store_key="customer_information",
          memory_entity_id="<memory_entity_id>",
          document_id="<document_id>"
      )
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      await client.memoryStores.deleteDocument({
        memoryStoreKey: 'customer_information',
        memoryEntityId: '<memory_entity_id>',
        documentId: '<document_id>',
      });
      ```
    </CodeGroup>

    For the full CRUD reference (list, retrieve, update memory stores and memories), see the [Memory Stores API Reference](/reference/memory-stores/list-memory-stores).
  </Tab>
</Tabs>

### Best Practices

**Entity ID strategy**: Use consistent, unique identifiers. Prefix by type (e.g., `user_123`, `session_456`) and keep IDs stable across your system.

**Descriptions**: Write exhaustive Memory Store descriptions. Agents use them to identify the correct store to query.

**Organization**: Create separate stores for different contexts (customers, products, sessions). Use descriptive keys.

**Metadata**: Use tags for filtering and categorization, not for storing large text content. Keep data types consistent per field.

<Callout icon="hat-chef" color="#7ecece">
  See Memory Stores powering real agent applications. Read our cookbooks [Multi-Agent HR System](/docs/tutorials/agents-API) and [Chat History](/docs/tutorials/maintaining-history-with-a-model).
</Callout>
