DeepFellow DOCS

Using Vector Stores

Vector Stores enable you to search for knowledge in files uploaded to DeepFellow. Search results consist of file chunks semantically similar to the query. Such search is a fundamental step in RAG systems (retrieval-augmented generation) that enable LLMs to ground their answers in knowledge from your uploaded files.

During DeepFellow Server Installation you have to configure the necessary components of working with a vector store system:

  • vector database provider - i.e. provider's specific vector database engine implementation (Qdrant, Milvus, Chroma, etc.),
  • embedding model - model for converting text into vectors.

Goal

This tutorial shows how to create a vector store, upload a text file to it, and how to match your query with the relevant file content. It will demonstrate using two examples that DeepFellow's semantic search mechanism can differentiate between two files depending on the asked question.

Create a Vector Store

Let's create a sample vector store. To create a new vector make a POST /v1/vector_stores request:

curl -X 'POST' \
  "https://deepfellow-server-host/v1/vector_stores" \
  -H "Authorization: Bearer DEEPFELLOW-PROJECT-API-KEY" \
  -H 'Content-Type: application/json' \
  -d '{
  "chunking_strategy": {
    "type": "auto",
    "static": {
      "chunk_overlap_tokens": 100,
      "max_chunk_size_tokens": 200
    }
  },
  "name": "my_vector_store"
}'
import requests

response = requests.post(
    "https://deepfellow-server-host/v1/vector_stores",
    json={
        "chunking_strategy": {
            "type": "auto",
            "static": {
                "chunk_overlap_tokens": 100,
                "max_chunk_size_tokens": 200,
            },
        },
        "name": "my_vector_store",
    },
    headers={
        "Content-Type": "application/json",
        "Authorization": "Bearer DEEPFELLOW-PROJECT-API-KEY",
    },
)

print(response.json())
const response = await fetch('https://deepfellow-server-host/v1/vector_stores', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        Authorization: 'Bearer DEEPFELLOW-PROJECT-API-KEY'
    },
    body: JSON.stringify({
        chunking_strategy: {
            type: 'auto',
            static: {
                chunk_overlap_tokens: 100,
                max_chunk_size_tokens: 200
            }
        },
        name: 'my_vector_store'
    })
});

const data = await response.json();
console.log(data);

Response:

{
    "project_id": "68da445c5186deb8bca2bde9",
    "object": "vector_store",
    "name": "my_vector_store",
    "status": "completed",
    "file_counts": {
        "cancelled": 0,
        "completed": 0,
        "failed": 0,
        "in_progress": 0,
        "total": 0
    },
    "expires_after": null,
    "metadata": null,
    "chunking_strategy": {
        "type": "auto",
        "static": {
            "max_chunk_size_tokens": 200,
            "chunk_overlap_tokens": 100
        }
    },
    "id": "68ee6e626fef807dd40b2f80",
    "last_active_at": 1760449091,
    "created_at": 1760449091,
    "expires_at": 4914049091,
    "bytes": 0
}

The id field is the important bit of information used to identify concrete vector store in the next steps:

"id": "68ee6e626fef807dd40b2f80"

During creation, each vector store is associated with the embedding model currently configured in the running DeepFellow Server upon its startup. So when you put your server down and change embedding model in config, all the vector stores created using previous embedding models become inactive until you change your settings back.

Upload Files

To upload a file use POST /v1/files endpoint.

Access rights

You can upload a file to a file storage using POST /v1/files endpoint. It doesn't automatically add this file to a vector store. To add a previously uploaded file to a vector store, use the following endpoint:

POST /v1/vector_stores/{vector_store_id}/files

Let's assume you have two files containing summary description for two companies.

  • secureo.txt
# Secureo Solutions

Secureo Solutions has established itself as a leading cybersecurity firm
specializing in enterprise-level threat detection and response systems. Founded
in 2018 by former government security analysts, the company offers a
comprehensive suite of services including penetration testing, security audits,
and 24/7 threat monitoring through their proprietary AI-powered platform,
ShieldWatch.
  • edulee.md
# Edulee Learning Platform

Edulee is an innovative online learning platform launched in 2019 that serves
over 2 million users worldwide with more than 15,000 courses in technology,
business, creative arts, and personal development. The platform partners with leading
companies like SoftABC, Searches, and ProDocs to ensure current content, while
offering flexible pricing tiers including a free option to make quality
education accessible to all.

Let's upload these files. For the first one:

curl -X 'POST' \
  "https://deepfellow-server-host/v1/files" \
  -H "Authorization: Bearer DEEPFELLOW-PROJECT-API-KEY" \
  -H 'Content-Type: multipart/form-data' \
  -F 'file=@secureo.txt;type=text/plain' \
  -F 'purpose=assistants'
import requests

url = "https://deepfellow-server-host/v1/files"
headers = {
    "Authorization": "Bearer DEEPFELLOW-PROJECT-API-KEY"
}
data = {
    "purpose": "assistants"
}

with open("secureo.txt", "rb") as f:
    files = {
        "file": ("secureo.txt", f, "text/plain")
    }
    response = requests.post(url, headers=headers, files=files, data=data)

print(response.json())
const url = 'https://deepfellow-server-host/v1/files';
const formData = new FormData();
const file = new File(['file content'], 'secureo.txt', { type: 'text/plain' });

formData.append('file', file);
formData.append('purpose', 'assistants');

const response = await fetch(url, {
    method: 'POST',
    headers: {
        Authorization: 'Bearer DEEPFELLOW-PROJECT-API-KEY"
    },
    body: formData
});

const data = await response.json();
console.log(data);

Response:

{
    "id": "68ee6e636fef807dd40b2f81",
    "project_id": "68da445c5186deb8bca2bde9",
    "object": "file",
    "bytes": 411,
    "filename": "secureo.txt",
    "purpose": "assistants",
    "created_at": 1760449091,
    "expires_at": 33296452691
}

The id field will be used for further requests.

Uploading the second file:

curl -X 'POST' \
  "https://deepfellow-server-host/v1/files" \
  -H "Authorization: Bearer DEEPFELLOW-PROJECT-API-KEY" \
  -H 'Content-Type: multipart/form-data' \
  -F 'file=@edulee.md;type=text/plain' \
  -F 'purpose=assistants'
import requests

url = "https://deepfellow-server-host/v1/files"
headers = {
    "Authorization": "Bearer DEEPFELLOW-PROJECT-API-KEY"
}
data = {
    "purpose": "assistants"
}

with open("secureo.txt", "rb") as f:
    files = {
        "file": ("edulee.md", f, "text/plain")
    }
    response = requests.post(url, headers=headers, files=files, data=data)


print(response.json())
const url = 'https://deepfellow-server-host/v1/files';
const formData = new FormData();
const file = new File(['file content'], 'edulee.md', { type: 'text/plain' });

formData.append('file', file);
formData.append('purpose', 'assistants');

const response = await fetch(url, {
    method: 'POST',
    headers: {
        Authorization: 'Bearer DEEPFELLOW-PROJECT-API-KEY"
    },
    body: formData
});

const data = await response.json();
console.log(data);

Response:

{
    "id": "68ee6e636fef807dd40b2f82",
    "project_id": "68da445c5186deb8bca2bde9",
    "object": "file",
    "bytes": 449,
    "filename": "edulee.md",
    "purpose": "assistants",
    "created_at": 1760449091,
    "expires_at": 33296452691
}

The id field will be used for further requests.

You cannot access files from the project you don't have access rights to. Each file can be only accessed within the project whose project API Key was used in the 'Authorization' header.

Add Uploaded File to Vector Store

Now add the uploaded files to the vector store in order to be able to search in them. Note that you don't need to add all the files you've uploaded – you have full control over which files are added to vector store.

For this task use POST /v1/vector_stores/{vector_store_id}/files endpoint.

Add the first file:

curl -X 'POST' \
  "https://deepfellow-server-host/v1/vector_stores/68ee6e626fef807dd40b2f80/files" \
  -H "Authorization: Bearer DEEPFELLOW-PROJECT-API-KEY" \
  -H 'Content-Type: application/json' \
  -d '{ "file_id": "68ee6e636fef807dd40b2f81" }'
import requests

response = requests.post(
    "https://deepfellow-server-host/v1/vector_stores/68ee6e626fef807dd40b2f80/files",
    json={
        "file_id": "68ee6e636fef807dd40b2f81",
    },
    headers={
        "Content-Type": "application/json",
        "Authorization": "Bearer DEEPFELLOW-PROJECT-API-KEY",
    },
)

print(response.json())
const response = await fetch(
    'https://deepfellow-server-host/v1/vector_stores/68ee6e626fef807dd40b2f80/files',
    {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            Authorization: 'Bearer DEEPFELLOW-PROJECT-API-KEY'
        },
        body: JSON.stringify({
            file_id: '68ee6e636fef807dd40b2f81'
        })
    }
);

const data = await response.json();
console.log(data);

Response:

{
    "project_id": "68da445c5186deb8bca2bde9",
    "vector_store_id": "68ee6e626fef807dd40b2f80",
    "object": "vector_store.file",
    "last_error": null,
    "status": "in_progress",
    "usage_bytes": 411,
    "chunking_strategy": {
        "type": "auto",
        "static": {
            "max_chunk_size_tokens": 200,
            "chunk_overlap_tokens": 100
        }
    },
    "attributes": {},
    "id": "68ee6e636fef807dd40b2f81",
    "created_at": 1760449091
}

Add the second file:

curl -X 'POST' \
  "https://deepfellow-server-host/v1/vector_stores/68ee6e626fef807dd40b2f80/files" \
  -H "Authorization: Bearer DEEPFELLOW-PROJECT-API-KEY" \
  -H 'Content-Type: application/json' \
  -d '{ "file_id": "68ee6e636fef807dd40b2f82" }'
import requests

response = requests.post(
    "https://deepfellow-server-host/v1/vector_stores/68ee6e626fef807dd40b2f80/files",
    json={
        "file_id": "68ee6e636fef807dd40b2f82",
    },
    headers={
        "Content-Type": "application/json",
        "Authorization": "Bearer DEEPFELLOW-PROJECT-API-KEY",
    },
)

print(response.json())
const response = await fetch(
    'https://deepfellow-server-host/v1/vector_stores/68ee6e626fef807dd40b2f80/files',
    {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            Authorization: 'Bearer DEEPFELLOW-PROJECT-API-KEY'
        },
        body: JSON.stringify({
            file_id: '68ee6e636fef807dd40b2f82'
        })
    }
);

const data = await response.json();
console.log(data);

Response:

{
    "project_id": "68da445c5186deb8bca2bde9",
    "vector_store_id": "68ee6e626fef807dd40b2f80",
    "object": "vector_store.file",
    "last_error": null,
    "status": "in_progress",
    "usage_bytes": 449,
    "chunking_strategy": {
        "type": "auto",
        "static": {
            "max_chunk_size_tokens": 200,
            "chunk_overlap_tokens": 100
        }
    },
    "attributes": {},
    "id": "68ee6e636fef807dd40b2f82",
    "created_at": 1760449091
}

In the background, each of these files will be chunked into pieces. Then for each piece a vector will be generated to be semantically associated with the given chunk.

You cannot search in files from the project you don't have access rights to. Each file can be only accessed within the project whose project API Key was used in the 'Authorization' header.

Invent a query that can be related to the Edulee file and not to the Secureo. Then ask vector database using this query to show that chunks are matched only with the relevant file.

"query": "I want to learn about computers"

Vector search uses vector similarity measure (like a cosine similarity) to match a query with a relevant text from a vector store.

For this task use POST /v1/vector_stores/{vector_store_id}/search endpoint.

To search vector store for three best results type:

curl -X 'POST' \
  "https://deepfellow-server-host/v1/vector_stores/68ee6e626fef807dd40b2f80/search" \
  -H "Authorization: Bearer DEEPFELLOW-PROJECT-API-KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "I want to learn about computers",
    "max_num_results": 3
  }'
import requests

response = requests.post(
    "https://deepfellow-server-host/v1/vector_stores/68ee6e626fef807dd40b2f80/search",
    json={
        "query": "I want to learn about computers",
        "max_num_results": 3
    },
    headers={
        "Content-Type": "application/json",
        "Authorization": "Bearer DEEPFELLOW-PROJECT-API-KEY",
    },
)

print(response.json())
const response = await fetch(
    'https://deepfellow-server-host/v1/vector_stores/68ee6e626fef807dd40b2f80/search',
    {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            Authorization: 'Bearer DEEPFELLOW-PROJECT-API-KEY'
        },
        body: JSON.stringify({
            query: 'I want to learn about computers',
            max_num_results: 3
        })
    }
);

const data = await response.json();
console.log(data);

Response:

{
    "object": "vector_store.search_results.page",
    "search_query": "I want to learn about computers",
    "data": [
        {
            "file_id": "68ee6e636fef807dd40b2f82",
            "filename": "edulee.md",
            "score": 0.5061247944831848,
            "attributes": {},
            "content": [
                {
                    "text": ", and ProDocs to ensure current content, while\noffering flexible pricing tiers including a free option to make quality\neducation accessible to all. \n",
                    "type": "text",
                    "offset": 0,
                    "metadata": {}
                }
            ]
        },
        {
            "file_id": "68ee6e636fef807dd40b2f82",
            "filename": "edulee.md",
            "score": 0.49376875162124634,
            "attributes": {},
            "content": [
                {
                    "text": "erves\nover 2 million users worldwide with more than 15,000 courses in technology,\nbusiness, creative arts, and personal development. The platform partners with leading\ncompanies like SoftABC, Searches",
                    "type": "text",
                    "offset": 0,
                    "metadata": {}
                }
            ]
        },
        {
            "file_id": "68ee6e636fef807dd40b2f82",
            "filename": "edulee.md",
            "score": 0.48902779817581177,
            "attributes": {},
            "content": [
                {
                    "text": " arts, and personal development. The platform partners with leading\ncompanies like SoftABC, Searches, and ProDocs to ensure current content, while\noffering flexible pricing tiers including a free opti",
                    "type": "text",
                    "offset": 0,
                    "metadata": {}
                }
            ]
        }
    ],
    "has_more": false,
    "next_page": null
}

Vector store returned chunks from the file containing info about education platform. It's expected as your query was related to learning.

Sometimes results are not satisfactory and the query needs refinement. You can adjust your search results using the following request body parameters:

{
    "filters": {
        "key": "string",
        "type": "eq", // different filter types are available
        "value": "string"
    },
    "max_num_results": 10,
    "ranking_options": {
        "score_threshold": 0.4
    }
}

filters can narrow down the scope of vectors to search. max_num_results limits the number of vectors returned. To return vectors which distance is above some threshold set score_threshold field.

Details on these parameters can be found in OpenAI API documentation.

How to Use Search Results

Search results can be used by LLMs to provide additional context in prompt to improve their answer in comparison to answering without context.

Prompt without context:

- Prompt: "What is Edulee?"
- LLM answer: "I don't have any specific information about Edulee."

Prompt with extra context:

- Prompt:"""

 <!-- This part is added programmatically in your app -->

Provided information in the context below, please answer the user prompt.
<context>
<entry>
File: edulee.md

[...] erves\nover 2 million users worldwide with more than 15,000 courses
in technology,\nbusiness, creative arts, and personal development.
The platform partners with leading\ncompanies like SoftABC, Searches [...]

</entry>
<entry>
File: edulee.md

[...] arts, and personal development. The platform partners with leading\ncompanies
like SoftABC, Searches, and ProDocs to ensure current content,
while\noffering flexible pricing tiers including a free opti [...]

</entry>
</context>
<!-- End of added context -->

What is Edulee?
"""

- LLM answer: "Edulee is a learning platform that offers 15,000 courses on various topics."

Final Notes

Vector stores open doors to building knowledge bases in your application. This is a major topic, programmatically based on RAG. Implementing knowledge bases securely is challenging but DeepFellow takes care of security and data safety for you.

We use cookies on our website. We use them to ensure proper functioning of the site and, if you agree, for purposes such as analytics, marketing, and targeting ads.