Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Chroma: простая векторная БД с метаданными
chroma

Chroma: простая векторная БД с метаданными

Работаем с Chroma — самой простой векторной базой данных. Фильтрация по метаданным, персистентность, клиент-серверный режим.

Chroma: простая векторная БД с метаданными

Работаем с Chroma — самой простой векторной базой данных. Фильтрация по метаданным, персистентность, клиент-серверный режим.

#Что вы сделаете в этой теме

За 45 минут вы:

  1. Поймёте, чем Chroma отличается от FAISS
  2. Научитесь создавать коллекции и добавлять документы
  3. Освоите фильтрацию по метаданным
  4. Настроите персистентное хранение
  5. Попробуете клиент-серверный режим

#Что такое Chroma

Chroma — векторная база данных с акцентом на простоту использования.

Преимущества:

  • 🟢 Простой API — начать работу за 5 минут
  • 🟢 Метаданные из коробки — не нужно внешних хранилищ
  • 🟢 Персистентность — сохранение на диск
  • 🟢 Встроенные эмбеддинги — может генерировать сама
  • 🟢 Клиент-сервер — режим для продакшена

Недостатки:

  • 🔴 Медленнее FAISS на больших данных
  • 🔴 Ограниченные возможности фильтрации
  • 🔴 Меньше подходит для высоких нагрузок

Когда использовать:

  • ✅ Прототипы и MVP
  • ✅ Небольшие проекты (<100K векторов)
  • ✅ Когда нужна простота развёртывания
  • ✅ Локальные приложения

#Шаг 1: Установка

pip install chromadb

Проверка:

import chromadb print(chromadb.__version__)

#Шаг 2: Первый запуск (в памяти)

import chromadb # Клиент в памяти (данные исчезнут после завершения) client = chromadb.Client() # Создание коллекции collection = client.create_collection( name="documents", metadata={"description": "Моя первая коллекция"} ) print(f"Коллекция создана: {collection.name}")

#Шаг 3: Добавление документов

#Chroma с автоматическими эмбеддингами

Chroma может сама генерировать эмбеддинги:

# Добавление документов (Chroma сама создаст эмбеддинги) collection.add( documents=[ "Python — язык программирования общего назначения", "Django — веб-фреймворк на Python", "Flask — микрофреймворк для веб-приложений", "FastAPI — современный фреймворк для API" ], ids=["doc1", "doc2", "doc3", "doc4"], metadatas=[ {"category": "programming", "author": "Alice"}, {"category": "web", "author": "Bob"}, {"category": "web", "author": "Charlie"}, {"category": "web", "author": "Alice"} ] ) print(f"Добавлено документов: {collection.count()}")

#Chroma с готовыми эмбеддингами

from sentence_transformers import SentenceTransformer model = SentenceTransformer('all-MiniLM-L6-v2') documents = [ "Python — язык программирования", "Django — веб-фреймворк", "Flask — микрофреймворк" ] # Генерация эмбеддингов embeddings = model.encode(documents).tolist() # Добавление с готовыми эмбеддингами collection.add( embeddings=embeddings, ids=["doc1", "doc2", "doc3"], documents=documents, metadatas=[ {"category": "programming"}, {"category": "web"}, {"category": "web"} ] )

#Шаг 4: Поиск

#Поиск по тексту

# Chroma сама создаст эмбеддинг для запроса results = collection.query( query_texts=["веб-разработка на Python"], n_results=2 ) print(f"Найдено документов: {len(results['documents'][0])}") print(f"Тексты: {results['documents'][0]}") print(f"ID: {results['ids'][0]}") print(f"Сходство: {results['distances'][0]}")

#Поиск по эмбеддингу

# Генерация эмбеддинга запроса query_embedding = model.encode(["веб-разработка"]).tolist() results = collection.query( query_embeddings=[query_embedding], n_results=2 ) print(f"Тексты: {results['documents'][0]}")

#Поиск с метаданными

# Возврат метаданных в результатах results = collection.query( query_texts=["веб-фреймворк"], n_results=2, include=["documents", "metadatas", "distances"] ) for i, doc in enumerate(results['documents'][0]): print(f"\nРезультат {i+1}:") print(f" Текст: {doc}") print(f" Метаданные: {results['metadatas'][0][i]}") print(f" Расстояние: {results['distances'][0][i]:.3f}")

#Шаг 5: Фильтрация по метаданным

#Простые фильтры

# Поиск только в категории "web" results = collection.query( query_texts=["фреймворк"], n_results=2, where={"category": "web"} ) print(f"Результаты в категории 'web': {results['documents'][0]}")

#Сложные фильтры

# Операторы сравнения results = collection.query( query_texts=["фреймворк"], n_results=2, where={ "author": {"$ne": "Bob"} # Не Bob } ) # $ne — не равно # $eq — равно # $gt — больше # $lt — меньше # $gte — больше или равно # $lte — меньше или равно

#Логические операторы

# AND: категория "web" И автор "Alice" results = collection.query( query_texts=["фреймворк"], n_results=2, where={ "$and": [ {"category": "web"}, {"author": "Alice"} ] } ) # OR: категория "web" ИЛИ "api" results = collection.query( query_texts=["фреймворк"], n_results=5, where={ "$or": [ {"category": "web"}, {"category": "api"} ] } )

#Все операторы фильтрации

ОператорОписаниеПример
$eqРавно{"age": {"$eq": 25}}
$neНе равно{"status": {"$ne": "deleted"}}
$gtБольше{"score": {"$gt": 0.7}}
$gteБольше или равно{"rating": {"$gte": 4}}
$ltМеньше{"price": {"$lt": 100}}
$lteМеньше или равно{"count": {"$lte": 10}}
$inВ списке{"category": {"$in": ["web", "api"]}}
$ninНе в списке{"status": {"$nin": ["draft"]}}
$andИ{"$and": [{"a": 1}, {"b": 2}]}
$orИЛИ{"$or": [{"a": 1}, {"b": 2}]}

#Шаг 6: Персистентное хранение

#Сохранение на диск

# Клиент с сохранением на диск client = chromadb.PersistentClient(path="./chroma_data") # Все коллекции сохраняются в папке ./chroma_data collection = client.get_or_create_collection("documents") # Добавление документов collection.add( documents=["документ 1", "документ 2"], ids=["doc1", "doc2"] ) # После завершения данные сохранятся

#Загрузка сохранённых данных

# При следующем запуске client = chromadb.PersistentClient(path="./chroma_data") # Получение существующей коллекции collection = client.get_collection("documents") print(f"Документов в коллекции: {collection.count()}")

#Шаг 7: Клиент-серверный режим

#Запуск сервера

# Запуск сервера Chroma chroma run --path ./chroma_data --port 8000

#Подключение к серверу

# HTTP клиент client = chromadb.HttpClient(host="localhost", port=8000) # Работа как обычно collection = client.get_or_create_collection("documents") collection.add( documents=["документ"], ids=["doc1"] )

#Асинхронный клиент

import asyncio import chromadb async def main(): client = chromadb.AsyncHttpClient(host="localhost", port=8000) collection = await client.get_or_create_collection("documents") await collection.add( documents=["документ"], ids=["doc1"] ) results = await collection.query( query_texts=["запрос"], n_results=2 ) await client.close() return results # Запуск results = asyncio.run(main())

#Шаг 8: Управление коллекциями

#Создание и получение

# Создание collection = client.create_collection("my_collection") # Получение существующей collection = client.get_collection("my_collection") # Получение или создание collection = client.get_or_create_collection("my_collection")

#Список коллекций

collections = client.list_collections() for col in collections: print(f"Коллекция: {col.name}") print(f" Документов: {col.count()}") print(f" Метаданные: {col.metadata}")

#Удаление коллекции

client.delete_collection("my_collection")

#Удаление документов

# Удаление по ID collection.delete(ids=["doc1", "doc2"]) # Удаление по фильтру collection.delete( where={"category": "temp"} )

#Обновление документов

# Обновление метаданных collection.update( ids=["doc1"], metadatas=[{"category": "updated", "author": "New Author"}] ) # Обновление документа collection.update( ids=["doc1"], documents=["Обновлённый текст документа"] )

#Шаг 9: Практический пример — поисковик с метаданными

# chroma_search.py import chromadb from pathlib import Path class ChromaSearch: """Поисковик на Chroma с метаданными.""" def __init__(self, persist_dir: str = None): if persist_dir: self.client = chromadb.PersistentClient(path=persist_dir) else: self.client = chromadb.Client() self.collection = None def create_collection(self, name: str): """Создать коллекцию.""" self.collection = self.client.create_collection(name) return self.collection def get_collection(self, name: str): """Получить коллекцию.""" self.collection = self.client.get_collection(name) return self.collection def add_documents( self, documents: list[str], ids: list[str] = None, metadatas: list[dict] = None ): """Добавить документы.""" if self.collection is None: raise ValueError("Сначала создайте или получите коллекцию") if ids is None: ids = [f"doc{i}" for i in range(len(documents))] self.collection.add( documents=documents, ids=ids, metadatas=metadatas ) def search( self, query: str, k: int = 5, filter: dict = None ) -> list[dict]: """Поиск с фильтрацией.""" results = self.collection.query( query_texts=[query], n_results=k, where=filter, include=["documents", "metadatas", "distances"] ) formatted = [] for i in range(len(results['documents'][0])): formatted.append({ "text": results['documents'][0][i], "metadata": results['metadatas'][0][i], "distance": results['distances'][0][i], "id": results['ids'][0][i] }) return formatted def get_stats(self) -> dict: """Статистика коллекции.""" if self.collection is None: return {"error": "Коллекция не выбрана"} return { "name": self.collection.name, "count": self.collection.count(), "metadata": self.collection.metadata } # Использование if __name__ == "__main__": search = ChromaSearch(persist_dir="./chroma_data") # Создание коллекции search.create_collection("tech_docs") # Добавление документов search.add_documents( documents=[ "Python — язык программирования общего назначения", "Django — веб-фреймворк на Python для быстрой разработки", "Flask — микрофреймворк для создания веб-приложений", "FastAPI — современный фреймворк для создания API", "NumPy — библиотека для научных вычислений" ], ids=["python", "django", "flask", "fastapi", "numpy"], metadatas=[ {"category": "programming", "level": "beginner"}, {"category": "web", "level": "intermediate"}, {"category": "web", "level": "beginner"}, {"category": "web", "level": "intermediate"}, {"category": "data", "level": "advanced"} ] ) # Поиск без фильтра print("Поиск 'веб-фреймворк':") results = search.search("веб-фреймворк", k=3) for r in results: print(f" [{r['distance']:.3f}] {r['text']} ({r['metadata']['category']})") # Поиск с фильтром print("\nПоиск 'фреймворк' только в категории 'web':") results = search.search( "фреймворк", k=3, filter={"category": "web"} ) for r in results: print(f" [{r['distance']:.3f}] {r['text']}") # Статистика print(f"\nСтатистика: {search.get_stats()}")

#Типичные ошибки

#1. Дублирование ID

# ❌ Ошибка: одинаковые ID collection.add( documents=["doc1", "doc2"], ids=["same_id", "same_id"] # Ошибка! ) # ✅ Уникальные ID collection.add( documents=["doc1", "doc2"], ids=["doc1", "doc2"] )

#2. Несоответствие длины списков

# ❌ Ошибка: разная длина collection.add( documents=["doc1", "doc2"], ids=["doc1"], # Только один ID! metadatas=[{"a": 1}, {"b": 2}] ) # ✅ Одинаковая длина collection.add( documents=["doc1", "doc2"], ids=["doc1", "doc2"], metadatas=[{"a": 1}, {"b": 2}] )

#3. Неправильный синтаксис фильтров

# ❌ Неправильно collection.query( query_texts=["запрос"], where={"category" == "web"} # Python-оператор! ) # ✅ Правильно collection.query( query_texts=["запрос"], where={"category": "web"} )

#4. Forget to include метаданные

# ❌ Метаданные не включены в результат results = collection.query( query_texts=["запрос"], n_results=2 ) # results['metadatas'] будет пустым! # ✅ Явно указать include results = collection.query( query_texts=["запрос"], n_results=2, include=["documents", "metadatas", "distances"] )

#Чеклист: вы научились

  • Создавать коллекции в Chroma
  • Добавлять документы с метаданными
  • Выполнять поиск по тексту и эмбеддингам
  • Использовать фильтры по метаданным
  • Настраивать персистентное хранение
  • Работать в клиент-серверном режиме
  • Управлять коллекциями (создание, удаление, обновление)

#Что дальше

Теперь вы умеете работать с Chroma. Следующий шаг — Qdrant:

  • Полноценная векторная БД для продакшена
  • REST API и gRPC
  • Сложные фильтры и асинхронный клиент

#Домашнее задание

  1. Создайте файл my_chroma_search.py с поисковиком на Chroma
  2. Добавьте 50+ документов с метаданными (категория, автор, дата)
  3. Реализуйте поиск с фильтрацией по 2+ полям
  4. Настройте персистентное хранение
  5. Протестируйте с 10+ запросами

Готовы? Открывайте qdrant!

Далее: Qdrant: полноценная векторная БД