После выполнения этой инструкции вы перенесёте данные из Pinecone в Chroma как ручной ETL-процесс: снимете инвентарь по namespace, выгрузите IDs и записи, загрузите их в Chroma и проверите результат до переключения приложения.
Короткий ответ: официального one-click пути Pinecone → Chroma в источниках нет. Рабочий путь на 2026-08-15 — describe_index_stats → list → fetch в Pinecone, затем add или, для повторяемой миграции, upsert в Chroma, после чего проверьте доступность через heartbeat() и выборки через get/query.
Редакционное ограничение: ниже — воспроизводимый шаблон миграции по официальным API, а не фирменный мигратор. Точный mapping между Pinecone namespace и сущностями Chroma нужно принять под ваше приложение заранее.
- Время: 45–120 минут на один индекс без учёта объёма данных.
- Сложность: средний.
- Стоимость: зависит от объёма и выбранного варианта Chroma. В документации Chroma Cloud указаны writes $2.50 за logical GiB, reads $0.0075 за TiB queried и $0.09 за GiB returned, storage $0.33 за GiB в месяц; новым пользователям дают $5 credits. Актуальные тарифы перепроверьте перед запуском.
- Что потребуется: доступ к Pinecone index и его namespace, доступ к Chroma Cloud или self-hosted Chroma server, место для промежуточного экспорта, окно на сверку количества записей и тестовые запросы.
- Актуальность: Pinecone docs: create_index 2026-04, list 2024-04, fetch 2024-10, describe_index_stats 2024-07; Chroma docs и видимый latest release 1.5.9 с build date 2026-05-05T05:55. Проверено по источникам на 2026-08-15.
Практический вердикт: если вы заменяете Pinecone на managed serverless сервис, обычно логично начинать с Chroma Cloud. Если вам нужен полный контроль над окружением, выбирайте self-hosted Chroma server. PersistentClient оставьте для локальной разработки и тестов: документация рекомендует для production server-backed Chroma instance.
Что нужно решить до начала миграции
Главная техническая развилка — не экспорт, а модель размещения и разбиения данных. В Pinecone данные часто разделены по namespace; в документации Pinecone это механизм разделения данных и мультитенантности. В Chroma вам нужно заранее решить, куда именно лягут эти данные: в отдельные коллекции, отдельные базы данных или в одну коллекцию с дополнительным полем в метаданных.
| Вариант Chroma | Когда подходит | Что проверить перед импортом |
|---|---|---|
| Chroma Cloud | Нужна managed/serverless замена Pinecone с hosted API. | Регион, API key, квоты, стоимость и region-specific возможности. База данных остаётся в выбранном регионе. |
| Self-hosted Chroma server + HttpClient | Нужен собственный контур и контроль над развёртыванием. | Сервер нужно эксплуатировать и масштабировать самостоятельно; это не managed service. |
| PersistentClient | Локальная разработка, тестирование и небольшие self-managed сценарии. | Данные живут на локальном диске; документация рекомендует server-backed Chroma instance для production. |
Если миграция запускается ради смены региона или требований к размещению данных, проверьте это до начала экспорта. Для Pinecone serverless cloud/region нельзя изменить после создания индекса; на плане Starter поддерживается только AWS us-east-1, другие регионы доступны на более высоких планах. В Chroma Cloud база данных остаётся в выбранном регионе, а в официальной документации на дату проверки указаны два multi-tenant региона: AWS us-east-1 и GCP europe-west1. Core API доступны в обоих, а Chroma Sync, CLI и Search Agent — только в us-east-1.
Перед первой записью в Chroma отдельно сверьте ограничения. Для Chroma Cloud в документации указаны максимум 4096 embedding dimensions и максимум 5,000,000 records per collection. Если ваш индекс Pinecone крупнее или использует другую размерность, меняйте схему разбиения до загрузки.
Пошаговая миграция Pinecone → Chroma
- Снимите инвентарь Pinecone через
describe_index_stats.Зафиксируйте общее количество векторов, распределение по namespace и размерность индекса. Поле fullness пригодится в основном для pod-based indexes; для serverless оно обычно не главный ориентир. Ожидаемый результат: у вас есть таблица namespace → count и зафиксирована dimension, с которой вы будете сверять Chroma после загрузки.
# Псевдокод по названиям методов из документации stats = pinecone_index.describe_index_stats() # Сохраните: # - namespaces # - vector counts # - dimension # - fullness, если релевантно для вашего типа индекса - Подготовьте целевое окружение Chroma.
Выберите один из трёх вариантов: Chroma Cloud, self-hosted Chroma server с
HttpClientили локальныйPersistentClient. Для production документация рекомендует server-backed Chroma instance, поэтому локальный клиент используйте только для разработки и тестов. Ожидаемый результат: у вас есть либо рабочий Chroma Cloud tenant/database/api key, либо запущенный сервер, к которому подключается клиент.export CHROMA_TENANT=your-tenant export CHROMA_DATABASE=your-database export CHROMA_API_KEY=your-api-keyЕсли вы идёте в Cloud, учитывайте region-specific ограничения заранее. Если выбираете self-hosted, поднимите сервер и проверьте подключение через клиент до старта экспорта.
- Зафиксируйте mapping между Pinecone namespace и сущностями Chroma.
Это решение нужно принять до выгрузки, иначе вы потеряете воспроизводимость. Практически чаще всего используют один из трёх вариантов: один namespace = одна collection; один namespace = одна database; несколько namespace = одна collection с отдельным признаком в metadata. Ожидаемый результат: для каждого namespace известна целевая коллекция или база данных Chroma.
- Если приложение уже использует namespace как изоляцию арендаторов, обычно безопаснее сохранить изоляцию и не смешивать данные в одной коллекции без явного поля в metadata.
- Если вы хотите упростить запросы, зафиксируйте выбранный mapping в отдельном документе миграции, чтобы одинаково строить импорт и постпроверку.
- Выгрузите IDs из Pinecone по каждому namespace через
list.Метод
listвозвращает до 100 IDs за страницу, поэтому экспортируйте namespace постранично и сохраняйте промежуточный список IDs. Не смешивайте namespaces в одном проходе: дальшеfetchработает внутри одного namespace. Ожидаемый результат: для каждого namespace у вас есть полный список IDs, который можно повторно использовать при рестарте миграции.# Псевдокод: обрабатывайте list постранично for namespace in namespaces: for page in pinecone_index.list(namespace=namespace): page_ids = extract_ids(page) save_ids(namespace, page_ids) - Выгрузите записи по экспортированным ID через
fetch.fetchполучает векторы по ID внутри одного namespace и возвращает vector data и/или metadata. Идите батчами по ранее сохранённым IDs и сохраняйте результат в промежуточный формат так, чтобы не потерятьid, embedding, metadata и исходный namespace. Ожидаемый результат: у вас есть воспроизводимый экспорт, который можно загрузить в Chroma без повторного обращения к Pinecone.# Псевдокод: выгружайте записи по ID внутри того же namespace for namespace in namespaces: for ids_batch in saved_id_batches(namespace): records = pinecone_index.fetch(ids=ids_batch, namespace=namespace) save_records(namespace, records) - Создайте целевые коллекции и загрузите данные в Chroma через
upsert.Для одноразовой первичной загрузки подойдёт
add, но помните нюанс: в Chromaaddтребует уникальный string id, а при повторном ID запись игнорируется без ошибки. Если вам нужна безопасная повторная загрузка, используйтеupsert: он обновляет существующие записи и добавляет отсутствующие. Ожидаемый результат: батчи записей загружены в целевые коллекции, а повторный запуск не ломает импорт.# Псевдокод: повторяемая загрузка for target_collection, records_batch in export_batches: target_collection.upsert(records_batch)Перед загрузкой проверьте, что размерность embeddings укладывается в лимит Chroma Cloud 4096, а прогнозируемое число records в коллекции не превышает 5,000,000. Если превышает — разбивайте данные на несколько коллекций или баз данных до старта импорта.
- Проведите контрольную сверку перед переключением приложения.
Сначала проверьте доступность Chroma через
client.heartbeat(). Затем сверяйте количество записей с инвентарём Pinecone, делайте выборки черезgetпо нескольким известным ID и запускайтеqueryна типовых запросах. Ожидаемый результат: сервер отвечает, количество записей сходится с исходным инвентарём, отдельные записи читаются, а поиск возвращает ожидаемо близкие результаты.# Псевдокод проверки client.heartbeat() sample = collection.get(...) neighbors = collection.query(...)
Если приложение продолжает писать в Pinecone во время миграции, зафиксируйте окно заморозки или запланируйте повторную инкрементальную выгрузку до cutover. Это важно, потому что при совпадении ID upsert в Pinecone перезаписывает весь record, и без окна консистентности вы не узнаете, какая версия уехала в Chroma.
Как проверить, что всё работает
- Проверьте доступность сервера.
Вызовите
client.heartbeat(). Если сервер или Cloud endpoint отвечает, можно переходить к выборочной проверке данных. - Сверьте количество записей.
Сравните инвентарь Pinecone по каждому namespace из
describe_index_statsс количеством записей в соответствующей collection или database Chroma по вашему mapping. - Проверьте контрольные ID.
Возьмите несколько известных IDs из каждого namespace и выполните
get. Убедитесь, что запись читается из нужной коллекции и содержит те же данные, которые вы ожидали перенести. - Проверьте типовые поисковые запросы.
Запустите
queryна нескольких реальных запросах из приложения. Для миграции считается хорошим знаком, если результат не только технически возвращается, но и семантически выглядит ожидаемо.
Частые ошибки и исправления
- Ошибка: повторный импорт запущен через
add, и часть записей «пропала». Решение: в Chroma дубликат ID приaddигнорируется без ошибки. Для restartable миграции используйтеupsert. - Ошибка: IDs выгружены из одного namespace, а
fetchвыполняется в другом. Решение: держите экспорт строго по namespace, потому чтоfetchработает внутри одного namespace. - Ошибка: после загрузки выяснилось, что коллекция не проходит по лимитам Chroma Cloud. Решение: до импорта сверьте 4096 embedding dimensions и 5,000,000 records per collection, затем при необходимости разбейте данные по нескольким коллекциям или базам.
- Ошибка: выбран регион Chroma Cloud, где недоступна нужная облачная функция. Решение: перепроверьте таблицу регионов: core API доступны в обоих задокументированных multi-tenant регионах, а Chroma Sync, CLI и Search Agent — только в us-east-1.
- Ошибка:
PersistentClientвыбран как production-замена Pinecone. Решение: оставьтеPersistentClientдля локальной разработки и тестирования, а для production используйте Chroma Cloud или self-hosted server-backed инстанс.
Безопасность и ограничения
- Официального one-click migration Pinecone → Chroma в источниках не найдено. Это ручной ETL, и точный mapping зависит от вашей схемы данных.
- Следите за residency. Pinecone serverless region нельзя изменить после создания индекса, а Chroma Cloud хранит базу в выбранном регионе.
- Для production не полагайтесь на
PersistentClient: документация рекомендует server-backed Chroma instance. - Если ваш поиск завязан на Chroma Cloud Search API, учтите ограничение из migration guide:
query_imagesиquery_urisпока не поддерживаются. - Тарифы и квоты меняются. Перед rollout перепроверьте страницы Chroma Cloud pricing и quotas/limits.
Редакционная оговорка: в этой инструкции нет готового рабочего скрипта с конкретной библиотекой и версиями пакетов, потому что в supplied source pack нет полных сигнатур клиентских методов Pinecone и Chroma. Зато все ключевые операции и текущие ограничения привязаны к официальной документации.
Что делать дальше
- Если вам нужен базовый сетап обеих векторных БД, начните с инструкции Как настроить векторную базу: Pinecone и Chroma.
- Если после замены вы собираете retrieval-слой, переходите к Как развернуть RAG-систему с Chroma (векторная БД).
- Если вы параллельно меняете не только векторную БД, но и LLM-провайдера, посмотрите шаблон миграции Как мигрировать с OpenAI API на Anthropic API.
Вопросы и ответы
Можно ли перенести Pinecone в Chroma одной кнопкой?
По источникам на 2026-08-15 — нет. Официально подтверждённый путь выглядит как ручной ETL: инвентарь Pinecone по namespace, экспорт IDs через list, выгрузка записей через fetch, затем загрузка в Chroma через add или upsert.
Что делать с Pinecone namespace при миграции?
Не переносите их вслепую. Pinecone и Chroma по-разному организуют данные, поэтому сначала зафиксируйте mapping: отдельная collection, отдельная database или единая collection с признаком namespace в metadata.
Что выбрать: Chroma Cloud, self-hosted или PersistentClient?
Для managed serverless замены Pinecone обычно выбирают Chroma Cloud. Если нужен собственный контур — self-hosted server с HttpClient. PersistentClient документация рекомендует для локальной разработки и тестирования, не как основной production-вариант.
Какие лимиты проверить до запуска импорта?
Для Chroma Cloud проверьте как минимум два ограничения из документации: максимум 4096 embedding dimensions и максимум 5,000,000 records per collection. Также перепроверьте region-specific возможности, если вам нужны облачные функции за пределами core API.
Можно ли просто использовать add вместо upsert?
Только если вы уверены, что импорт запускается один раз и в целевой коллекции нет повторных ID. При повторном ID add в Chroma игнорирует запись без ошибки, поэтому для restartable миграции безопаснее upsert.
Источники
- Get index stats – Pinecone Docs
- List vector IDs – Pinecone Docs
- Fetch vectors – Pinecone Docs
- Upsert records – Pinecone Docs
- Create an index – Pinecone Docs
- Chroma Cloud – Chroma Docs
- Pricing – Chroma Docs
- Quotas & Limits – Chroma Docs
- Client – Chroma Docs
- Client-Server Mode – Chroma Docs
- Adding Data to Chroma Collections – Chroma Docs
- Update Data – Chroma Docs
- Query and Get – Chroma Docs
- Manage Collections – Chroma Docs
- Migration Guide – Chroma Docs
- Releases · chroma-core/chroma · GitHub