diff --git a/sample_apps/generative_benchmarking/data/chroma_docs.json b/sample_apps/generative_benchmarking/data/chroma_docs.json deleted file mode 100644 index 7a0dde70005..00000000000 --- a/sample_apps/generative_benchmarking/data/chroma_docs.json +++ /dev/null @@ -1,218 +0,0 @@ -{ - "5ecb1f42-d818-4e7c-b54f-ce87b1264f20": "# Full Text Search\n\nIn order to filter on document contents, you must supply a `where_document` filter dictionary to the query. We support two filtering keys: `$contains` and `$not_contains`. The dictionary must have the following structure:\n\n```python\n# Filtering for a search_string\n{\n \"$contains\": \"search_string\"\n}\n\n# Filtering for not contains\n{\n \"$not_contains\": \"search_string\"\n}\n```\n\nYou can combine full-text search with Chroma's metadata filtering.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\ncollection.query(\n query_texts=[\"doc10\", \"thus spake zarathustra\", ...],\n n_results=10,\n where={\"metadata_field\": \"is_equal_to_this\"},\n where_document={\"$contains\":\"search_string\"}\n)\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nawait collection.query({\n queryTexts: [\"doc10\", \"thus spake zarathustra\", ...],\n nResults: 10,\n where: {\"metadata_field\": \"is_equal_to_this\"},\n whereDocument: {\"$contains\": \"search_string\"}\n})\n```\n\n# Query and Get Data from", - "51dedd38-9496-4e7a-8666-b5acf2bd29bb": " Chroma Collections\n\nChroma collections can be queried in a variety of ways, using the `.query` method.\n\nYou can query by a set of `query embeddings`.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\ncollection.query(\n query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],\n n_results=10,\n where={\"metadata_field\": \"is_equal_to_this\"},\n where_document={\"$contains\":\"search_string\"}\n)\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nconst result = await collection.query({\n queryEmbeddings: [[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],\n nResults: 10,\n where: {\"metadata_field\": \"is_equal_to_this\"},\n})\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nThe query will return the `n results` closest matches to each `query embedding`, in order.\nAn optional `where` filter dictionary can be supplied to filter by the `metadata`", - "a5660ec0-8b27-49cd-9a1f-75b40802b0db": " associated with each document.\nAdditionally, an optional `where document` filter dictionary can be supplied to filter by contents of the document.\n\nIf the supplied `query embeddings` are not the same dimension as the collection, an exception will be raised.\n\nYou can also query by a set of `query texts`. Chroma will first embed each `query text` with the collection's embedding function, and then perform the query with the generated embedding.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\ncollection.query(\n query_texts=[\"doc10\", \"thus spake zarathustra\", ...],\n n_results=10,\n where={\"metadata_field\": \"is_equal_to_this\"},\n where_document={\"$contains\":\"search_string\"}\n)\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nawait collection.query({\n queryTexts: [\"doc10\", \"thus spake zarathustra\", ...],\n nResults: 10,\n where: {\"metadata_field\": \"is_equal_to_this\"},\n whereDocument: {\"$contains\": \"search_string\"}\n})\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nYou can also retrieve items from a", - "9c820c40-7492-481c-9aba-07b08b0c860d": " collection by `id` using `.get`.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\ncollection.get(\n\tids=[\"id1\", \"id2\", \"id3\", ...],\n\twhere={\"style\": \"style1\"}\n)\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nawait collection.get( {\n ids: [\"id1\", \"id2\", \"id3\", ...],\n where: {\"style\": \"style1\"}\n})\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n`.get` also supports the `where` and `where document` filters. If no `ids` are supplied, it will return all items in the collection that match the `where` and `where document` filters.\n\n### Choosing Which Data is Returned\n\nWhen using get or query you can use the `include` parameter to specify which data you want returned - any of `embeddings`, `documents`, `metadatas`, and for query, `distances`. By default, Chroma will return the `documents`, `metadatas` and in the case of query, the `distances` of the results. `embeddings`", - "3f4cbbd5-71ca-403d-a56c-5e5550686b4a": " are excluded by default for performance and the `ids` are always returned. You can specify which of these you want returned by passing an array of included field names to the includes parameter of the query or get method. Note that embeddings will be returned as a 2-d numpy array in `.get` and a python list of 2-d numpy arrays in `.query`.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\n# Only get documents and ids\ncollection.get(\n include=[\"documents\"]\n)\n\ncollection.query(\n query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],\n include=[\"documents\"]\n)\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\n// Only get documents and ids\nawait collection.get({\n include: [\"documents\"]\n})\n\nawait collection.query({\n query_embeddings: [[11.1, 12.1, 13.1], [1.1, 2.3, 3.2], ...],\n include: [\"documents\"]\n})\n```\n", - "0ceea0de-622a-4131-8ea9-06b8f0862ca8": "# About\n\nWe are hiring software engineers and applied research scientists.\n\n## Who we are\n\nChroma as a project is coordinated by a small team of full-time employees who work at a company also called Chroma.\n\nWe work in the sunny Mission District in San Francisco.\n\nChroma was co-founded by [Jeff Huber](https://twitter.com/jeffreyhuber) (left, CEO) and [Anton Troynikov](https://twitter.com/atroyn) (right, now Advisor).\n\n\n## Our commitment to open source\n\nChroma is a company that builds the open-source project also called Chroma.\n\nWe are committed to building open source software because we believe in the flourishing of humanity that will be unlocked through the democratization of robust, safe, and aligned AI systems. These tools need to be available to a new developer just starting in ML as well as the organizations that scale ML to millions (and billions) of users. Open source is about expanding the horizon of what\u2019s possible.\n\nChroma is a _commercial_ open source company. What does that mean? We believe that organizing financially sustainable teams of people to work to manage, push and integrate the project enriches the health of the project and the community.\n\n", - "cdaf0d8b-60d4-4d4d-8938-7e252609f2f0": "It is important that our values around this are very clear!\n\n- We are committed to building Chroma as a ubiquitous open source standard\n- A successful Chroma-based commercial product is essential for the success of the technology, and is a win-win for everyone. Simply put, many organizations will not adopt Chroma without the option of a commercially hosted solution; and the project must be backed by a company with a viable business model. We want to build an awesome project and an awesome business.\n- We will decide what we provide exclusively in the commercial product based on clear, consistent criteria.\n\nWhat code will be open source? As a general rule, any feature which an individual developer would find useful will be 100% open source forever. This approach, popularized by Gitlab, is called [buyer-based open source](https://about.gitlab.com/company/stewardship/). We believe that this is essential to accomplishing our mission.\n\nCurrently we don\u2019t have any specific plans to monetize Chroma, we are working on a hosted service that will be launched as a free technical preview to make it easier for developers to get going. We are 100% focused on building valuable open source software with the community and for the community.\n\n\n## Our", - "71152c82-ebab-4f09-93b9-e9933faaadf2": " investors\n\nChroma raised an $18M seed round led by Astasia Myers from Quiet Capital. Joining the round are angels including Naval Ravikant, Max and Jack Altman, Jordan Tigani (Motherduck), Guillermo Rauch (Vercel), Akshay Kothari (Notion), Amjad Masad (Replit), Spencer Kimball (CockroachDB), and other founders and leaders from ScienceIO, Gumroad, MongoDB, Scale, Hugging Face, Jasper and more.\n\nChroma raised a pre-seed in May 2022, led by Anthony Goldbloom (Kaggle) from AIX Ventures, James Cham from Bloomberg Beta, and Nat Friedman and Daniel Gross (AI Grant).\n\nWe're excited to work with a deep set of investors and enterpreneurs who have invested in and built some of the most successful open-source projects in the world.\n\n# Contributing\n\nWe welcome all contributions, bug reports, bug fixes, documentation improvements, enhancements, and ideas.\n\n## Getting Started\nHere are some helpful links to get you started with contributing to Chroma\n\n- The Chroma codebase is hosted on [Github](https://github.com/chroma-core/chroma)\n- Issues are", - "47aea36d-4fbe-40ea-a0fb-5b02290eb5b7": " tracked on [Github Issues](https://github.com/chroma-core/chroma/issues). Please report any issues you find there making sure to fill out the correct [form for the type of issue you are reporting](https://github.com/chroma-core/chroma/issues/new/choose).\n- In order to run Chroma locally you can follow the [Development Instructions](https://github.com/chroma-core/chroma/blob/main/DEVELOP.md).\n- If you want to contribute and aren't sure where to get started you can search for issues with the [Good first issue](https://github.com/chroma-core/chroma/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) tag or take a look at our [Roadmap](https://docs.trychroma.com/roadmap).\n- The Chroma documentation (including this page!) is hosted on [Github](https://github.com/chroma-core/docs) as well. If you find any issues with the documentation please report them on the Github Issues page for the documentation [here](https://github.com/chroma-core/docs/issues).\n\n\n## Contributing Code and Ideas\n\n### Pull Requests\nIn order to submit a", - "9aaaed58-cf0f-4623-b6b6-4718a6190710": " change to Chroma please submit a [Pull Request](https://github.com/chroma-core/chroma/compare) against Chroma or the documentation. The pull request will be reviewed by the Chroma team and if approved, will be merged into the repository. We will do our best to review pull requests in a timely manner but please be patient as we are a small team. We will work to integrate your proposed changes as quickly as possible if they align with the goals of the project. We ask that you label your pull request with a title prefix that indicates the type of change you are proposing. The following prefixes are used:\n\n```\nENH: Enhancement, new functionality\nBUG: Bug fix\nDOC: Additions/updates to documentation\nTST: Additions/updates to tests\nBLD: Updates to the build process/scripts\nPERF: Performance improvement\nTYP: Type annotations\nCLN: Code cleanup\nCHORE: Maintenance and other tasks that do not modify source or test files\n```\n\n\n### CIPs\nChroma Improvement Proposals or CIPs (pronounced \"Chips\") are the way to propose new features or large changes to Chroma. If you plan to make a large change to", - "8e14f0d2-fe83-46f3-a456-044a0b9e4949": " Chroma please submit a CIP first so that the core Chroma team as well as the community can discuss the proposed change and provide feedback. A CIP should provide a concise technical specification of the feature and a rationale for why it is needed. The CIP should be submitted as a pull request to the [CIPs folder](https://github.com/chroma-core/chroma/tree/main/docs). The CIP will be reviewed by the Chroma team and if approved will be merged into the repository. To learn more about writing a CIP you can read the [guide](https://github.com/chroma-core/chroma/blob/main/docs/CIP_Chroma_Improvment_Proposals.md). CIPs are not required for small changes such as bug fixes or documentation updates.\n\nA CIP starts in the \"Proposed\" state, then moves to \"Under Review\" once the Chroma team has reviewed it and is considering it for implementation. Once the CIP is approved it will move to the \"Accepted\" state and the implementation can begin. Once the implementation is complete the CIP will move to the \"Implemented\" state. If the CIP is not approved it will move to the \"Rejected\" state. If the", - "9a0748a6-859e-4210-95a4-684775989f7b": " CIP is withdrawn by the author it will move to the \"Withdrawn\" state.\n\n\n### Discord\nFor less fleshed out ideas you want to discuss with the community, you can join our [Discord](https://discord.gg/Fk2pH7k6) and chat with us in the #feature-ideas channel. We are always happy to discuss new ideas and features with the community.\n\n\n# Getting Started\n\nChroma is an AI-native open-source vector database. It comes with everything you need to get started built in, and runs on your machine. A [hosted version](https://trychroma.com/signup) is now available for early access!\n\n### 1. Install\n\n{% Tabs %}\n\n{% Tab label=\"python\" %}\n\n```terminal\npip install chromadb\n```\n\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n\n{% TabbedUseCaseCodeBlock language=\"Terminal\" %}\n\n{% Tab label=\"yarn\" %}\n```terminal\nyarn add chromadb chromadb-default-embed \n```\n{% /Tab %}\n\n{% Tab label=\"npm\" %}\n```terminal\nnpm install --save chromadb chromadb-default-embed\n```\n{% /Tab %}\n\n{% Tab", - "e00d6a02-5557-44f0-b349-dc2a646f71cc": " label=\"pnpm\" %}\n```terminal\npnpm add chromadb chromadb-default-embed \n```\n{% /Tab %}\n\n{% /TabbedUseCaseCodeBlock %}\n\nInstall chroma via `pip` to easily run the backend server. Here are [instructions](https://pip.pypa.io/en/stable/installation/) for installing and running `pip`. Alternatively, you can also run Chroma in a [Docker](../../production/containers/docker) container.\n\n```terminal\npip install chromadb\n```\n\n{% /Tab %}\n\n{% /Tabs %}\n\n### 2. Create a Chroma Client\n\n{% Tabs %}\n\n{% Tab label=\"python\" %}\n```python\nimport chromadb\nchroma_client = chromadb.Client()\n```\n{% /Tab %}\n{% Tab label=\"typescript\" %}\n\nRun the Chroma backend:\n\n{% TabbedUseCaseCodeBlock language=\"Terminal\" %}\n\n{% Tab label=\"CLI\" %}\n```terminal\nchroma run --path ./getting-started \n```\n{% /Tab %}\n\n{% Tab label=\"Docker\" %}\n```terminal\ndocker pull chromadb/chroma\ndocker run -p 8000:8000 chromadb/chroma---\n\n\n# Chrom", - "60d8e1e8-6f20-48fc-9ad0-290dca7c8980": "a\n\n**Chroma is the open-source AI application database**. Chroma makes it easy to build LLM apps by making knowledge, facts, and skills pluggable for LLMs.\n\n{% Banner type=\"tip\" %}\nNew to Chroma? Check out the [getting started guide](./getting-started)\n{% /Banner %}\n\n![Chroma Computer](/computer.svg)\n\nChroma gives you everything you need for retrieval:\n\n- Store embeddings and their metadata\n- Vector search\n- Full-text search\n- Document storage\n- Metadata filtering\n- Multi-modal retrieval\n\nChroma runs as a server and provides `Python` and `JavaScript/TypeScript` client SDKs. Check out the [Colab demo](https://colab.research.google.com/drive/1QEzFyqnoFxq7LUGyP1vzR4iLt9PpCDXv?usp=sharing) (yes, it can run in a Jupyter notebook).\n\nChroma is licensed under [Apache 2.0](https://github.com/chroma-core/chroma/blob/main/LICENSE)\n\n### Python\nIn Python, Chroma can run in a python script or as a server. Install Chroma", - "22c4ff22-4dd3-4f8b-b20e-1b40332ce91d": " with\n\n```shell\npip install chromadb\n```\n\n### JavaScript\nIn JavaScript, use the Chroma JS/TS Client to connect to a Chroma server. Install Chroma with your favorite package manager:\n\n{% TabbedUseCaseCodeBlock language=\"Terminal\" %}\n\n{% Tab label=\"yarn\" %}\n```terminal\nyarn add chromadb chromadb-default-embed \n```\n{% /Tab %}\n\n{% Tab label=\"npm\" %}\n```terminal\nnpm install --save chromadb chromadb-default-embed\n```\n{% /Tab %}\n\n{% Tab label=\"pnpm\" %}\n```terminal\npnpm install chromadb chromadb-default-embed \n```\n{% /Tab %}\n\n{% /TabbedUseCaseCodeBlock %}\n\n\nContinue with the full [getting started guide](./getting-started).\n\n\n***\n\n## Language Clients\n\n| Language | Client |\n|---------------|--------------------------------------------------------------------------------------------------------------------------|\n| Python | [`chromadb`](https://pypistats.org/packages/chromadb) (by Chroma) |\n| Javascript | [`chromadb`](https://www.npmjs.com/package/chromadb) (by Chroma) |\n| Ruby | [from @mario", - "88a34292-66c8-4136-bfef-1a959907d436": "chavez](https://github.com/mariochavez/chroma) |\n| Java | [from @t_azarov](https://github.com/amikos-tech/chromadb-java-client) |\n| Go | [from @t_azarov](https://github.com/amikos-tech/chroma-go) |\n| C# | [from @microsoft](https://github.com/microsoft/semantic-kernel/tree/main/dotnet/src/Connectors/Connectors.Memory.Chroma) |\n| Rust | [from @Anush008](https://crates.io/crates/chromadb) |\n| Elixir | [from @3zcurdia](https://hex.pm/packages/chroma/) |\n| Dart | [from @davidmigloz](https://pub.dev/packages/chromadb) |\n| PHP | [from @CodeWithKyrian](https://github.com/CodeWithKyrian/chromadb-php) |\n| PHP (Laravel) | [from @HelgeSverre](https://github.com/helgeSverre/chromadb) |\n| Clojure | [from @levand", - "7d835db1-6572-4e59-9dc3-c4940af4eafb": "](https://github.com/levand/clojure-chroma-client) |\n| R | [from @cynkra](https://cynkra.github.io/rchroma/) |\n| C++ | [from @BlackyDrum](https://github.com/BlackyDrum/chromadb-cpp) |\n\n\n{% br %}{% /br %}\n\nWe welcome [contributions](/markdoc/content/docs/overview/contributing.md) for other languages!\n\n```\n{% /Tab %}\n\n{% /TabbedUseCaseCodeBlock %}\n\nThen create a client which connects to it:\n\n{% TabbedUseCaseCodeBlock language=\"typescript\" %}\n\n{% Tab label=\"ESM\" %}\n```typescript\nimport { ChromaClient } from \"chromadb\";\nconst client = new ChromaClient();\n```\n{% /Tab %}\n\n{% Tab label=\"CJS\" %}\n```typescript\nconst { ChromaClient } = require(\"chromadb\");\nconst client = new ChromaClient();\n```\n{% /Tab %}\n\n{% /TabbedUseCaseCodeBlock %}\n\n{% /Tab %}\n\n{% /Tabs %}\n\n### 3. Create a collection\n\nCollections are where", - "2a146e1c-c03a-4351-a75a-2b1dcbcbff10": " you'll store your embeddings, documents, and any additional metadata. Collections index your embeddings and documents, and enable efficient retrieval and filtering. You can create a collection with a name:\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\ncollection = chroma_client.create_collection(name=\"my_collection\")\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nconst collection = await client.createCollection({\n name: \"my_collection\",\n});\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n### 4. Add some text documents to the collection\n\nChroma will store your text and handle embedding and indexing automatically. You can also customize the embedding model. You must provide unique string IDs for your documents.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\ncollection.add(\n documents=[\n \"This is a document about pineapple\",\n \"This is a document about oranges\"\n ],\n ids=[\"id1\", \"id2\"]\n)\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nawait collection.add({\n documents: [\n \"This is a document about pineapple\",\n \"This is a document", - "b2ea8533-e8e7-4da9-9dee-e032d636f722": " about oranges\",\n ],\n ids: [\"id1\", \"id2\"],\n});\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n### 5. Query the collection\n\nYou can query the collection with a list of query texts, and Chroma will return the `n` most similar results. It's that easy!\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\nresults = collection.query(\n query_texts=[\"This is a query document about hawaii\"], # Chroma will embed this for you\n n_results=2 # how many results to return\n)\nprint(results)\n```\n\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nconst results = await collection.query({\n queryTexts: \"This is a query document about hawaii\", // Chroma will embed this for you\n nResults: 2, // how many results to return\n});\n\nconsole.log(results);\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nIf `n_results` is not provided, Chroma will return 10 results by default. Here we only added 2 documents, so we set `n_results=2`.\n\n### ", - "449db2de-d98f-4878-b5ad-ebe533a4ebce": "6. Inspect Results\n\nFrom the above query - you can see that our query about `hawaii` is the semantically most similar to the document about `pineapple`.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\n{\n 'documents': [[\n 'This is a document about pineapple',\n 'This is a document about oranges'\n ]],\n 'ids': [['id1', 'id2']],\n 'distances': [[1.0404009819030762, 1.243080496788025]],\n 'uris': None,\n 'data': None,\n 'metadatas': [[None, None]],\n 'embeddings': None,\n}\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\n{\n documents: [\n [\n 'This is a document about pineapple', \n 'This is a document about oranges'\n ]\n ], \n ids: [\n ['id1', 'id2']\n ], \n distances: [[1.0404009819030762, 1.243080496788025]],\n uris: null,\n data: null,\n metadatas", - "833f5399-3d73-4047-bb65-4d92962daa14": ": [[null, null]],\n embeddings: null\n}\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n### 7. Try it out yourself\n\nFor example - what if we tried querying with `\"This is a document about florida\"`?\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\nimport chromadb\nchroma_client = chromadb.Client()\n\n# switch `create_collection` to `get_or_create_collection` to avoid creating a new collection every time\ncollection = chroma_client.get_or_create_collection(name=\"my_collection\")\n\n# switch `add` to `upsert` to avoid adding the same documents every time\ncollection.upsert(\n documents=[\n \"This is a document about pineapple\",\n \"This is a document about oranges\"\n ],\n ids=[\"id1\", \"id2\"]\n)\n\nresults = collection.query(\n query_texts=[\"This is a query document about florida\"], # Chroma will embed this for you\n n_results=2 # how many results to return\n)\n\nprint(results)\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nimport { ChromaClient } from \"chromadb\";\nconst client = new", - "1d04c29e-4372-4895-8aaa-8fd507aab871": " ChromaClient();\n\n// switch `createCollection` to `getOrCreateCollection` to avoid creating a new collection every time\nconst collection = await client.getOrCreateCollection({\n name: \"my_collection\",\n});\n\n// switch `addRecords` to `upsertRecords` to avoid adding the same documents every time\nawait collection.upsert({\n documents: [\n \"This is a document about pineapple\",\n \"This is a document about oranges\",\n ],\n ids: [\"id1\", \"id2\"],\n});\n\nconst results = await collection.query({\n queryTexts: \"This is a query document about florida\", // Chroma will embed this for you\n nResults: 2, // how many results to return\n});\n\nconsole.log(results);\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n## Next steps\n\nIn this guide we used Chroma's [ephemeral client](../run-chroma/ephemeral-client) for simplicity. It starts a Chroma server in-memory, so any data you ingest will be lost when your program terminates. You can use the [persistent client](../run-chroma/persistent-client) or run Chroma in [client-server mode](../run-ch", - "90fa63e7-aaf0-4a0f-b169-73139fe0e7ad": "roma/client-server) if you need data persistence.\n\n- Learn how to [Deploy Chroma](../../production/deployment) to a server\n- Join Chroma's [Discord Community](https://discord.com/invite/MMeYNTmh3x) to ask questions and get help\n- Follow Chroma on [Twitter (@trychroma)](https://twitter.com/trychroma) for updates\n\n# Chroma\n\n**Chroma is the open-source AI application database**. Chroma makes it easy to build LLM apps by making knowledge, facts, and skills pluggable for LLMs.\n\n{% Banner type=\"tip\" %}\nNew to Chroma? Check out the [getting started guide](./getting-started)\n{% /Banner %}\n\n![Chroma Computer](/computer.svg)\n\nChroma gives you everything you need for retrieval:\n\n- Store embeddings and their metadata\n- Vector search\n- Full-text search\n- Document storage\n- Metadata filtering\n- Multi-modal retrieval\n\nChroma runs as a server and provides `Python` and `JavaScript/TypeScript` client SDKs. Check out the [Colab demo](https://colab.research.google.com/drive/1QEzFy", - "ac57bd52-260b-4995-b892-4c175e28f86d": "qnoFxq7LUGyP1vzR4iLt9PpCDXv?usp=sharing) (yes, it can run in a Jupyter notebook).\n\nChroma is licensed under [Apache 2.0](https://github.com/chroma-core/chroma/blob/main/LICENSE)\n\n### Python\nIn Python, Chroma can run in a python script or as a server. Install Chroma with\n\n```shell\npip install chromadb\n```\n\n### JavaScript\nIn JavaScript, use the Chroma JS/TS Client to connect to a Chroma server. Install Chroma with your favorite package manager:\n\n{% TabbedUseCaseCodeBlock language=\"Terminal\" %}\n\n{% Tab label=\"yarn\" %}\n```terminal\nyarn add chromadb chromadb-default-embed \n```\n{% /Tab %}\n\n{% Tab label=\"npm\" %}\n```terminal\nnpm install --save chromadb chromadb-default-embed\n```\n{% /Tab %}\n\n{% Tab label=\"pnpm\" %}\n```terminal\npnpm install chromadb chromadb-default-embed \n```\n{% /Tab %}\n\n{% /TabbedUseCaseCodeBlock %}\n\n\nContinue with the full [getting started guide](./getting", - "0415ae0b-e74a-484c-91a6-ed5aeba83fd9": "-started).\n\n\n***\n\n## Language Clients\n\n| Language | Client |\n|---------------|--------------------------------------------------------------------------------------------------------------------------|\n| Python | [`chromadb`](https://pypistats.org/packages/chromadb) (by Chroma) |\n| Javascript | [`chromadb`](https://www.npmjs.com/package/chromadb) (by Chroma) |\n| Ruby | [from @mariochavez](https://github.com/mariochavez/chroma) |\n| Java | [from @t_azarov](https://github.com/amikos-tech/chromadb-java-client) |\n| Go | [from @t_azarov](https://github.com/amikos-tech/chroma-go) |\n| C# | [from @microsoft](https://github.com/microsoft/semantic-kernel/tree/main/dotnet/src/Connectors/Connectors.Memory.Chroma) |\n| Rust | [from @Anush008](https://crates.io/crates/chromadb) |\n| Elixir | [from @3zcurdia](https://hex.pm/packages/chroma/) |\n| Dart | [from @david", - "d6227cb9-757c-4f65-8da1-9b9aa4344da9": "migloz](https://pub.dev/packages/chromadb) |\n| PHP | [from @CodeWithKyrian](https://github.com/CodeWithKyrian/chromadb-php) |\n| PHP (Laravel) | [from @HelgeSverre](https://github.com/helgeSverre/chromadb) |\n| Clojure | [from @levand](https://github.com/levand/clojure-chroma-client) |\n| R | [from @cynkra](https://cynkra.github.io/rchroma/) |\n| C++ | [from @BlackyDrum](https://github.com/BlackyDrum/chromadb-cpp) |\n\n\n{% br %}{% /br %}\n\nWe welcome [contributions](/markdoc/content/docs/overview/contributing.md) for other languages!\n\n\n# Roadmap\n\nThe goal of this doc is to align *core* and *community* efforts for the project and to share what's in store for this year!\n\n**Sections**\n- What is the core Chroma team working on right now?\n- What will Chroma prioritize over the next", - "f36b5ea9-6c0e-496d-af3d-f5fdf13be8d2": " 6mo?\n- What areas are great for community contributions?\n\n## What is the core Chroma team working on right now?\n\n- Standing up that distributed system as a managed service (aka \"Hosted Chroma\" - [sign up for waitlist](https://trychroma.com/signup)!)\n\n## What did the Chroma team just complete?\n\nFeatures like:\n- *New* - [Chroma 0.4](https://www.trychroma.com/blog/chroma_0.4.0) - our first production-oriented release\n- A more minimal python-client only build target\n- Google PaLM embedding support\n- OpenAI ChatGPT Retrieval Plugin\n\n## What will Chroma prioritize over the next 6mo?\n\n**Next Milestone: \u2601\ufe0f Launch Hosted Chroma**\n\n**Areas we will invest in**\n\nNot an exhaustive list, but these are some of the core team\u2019s biggest priorities over the coming few months. Use caution when contributing in these areas and please check-in with the core team first.\n\n- **Workflow**: Building tools for answer questions like: what embedding model should I use? And how should I chunk up my documents?\n- **Visualization**: Building visualization tool to give developers greater intuition", - "158433cc-2181-4a53-b2c5-9fb86d74e590": " embedding spaces\n- **Query Planner**: Building tools to enable per-query and post-query transforms\n- **Developer experience**: Extending Chroma into a CLI\n- **Easier Data Sharing**: Working on formats for serialization and easier data sharing of embedding Collections\n- **Improving recall**: Fine-tuning embedding transforms through human feedback\n- **Analytical horsepower**: Clustering, deduplication, classification and more\n\n## What areas are great for community contributions?\n\nThis is where you have a lot more free reign to contribute (without having to sync with us first)!\n\nIf you're unsure about your contribution idea, feel free to chat with us (@chroma) in the `#general` channel in [our Discord](https://discord.gg/rahcMUU5XV)! We'd love to support you however we can.\n\n### Example Templates\n\nWe can always use [more integrations](../../integrations/chroma-integrations) with the rest of the AI ecosystem. Please let us know if you're working on one and need help!\n\nOther great starting points for Chroma (please send PRs for more [here](https://github.com/chroma-core/docs/tree/swyx/addRoadmap/docs)):\n- [Google Col", - "9eb60ecf-5dec-45df-afa2-2c27743d07da": "ab](https://colab.research.google.com/drive/1QEzFyqnoFxq7LUGyP1vzR4iLt9PpCDXv?usp=sharing)\n- [Replit Template](https://replit.com/@swyx/BasicChromaStarter?v=1)\n\nFor those integrations we do have, like LangChain and LlamaIndex, we do always want more tutorials, demos, workshops, videos, and podcasts (we've done some pods [on our blog](https://trychroma.com/interviews)).\n\n### Example Datasets\n\nIt doesn\u2019t make sense for developers to embed the same information over and over again with the same embedding model.\n\nWe'd like suggestions for:\n\n- \"small\" (<100 rows)\n- \"medium\" (<5MB)\n- \"large\" (>1GB)\n\ndatasets for people to stress test Chroma in a variety of scenarios.\n\n### Embeddings Comparison\n\nChroma does ship with Sentence Transformers by default for embeddings, but we are otherwise unopinionated about what embeddings you use. Having a library of information that has been embedded with many models, alongside example query sets would make it much easier for empirical work to", - "bfc3cf9c-3293-4003-a3a2-2cd4739d568d": " be done on the effectiveness of various models across different domains.\n\n- [Preliminary reading on Embeddings](https://towardsdatascience.com/neural-network-embeddings-explained-4d028e6f0526?gi=ee46baab0d8f)\n- [Huggingface Benchmark of a bunch of Embeddings](https://huggingface.co/blog/mteb)\n- [notable issues with GPT3 Embeddings](https://twitter.com/Nils_Reimers/status/1487014195568775173) and alternatives to consider\n\n### Experimental Algorithms\n\nIf you have a research background, please consider adding to our `ExperimentalAPI`s. For example:\n\n- Projections (t-sne, UMAP, the new hotness, the one you just wrote) and Lightweight visualization\n- Clustering (HDBSCAN, PCA)\n- Deduplication\n- Multimodal (CLIP)\n- Fine-tuning manifold with human feedback [eg](https://github.com/openai/openai-cookbook/blob/main/examples/Customizing_embeddings.ipynb)\n- Expanded vector search (MMR, Polytope)\n- Your research\n\nYou can find the REST OpenAPI spec at", - "14b13c9e-2680-4030-82f0-46833f424700": " `localhost:8000/openapi.json` when the backend is running.\n\nPlease [reach out](https://discord.gg/MMeYNTmh3x) and talk to us before you get too far in your projects so that we can offer technical guidance/align on roadmap.\n\n# Telemetry\n\nChroma contains a telemetry feature that collects **anonymous** usage information.\n\n### Why?\n\nWe use this information to help us understand how Chroma is used, to help us prioritize work on new features and bug fixes, and to help us improve Chroma\u2019s performance and stability.\n\n### Opting out\n\nIf you prefer to opt out of telemetry, you can do this in two ways.\n\n#### In Client Code\n\n{% Tabs %}\n\n{% Tab label=\"python\" %}\n\nSet `anonymized_telemetry` to `False` in your client's settings:\n\n```python\nfrom chromadb.config import Settings\nclient = chromadb.Client(Settings(anonymized_telemetry=False))\n# or if using PersistentClient\nclient = chromadb.PersistentClient(path=\"/path/to/save/to\", settings=Settings(anonymized_telemetry=False))\n```\n\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n\nDisable telemetry on you Chroma server", - "527f2a2f-10d2-4e19-9e65-2bac1376c0f2": " (see next section).\n\n{% /Tab %}\n\n{% /Tabs %}\n\n#### In Chroma's Backend Using Environment Variables\n\nSet `ANONYMIZED_TELEMETRY` to `False` in your shell or server environment.\n\nIf you are running Chroma on your local computer with `docker-compose` you can set this value in an `.env` file placed in the same directory as the `docker-compose.yml` file:\n\n```\nANONYMIZED_TELEMETRY=False\n```\n\n### What do you track?\n\nWe will only track usage details that help us make product decisions, specifically:\n\n- Chroma version and environment details (e.g. OS, Python version, is it running in a container, or in a jupyter notebook)\n- Usage of embedding functions that ship with Chroma and aggregated usage of custom embeddings (we collect no information about the custom embeddings themselves)\n- Client interactions with our hosted Chroma Cloud service.\n- Collection commands. We track the anonymized uuid of a collection as well as the number of items\n - `add`\n - `update`\n - `query`\n - `get`\n - `delete`\n\nWe **do not** collect personally-identifiable or sensitive information,", - "4fdd753e-246e-4677-bb0d-b06992f3a34d": " such as: usernames, hostnames, file names, environment variables, or hostnames of systems being tested.\n\nTo view the list of events we track, you may reference the **[code](https://github.com/chroma-core/chroma/blob/main/chromadb/telemetry/product/events.py)**\n\n### Where is telemetry information stored?\n\nWe use **[Posthog](https://posthog.com/)** to store and visualize telemetry data.\n\n{% Banner type=\"tip\" %}\n\nPosthog is an open source platform for product analytics. Learn more about Posthog on **[posthog.com](https://posthog.com/)** or **[github.com/posthog](https://github.com/posthog/posthog)**\n\n{% /Banner %}", - "e71ec041-f435-4434-a2e7-59c1d93ce9c0": "# Install and Run\n\nYou can install the Chroma CLI with `pip`:\n\n```terminal\npip install chromadb\n```\n\nYou can then run a Chroma server locally with the `chroma run` command:\n\n```terminal\nchroma run --path [/path/to/persist/data]\n```\n\nYour Chroma server will persist its data in the path you provide after the `path` argument. By default, \nit will save data to the `.chroma` directory.\n\nWith your Chroma server running, you can connect to it with the `HttpClient`:\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\nimport chromadb\n\nchroma_client = chromadb.HttpClient(host='localhost', port=8000)\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nimport { ChromaClient } from \"chromadb\";\n\nconst client = new ChromaClient();\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n# Vacuuming\n\nVacuuming shrinks and optimizes your database.\n\nVacuuming after upgrading from a version of Chroma below v0.5.6 will greatly reduce the size of your database and enable continuous database", - "e827e31d-eb51-4877-ad1e-aeb667766a31": " pruning. A warning is logged during server startup if this is necessary.\n\nIn most other cases, vacuuming is unnecessary. **It does not need to be run regularly**.\n\nVacuuming blocks all reads and writes to your database while it's running, so we recommend shutting down your Chroma server before vacuuming (although it's not strictly required).\n\nTo vacuum your database, run:\n\n```bash\nchroma utils vacuum --path \n```\n\nFor large databases, expect this to take up to a few minutes.\n\n", - "525d7739-7def-4dec-b995-782f81df1f23": "# Chroma Reference\n\n## Client APIs\n\nChroma currently maintains 1st party clients for Python and Javascript. For other clients in other languages, use their repos for documentation.\n\n`Client` - is the object that wraps a connection to a backing Chroma DB\n\n`Collection` - is the object that wraps a collection\n\n\n{% special_table %}\n{% /special_table %}\n\n| | Client | Collection |\n|--------------|-----------------------|-----------------------------------|\n| Python | [Client](./python/client) | [Collection](./python/collection) |\n| Javascript | [Client](./js/client) | [Collection](./js/collection) |\n\n***\n\n## Backend API\n\nChroma's backend Swagger REST API docs are viewable by running Chroma and navigating to `http://localhost:8000/docs`.\n\n```bash\npip install chromadb\nchroma run\nopen http://localhost:8000/docs\n```\n\n# JS Client\n\n## Class: ChromaClient\n\n### constructor\n\n* `new ChromaClient(params?)`\n\nCreates a new ChromaClient instance.\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `ChromaClient", - "165b0f46-a816-4bfe-a3fa-9ddada1ce469": "Params` | The parameters for creating a new client |\n\n**Example**\n\n```typescript\nconst client = new ChromaClient({\n path: \"http://localhost:8000\"\n});\n```\n\n## Methods\n\n### countCollections\n\n* `countCollections(): Promise`\n\nCounts all collections.\n\n#### Returns\n\n`Promise`\n\nA promise that resolves to the number of collections.\n\n**Throws**\n\nIf there is an issue counting the collections.\n\n**Example**\n\n```typescript\nconst collections = await client.countCollections();\n```\n\n### createCollection\n\n* `createCollection(params): Promise`\n\nCreates a new collection with the specified properties.\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `CreateCollectionParams` | The parameters for creating a new collection. |\n\n#### Returns\n\n`Promise`\n\nA promise that resolves to the created collection.\n\n**Throws**\n\n* If the client is unable to connect to the server.\n* If there is an issue creating the collection.\n\n**Example**\n\n```typescript\nconst collection = await client.createCollection({\n name: \"my_collection\",\n metadata: {\n \"description\": \"My first collection\"\n }\n});\n``", - "9614da41-31e0-47f3-8998-d8d1f8fcb473": "`\n\n### deleteCollection\n\n* `deleteCollection(params): Promise`\n\nDeletes a collection with the specified name.\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `DeleteCollectionParams` | The parameters for deleting a collection. |\n\n#### Returns\n\n`Promise`\n\nA promise that resolves when the collection is deleted.\n\n**Throws**\n\nIf there is an issue deleting the collection.\n\n**Example**\n\n```typescript\nawait client.deleteCollection({\n name: \"my_collection\"\n});\n```\n\n### getCollection\n\n`getCollection(params): Promise`\n\nGets a collection with the specified name.\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `GetCollectionParams` | The parameters for getting a collection. |\n\n#### Returns\n\n`Promise`\n\nA promise that resolves to the collection.\n\n**Throws**\n\nIf there is an issue getting the collection.\n\n**Example**\n\n```typescript\nconst collection = await client.getCollection({\n name: \"my_collection\"\n});\n```\n\n### getOrCreateCollection\n\n* `getOrCreateCollection(params): Promise`\n\nGets or creates a collection with the", - "d61bdb2b-e393-4c12-b615-c801f72ed408": " specified properties.\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `CreateCollectionParams` | The parameters for creating a new collection. |\n\n#### Returns\n\n`Promise`\n\nA promise that resolves to the got or created collection.\n\n**Throws**\n\nIf there is an issue getting or creating the collection.\n\n**Example**\n\n```typescript\nconst collection = await client.getOrCreateCollection({\n name: \"my_collection\",\n metadata: {\n \"description\": \"My first collection\"\n }\n});\n```\n\n### heartbeat\n\n* `heartbeat(): Promise`\n\nReturns a heartbeat from the Chroma API.\n\n#### Returns\n\n`Promise`\n\nA promise that resolves to the heartbeat from the Chroma API.\n\n**Throws**\n\nIf the client is unable to connect to the server.\n\n**Example**\n\n```typescript\nconst heartbeat = await client.heartbeat();\n```\n\n### listCollections\n\n* `listCollections(params?): Promise`\n\nLists all collections.\n\n#### Parameters\n\n| Name | Type |\n|:---------| :------ |\n| `params` | `ListCollectionsParams` |\n\n#### Returns\n\n`Promise`\n\nA promise that resolves to", - "5ac1eebf-3db6-4920-9f2f-758ad279a5cc": " a list of collection names.\n\n**Throws**\n\nIf there is an issue listing the collections.\n\n**Example**\n\n```typescript\nconst collections = await client.listCollections({\n limit: 10,\n offset: 0,\n});\n```\n\n### reset\n\n* `reset(): Promise`\n\nResets the state of the object by making an API call to the reset endpoint.\n\n#### Returns\n\n`Promise`\n\nA promise that resolves when the reset operation is complete.\n\n**Throws**\n\n* If the client is unable to connect to the server.\n* If the server experienced an error while the state.\n\n**Example**\n\n```typescript\nawait client.reset();\n```\n\n### version\n\n* `version(): Promise`\n\nReturns the version of the Chroma API.\n\n#### Returns\n\n`Promise`\n\nA promise that resolves to the version of the Chroma API.\n\n**Throws**\n\nIf the client is unable to connect to the server.\n\n**Example**\n\n```typescript\nconst version = await client.version();\n```\n# Class: Collection\n\n## Properties\n\n* `id: string`\n* `metadata: CollectionMetadata`\n* `name: string`\n\n## Methods\n\n### add\n\n* `add(params): Promise`\n\nAdd items to the collection\n\n", - "f3806e87-1453-4495-a40f-20acecb209f0": "#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `AddRecordsParams` | The parameters for the query. |\n\n#### Returns\n\n`Promise`\n\n- The response from the API.\n\n**Example**\n\n```typescript\nconst response = await collection.add({\n ids: [\"id1\", \"id2\"],\n embeddings: [[1, 2, 3], [4, 5, 6]],\n metadatas: [{ \"key\": \"value\" }, { \"key\": \"value\" }],\n documents: [\"document1\", \"document2\"]\n});\n```\n\n### count\n\n* `count(): Promise`\n\nCount the number of items in the collection\n\n#### Returns\n\n`Promise`\n\n- The number of items in the collection.\n\n**Example**\n\n```typescript\nconst count = await collection.count();\n```\n\n### delete\n\n* `delete(params?): Promise`\n\nDeletes items from the collection.\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `DeleteParams` | The parameters for deleting items from the collection. |\n\n#### Returns\n\n`Promise", - "e879307f-7e69-4900-a835-726e48322480": "`\n\nA promise that resolves to the IDs of the deleted items.\n\n**Throws**\n\nIf there is an issue deleting items from the collection.\n\n**Example**\n\n```typescript\nconst results = await collection.delete({\n ids: \"some_id\",\n where: {\"name\": {\"$eq\": \"John Doe\"}},\n whereDocument: {\"$contains\":\"search_string\"}\n});\n```\n\n### get\n\n* `get(params?): Promise`\n\nGet items from the collection\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `BaseGetParams` | The parameters for the query. |\n\n#### Returns\n\n`Promise`\n\nThe response from the server.\n\n**Example**\n\n```typescript\nconst response = await collection.get({\n ids: [\"id1\", \"id2\"],\n where: { \"key\": \"value\" },\n limit: 10,\n offset: 0,\n include: [\"embeddings\", \"metadatas\", \"documents\"],\n whereDocument: { $contains: \"value\" },\n});\n```\n\n### modify\n\n* `modify(params): Promise`\n\nModify the collection name or metadata\n\n####", - "94106018-c089-48de-8d92-56424a9438d0": " Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `Object` | The parameters for the query. |\n| `params.metadata?` | `CollectionMetadata` | Optional new metadata for the collection. |\n| `params.name?` | `string` | Optional new name for the collection. |\n\n#### Returns\n\n`Promise`\n\nThe response from the API.\n\n**Example**\n\n```typescript\nconst response = await client.updateCollection({\n name: \"new name\",\n metadata: { \"key\": \"value\" },\n});\n```\n\n### peek\n\n* `peek(params?): Promise`\n\nPeek inside the collection\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `PeekParams` | The parameters for the query. |\n\n#### Returns\n\n`Promise`\n\nA promise that resolves to the query results.\n\n**Throws**\n\nIf there is an issue executing the query.\n\n**Example**\n\n```typescript\nconst results = await collection.peek({\n limit: 10\n});\n```\n\n### query\n\n* `query(params): Promise`\n\nPerforms a query on the collection using the specified parameters.\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `QueryRecordsParams` | The parameters for the query. |\n\n#### Returns\n\n`Promise`\n\nA promise that resolves to the query results.\n\n**Throws**\n\nIf there is an issue executing the query.\n\n**Example**\n\n```typescript\n// Query the collection using embeddings\nconst embeddingsResults = await collection.query({\n queryEmbeddings: [[0.1, 0.2, ...], ...],\n nResults: 10,\n where: {\"name\": {\"$eq\": \"John Doe\"}},\n include: [\"metadata\", \"document\"]\n});\n\n// Query the collection using query text\nconst textResults = await collection.query({\n queryTexts: \"some text\",\n nResults: 10,\n where: {\"name\": {\"$eq\": \"John Doe\"}},\n include: [\"metadata\", \"document\"]\n});\n```\n\n### update\n\n* `update(params): Promise`\n\nUpdate items in the collection\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :", - "9cb4677f-878c-4d19-bfb1-65369ed77e16": "------ |\n| `params` | `UpdateRecordsParams` | The parameters for the query. |\n\n#### Returns\n\n`Promise`\n\n**Example**\n\n```typescript\nconst response = await collection.update({\n ids: [\"id1\", \"id2\"],\n embeddings: [[1, 2, 3], [4, 5, 6]],\n metadatas: [{ \"key\": \"value\" }, { \"key\": \"value\" }],\n documents: [\"document1\", \"document2\"],\n});\n```\n\n### upsert\n\n* `upsert(params): Promise`\n\nUpsert items to the collection\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `AddRecordsParams` | The parameters for the query. |\n\n#### Returns\n\n`Promise`\n\n**Example**\n\n```typescript\nconst response = await collection.upsert({\n ids: [\"id1\", \"id2\"],\n embeddings: [[1, 2, 3], [4, 5, 6]],\n metadatas: [{ \"key\": \"value\" }, { \"key\": \"value\" }],\n documents: [\"document1\", \"", - "52668e87-a665-4d15-bfbd-70ba37715999": "document2\"],\n});\n```\n\n# Python Client\n\n## configure\n\n```python\ndef configure(**kwargs) -> None\n```\n\nOverride Chroma's default settings, environment variables or .env files\n\n## EphemeralClient\n\n```python\ndef EphemeralClient(settings: Optional[Settings] = None,\n tenant: str = DEFAULT_TENANT,\n database: str = DEFAULT_DATABASE) -> ClientAPI\n```\n\nCreates an in-memory instance of Chroma. This is useful for testing and\ndevelopment, but not recommended for production use.\n\n**Arguments**:\n\n- `tenant` - The tenant to use for this client. Defaults to the default tenant.\n- `database` - The database to use for this client. Defaults to the default database.\n\n## PersistentClient\n\n```python\ndef PersistentClient(path: str = \"./chroma\",\n settings: Optional[Settings] = None,\n tenant: str = DEFAULT_TENANT,\n database: str = DEFAULT_DATABASE) -> ClientAPI\n```\n\nCreates a persistent instance of Chroma that saves to disk. This is useful for\ntesting and development, but not recommended for production use.\n\n**Arguments**:\n\n- `path` - The directory to save Chroma's", - "9a502759-f7bc-4290-9ce3-a957b81c12fd": " data to. Defaults to \"./chroma\".\n- `tenant` - The tenant to use for this client. Defaults to the default tenant.\n- `database` - The database to use for this client. Defaults to the default database.\n\n## HttpClient\n\n```python\ndef HttpClient(host: str = \"localhost\",\n port: int = 8000,\n ssl: bool = False,\n headers: Optional[Dict[str, str]] = None,\n settings: Optional[Settings] = None,\n tenant: str = DEFAULT_TENANT,\n database: str = DEFAULT_DATABASE) -> ClientAPI\n```\n\nCreates a client that connects to a remote Chroma server. This supports\nmany clients connecting to the same server, and is the recommended way to\nuse Chroma in production.\n\n**Arguments**:\n\n- `host` - The hostname of the Chroma server. Defaults to \"localhost\".\n- `port` - The port of the Chroma server. Defaults to \"8000\".\n- `ssl` - Whether to use SSL to connect to the Chroma server. Defaults to False.\n- `headers` - A dictionary of headers to send to the Chroma server. Defaults to {}.\n- `settings` - A", - "a5c4a8bf-b5a7-46b9-b598-9ed8610b88b0": " dictionary of settings to communicate with the chroma server.\n- `tenant` - The tenant to use for this client. Defaults to the default tenant.\n- `database` - The database to use for this client. Defaults to the default database.\n\n## AsyncHttpClient\n\n```python\nasync def AsyncHttpClient(host: str = \"localhost\",\n port: int = 8000,\n ssl: bool = False,\n headers: Optional[Dict[str, str]] = None,\n settings: Optional[Settings] = None,\n tenant: str = DEFAULT_TENANT,\n database: str = DEFAULT_DATABASE) -> AsyncClientAPI\n```\n\nCreates an async client that connects to a remote Chroma server. This supports\nmany clients connecting to the same server, and is the recommended way to\nuse Chroma in production.\n\n**Arguments**:\n\n- `host` - The hostname of the Chroma server. Defaults to \"localhost\".\n- `port` - The port of the Chroma server. Defaults to \"8000\".\n- `ssl` - Whether to use SSL to connect to the Chroma server. Defaults to False.\n- `headers` - A dictionary of headers to send to the Chroma server. Defaults to {}", - "0a7e1b15-5e91-4cbc-9974-b2928e374d6c": ".\n- `settings` - A dictionary of settings to communicate with the chroma server.\n- `tenant` - The tenant to use for this client. Defaults to the default tenant.\n- `database` - The database to use for this client. Defaults to the default database.\n\n## CloudClient\n\n```python\ndef CloudClient(tenant: str,\n database: str,\n api_key: Optional[str] = None,\n settings: Optional[Settings] = None,\n *,\n cloud_host: str = \"api.trychroma.com\",\n cloud_port: int = 8000,\n enable_ssl: bool = True) -> ClientAPI\n```\n\nCreates a client to connect to a tenant and database on the Chroma cloud.\n\n**Arguments**:\n\n- `tenant` - The tenant to use for this client.\n- `database` - The database to use for this client.\n- `api_key` - The api key to use for this client.\n\n## Client\n\n```python\ndef Client(settings: Settings = __settings,\n tenant: str = DEFAULT_TENANT,\n database: str = DEFAULT_DATABASE) -> ClientAPI\n```\n\nReturn a running `chroma.API` instance\n\n**Arguments**:\n\n*", - "d6852c3f-d696-4e7d-a4a4-271f26d9590a": " `tenant`: The tenant to use for this client. Defaults to the `default` tenant.\n* `database`: The database to use for this client. Defaults to the `default` database.\n\n## AdminClient\n\n```python\ndef AdminClient(settings: Settings = Settings()) -> AdminAPI\n```\n\nCreates an admin client that can be used to create tenants and databases.\n\n***\n\n# BaseClient Methods\n\n```python\nclass BaseAPI(ABC)\n```\n\n## heartbeat\n\n```python\ndef heartbeat() -> int\n```\n\nGet the current time in nanoseconds since epoch.\nUsed to check if the server is alive.\n\n**Returns**:\n\n- `int` - The current time in nanoseconds since epoch\n\n## count\\_collections\n\n```python\ndef count_collections() -> int\n```\n\nCount the number of collections.\n\n**Returns**:\n\n- `int` - The number of collections.\n\n\n**Examples**:\n\n```python\nclient.count_collections()\n# 1\n```\n\n## delete\\_collection\n\n```python\ndef delete_collection(name: str) -> None\n```\n\nDelete a collection with the given name.\n\n**Arguments**:\n\n- `name` - The name of the collection to delete.\n\n\n**Raises**:\n\n- `ValueError", - "4d586c67-5473-4d1d-9204-17ac4c9fe6f8": "` - If the collection does not exist.\n\n\n**Examples**:\n\n ```python\n client.delete_collection(\"my_collection\")\n ```\n\n## reset\n\n```python\ndef reset() -> bool\n```\n\nResets the database. This will delete all collections and entries.\n\n**Returns**:\n\n- `bool` - True if the database was reset successfully.\n\n## get\\_version\n\n```python\ndef get_version() -> str\n```\n\nGet the version of Chroma.\n\n**Returns**:\n\n- `str` - The version of Chroma\n\n## get\\_settings\n\n```python\ndef get_settings() -> Settings\n```\n\nGet the settings used to initialize.\n\n**Returns**:\n\n- `Settings` - The settings used to initialize.\n\n## get\\_max\\_batch\\_size\n\n```python\ndef get_max_batch_size() -> int\n```\n\nReturn the maximum number of records that can be created or mutated in a single call.\n\n***\n\n# ClientClient Methods\n\n```python\nclass ClientAPI(BaseAPI, ABC)\n```\n\n## list\\_collections\n\n```python\ndef list_collections(limit: Optional[int] = None,\n offset: Optional[int] = None) -> Sequence[CollectionName]\n```\n\nList all collections names.\n\n", - "8dd1648f-92f8-4af9-b324-0cba868ecd9d": "**Arguments**:\n\n- `limit` - The maximum number of entries to return. Defaults to None.\n- `offset` - The number of entries to skip before returning. Defaults to None.\n\n\n**Returns**:\n\n- `Sequence[CollectionName]` - A list of collection names. `CollectionName` is a string.\n\n\n**Examples**:\n\n```python\nclient.list_collections()\n# ['my_collection']\n```\n\n## create_collection\n\n```python\ndef create_collection(name: str,\n configuration: Optional[CollectionConfiguration] = None,\n metadata: Optional[CollectionMetadata] = None,\n embedding_function: Optional[EmbeddingFunction[\n Embeddable]] = ef.DefaultEmbeddingFunction(),\n data_loader: Optional[DataLoader[Loadable]] = None,\n get_or_create: bool = False) -> Collection\n```\n\nCreate a new collection with the given name and metadata.\n\n**Arguments**:\n\n- `name` - The name of the collection to create.\n- `metadata` - Optional metadata to associate with the collection.\n- `embedding_function` - Optional function to use to embed documents.\n Uses the default embedding function if not provided.\n- `get_or_create` - If True, return the existing collection", - "e50c7c13-3d39-4595-964a-544b1c3a71d5": " if it exists.\n- `data_loader` - Optional function to use to load records (documents, images, etc.)\n\n\n**Returns**:\n\n- `Collection` - The newly created collection.\n\n\n**Raises**:\n\n- `ValueError` - If the collection already exists and get_or_create is False.\n- `ValueError` - If the collection name is invalid.\n\n\n**Examples**:\n\n```python\nclient.create_collection(\"my_collection\")\n# collection(name=\"my_collection\", metadata={})\n\nclient.create_collection(\"my_collection\", metadata={\"foo\": \"bar\"})\n# collection(name=\"my_collection\", metadata={\"foo\": \"bar\"})\n```\n\n## get_collection\n\n```python\ndef get_collection(\n name: str,\n id: Optional[UUID] = None,\n embedding_function: Optional[\n EmbeddingFunction[Embeddable]] = ef.DefaultEmbeddingFunction(),\n data_loader: Optional[DataLoader[Loadable]] = None) -> Collection\n```\n\nGet a collection with the given name.\n\n**Arguments**:\n\n- `id` - The UUID of the collection to get. Id and Name are simultaneously used for lookup if provided.\n- `name` - The name of the collection to get\n- `embedding_function`", - "65c10865-cb97-454f-b8f0-e4093fc97fed": " - Optional function to use to embed documents.\n Uses the default embedding function if not provided.\n- `data_loader` - Optional function to use to load records (documents, images, etc.)\n\n\n**Returns**:\n\n- `Collection` - The collection\n\n\n**Raises**:\n\n- `ValueError` - If the collection does not exist\n\n\n**Examples**:\n\n ```python\n client.get_collection(\"my_collection\")\n # collection(name=\"my_collection\", metadata={})\n ```\n\n## get\\_or\\_create\\_collection\n\n```python\ndef get_or_create_collection(\n name: str,\n configuration: Optional[CollectionConfiguration] = None,\n metadata: Optional[CollectionMetadata] = None,\n embedding_function: Optional[\n EmbeddingFunction[Embeddable]] = ef.DefaultEmbeddingFunction(),\n data_loader: Optional[DataLoader[Loadable]] = None) -> Collection\n```\n\nGet or create a collection with the given name and metadata.\n\n**Arguments**:\n\n- `name` - The name of the collection to get or create\n- `metadata` - Optional metadata to associate with the collection. If\n the collection alredy exists, the metadata will be ignored. If the collection does", - "69e0f556-2a2a-4488-8d19-f7aa16c156b2": " not exist, the\n new collection will be created with the provided metadata.\n- `embedding_function` - Optional function to use to embed documents\n- `data_loader` - Optional function to use to load records (documents, images, etc.)\n\n\n**Returns**:\n\n The collection\n\n\n**Examples**:\n\n ```python\n client.get_or_create_collection(\"my_collection\")\n # collection(name=\"my_collection\", metadata={})\n ```\n\n## set_tenant\n\n```python\ndef set_tenant(tenant: str, database: str = DEFAULT_DATABASE) -> None\n```\n\nSet the tenant and database for the client. Raises an error if the tenant or\ndatabase does not exist.\n\n**Arguments**:\n\n- `tenant` - The tenant to set.\n- `database` - The database to set.\n\n## set_database\n\n```python\ndef set_database(database: str) -> None\n```\n\nSet the database for the client. Raises an error if the database does not exist.\n\n**Arguments**:\n\n- `database` - The database to set.\n\n## clear_system_cache\n\n```python\n@staticmethod\ndef clear_system_cache() -> None\n```\n\nClear the system cache so that new systems can be created for an", - "8fa305d2-fca2-4fde-b144-289a03ebed00": " existing path.\nThis should only be used for testing purposes.\n\n***\n\n# AdminClient Methods\n\n```python\nclass AdminAPI(ABC)\n```\n\n## create_database\n\n```python\ndef create_database(name: str, tenant: str = DEFAULT_TENANT) -> None\n```\n\nCreate a new database. Raises an error if the database already exists.\n\n**Arguments**:\n\n- `database` - The name of the database to create.\n\n## get_database\n\n```python\ndef get_database(name: str, tenant: str = DEFAULT_TENANT) -> Database\n```\n\nGet a database. Raises an error if the database does not exist.\n\n**Arguments**:\n\n- `database` - The name of the database to get.\n- `tenant` - The tenant of the database to get.\n\n## delete_database\n\n```python\ndef delete_database(name: str, tenant: str = DEFAULT_TENANT) -> None\n```\n\nDelete a database and all associated collections. Raises an error if the database does not exist.\n\n**Arguments**:\n\n- `database` - The name of the database to delete.\n- `tenant` - The tenant of the database to delete.\n\n## list_databases\n\n```python\ndef list_databases(limit:", - "6f623338-7220-4823-be53-b07cabde1e69": " Optional[int] = None, offset: Optional[int] = None, tenant: str = DEFAULT_TENANT) -> Sequence[Database]\n```\n\nList databases for a tenant.\n\n**Arguments**:\n\n- `limit` - The maximum number of entries to return. Defaults to None.\n- `offset` - The number of entries to skip before returning. Defaults to None.\n- `tenant` - The tenant to list databases for.\n\n## create_tenant\n\n```python\ndef create_tenant(name: str) -> None\n```\n\nCreate a new tenant. Raises an error if the tenant already exists.\n\n**Arguments**:\n\n- `tenant` - The name of the tenant to create.\n\n## get_tenant\n\n```python\ndef get_tenant(name: str) -> Tenant\n```\n\nGet a tenant. Raises an error if the tenant does not exist.\n\n**Arguments**:\n\n- `tenant` - The name of the tenant to get.\n\n***\n\n# ServerClient Methods\n\n```python\nclass ServerAPI(BaseAPI, AdminAPI, Component)\n```\n\nAn API instance that extends the relevant Base API methods by passing\nin a tenant and database. This is the root component of the Chroma System\n\n---\ntitle: Collection\n---\n\n#", - "ee0b6e7f-293e-4066-bd3b-2400788bdb0a": " Python Collection\n\n```python\nclass Collection(BaseModel)\n```\n\n## count\n\n```python\ndef count() -> int\n```\n\nThe total number of embeddings added to the database\n\n**Returns**:\n\n- `int` - The total number of embeddings added to the database\n\n## add\n\n```python\ndef add(ids: OneOrMany[ID],\n embeddings: Optional[OneOrMany[Embedding]] = None,\n metadatas: Optional[OneOrMany[Metadata]] = None,\n documents: Optional[OneOrMany[Document]] = None) -> None\n```\n\nAdd embeddings to the data store.\n\n**Arguments**:\n\n- `ids` - The ids of the embeddings you wish to add\n- `embeddings` - The embeddings to add. If None, embeddings will be computed based on the documents using the embedding_function set for the Collection. Optional.\n- `metadatas` - The metadata to associate with the embeddings. When querying, you can filter on this metadata. Optional.\n- `documents` - The documents to associate with the embeddings. Optional.\n\n\n**Returns**:\n\n None\n\n\n**Raises**:\n\n- `ValueError` - If you don't provide either embeddings or documents\n-", - "ebe94e1f-3715-4802-94c0-ceeafa8c6d63": " `ValueError` - If the length of ids, embeddings, metadatas, or documents don't match\n- `ValueError` - If you don't provide an embedding function and don't provide embeddings\n- `DuplicateIDError` - If you provide an id that already exists\n\n## get\n\n```python\ndef get(ids: Optional[OneOrMany[ID]] = None,\n where: Optional[Where] = None,\n limit: Optional[int] = None,\n offset: Optional[int] = None,\n where_document: Optional[WhereDocument] = None,\n include: Include = [\"metadatas\", \"documents\"]) -> GetResult\n```\n\nGet embeddings and their associate data from the data store. If no ids or where filter is provided returns\nall embeddings up to limit starting at offset.\n\n**Arguments**:\n\n- `ids` - The ids of the embeddings to get. Optional.\n- `where` - A Where type dict used to filter results by. E.g. `{\"color\" : \"red\", \"price\": 4.20}`. Optional.\n- `limit` - The number of documents to return. Optional.\n- `offset` - The offset to start returning results from", - "38812435-06d7-470f-ac24-2e0e7411940f": ". Useful for paging results with limit. Optional.\n- `where_document` - A WhereDocument type dict used to filter by the documents. E.g. `{$contains: {\"text\": \"hello\"}}`. Optional.\n- `include` - A list of what to include in the results. Can contain `\"embeddings\"`, `\"metadatas\"`, `\"documents\"`. Ids are always included. Defaults to `[\"metadatas\", \"documents\"]`. Optional.\n\n\n**Returns**:\n\n- `GetResult` - A GetResult object containing the results.\n\n## peek\n\n```python\ndef peek(limit: int = 10) -> GetResult\n```\n\nGet the first few results in the database up to limit\n\n**Arguments**:\n\n- `limit` - The number of results to return.\n\n\n**Returns**:\n\n- `GetResult` - A GetResult object containing the results.\n\n## query\n\n```python\ndef query(\n query_embeddings: Optional[OneOrMany[Embedding]] = None,\n query_texts: Optional[OneOrMany[Document]] = None,\n n_results: int = 10,\n where: Optional[Where] = None,\n where_document: Optional[WhereDocument] =", - "10407513-0352-48d5-a962-1f380d6ffec5": " None,\n include: Include = [\"metadatas\", \"documents\",\n \"distances\"]) -> QueryResult\n```\n\nGet the n_results nearest neighbor embeddings for provided query_embeddings or query_texts.\n\n**Arguments**:\n\n- `query_embeddings` - The embeddings to get the closest neighbors of. Optional.\n- `query_texts` - The document texts to get the closest neighbors of. Optional.\n- `n_results` - The number of neighbors to return for each query_embedding or query_texts. Optional.\n- `where` - A Where type dict used to filter results by. E.g. `{\"color\" : \"red\", \"price\": 4.20}`. Optional.\n- `where_document` - A WhereDocument type dict used to filter by the documents. E.g. `{$contains: {\"text\": \"hello\"}}`. Optional.\n- `include` - A list of what to include in the results. Can contain `\"embeddings\"`, `\"metadatas\"`, `\"documents\"`, `\"distances\"`. Ids are always included. Defaults to `[\"metadatas\", \"documents\", \"distances\"]`. Optional.\n\n\n**Returns**:\n\n- `QueryResult` - A QueryResult object containing the", - "ad8892c2-cf94-465d-ab03-79638af8c609": " results.\n\n\n**Raises**:\n\n- `ValueError` - If you don't provide either query_embeddings or query_texts\n- `ValueError` - If you provide both query_embeddings and query_texts\n\n## modify\n\n```python\ndef modify(name: Optional[str] = None,\n metadata: Optional[CollectionMetadata] = None) -> None\n```\n\nModify the collection name or metadata\n\n**Arguments**:\n\n- `name` - The updated name for the collection. Optional.\n- `metadata` - The updated metadata for the collection. Optional.\n\n\n**Returns**:\n\n None\n\n## update\n\n```python\ndef update(ids: OneOrMany[ID],\n embeddings: Optional[OneOrMany[Embedding]] = None,\n metadatas: Optional[OneOrMany[Metadata]] = None,\n documents: Optional[OneOrMany[Document]] = None) -> None\n```\n\nUpdate the embeddings, metadatas or documents for provided ids.\n\n**Arguments**:\n\n- `ids` - The ids of the embeddings to update\n- `embeddings` - The embeddings to add. If None, embeddings will be computed based on the documents using the embedding_function set for the Collection. Optional.\n- `metad", - "7ca0bc18-158f-477c-84c8-e47088a9253d": "atas` - The metadata to associate with the embeddings. When querying, you can filter on this metadata. Optional.\n- `documents` - The documents to associate with the embeddings. Optional.\n\n\n**Returns**:\n\n None\n\n## upsert\n\n```python\ndef upsert(ids: OneOrMany[ID],\n embeddings: Optional[OneOrMany[Embedding]] = None,\n metadatas: Optional[OneOrMany[Metadata]] = None,\n documents: Optional[OneOrMany[Document]] = None) -> None\n```\n\nUpdate the embeddings, metadatas or documents for provided ids, or create them if they don't exist.\n\n**Arguments**:\n\n- `ids` - The ids of the embeddings to update\n- `embeddings` - The embeddings to add. If None, embeddings will be computed based on the documents using the embedding_function set for the Collection. Optional.\n- `metadatas` - The metadata to associate with the embeddings. When querying, you can filter on this metadata. Optional.\n- `documents` - The documents to associate with the embeddings. Optional.\n\n\n**Returns**:\n\n None\n\n## delete\n\n```python\ndef delete(ids: Optional[IDs] = None,\n", - "d9522f64-ccb3-4438-a110-4b22a7d574bc": " where: Optional[Where] = None,\n where_document: Optional[WhereDocument] = None) -> None\n```\n\nDelete the embeddings based on ids and/or a where filter\n\n**Arguments**:\n\n- `ids` - The ids of the embeddings to delete\n- `where` - A Where type dict used to filter the delection by. E.g. `{\"color\" : \"red\", \"price\": 4.20}`. Optional.\n- `where_document` - A WhereDocument type dict used to filter the deletion by the document content. E.g. `{$contains: {\"text\": \"hello\"}}`. Optional.\n\n\n**Returns**:\n\n None", - "2d7637e9-510a-492d-b213-7e4edb4ceca8": "# Embedding Functions\n\n## Default: all-MiniLM-L6-v2\n\nBy default, Chroma uses the [Sentence Transformers](https://www.sbert.net/) `all-MiniLM-L6-v2` model to create embeddings. This embedding model can create sentence and document embeddings that can be used for a wide variety of tasks. This embedding function runs locally on your machine, and may require you download the model files (this will happen automatically).\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\nfrom chromadb.utils import embedding_functions\ndefault_ef = embedding_functions.DefaultEmbeddingFunction()\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nimport { DefaultEmbeddingFunction } from \"chromadb\";\nconst defaultEF = new DefaultEmbeddingFunction();\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nEmbedding functions can be linked to a collection and used whenever you call `add`, `update`, `upsert` or `query`. You can also use them directly which can be handy for debugging.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\nval = default_ef([\"foo\"])\nprint(val)", - "be0cbc2f-da01-4e8f-9d84-0e6a2fde6455": " # [[0.05035809800028801, 0.0626462921500206, -0.061827320605516434...]]\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nconst val = defaultEf.generate([\"foo\"]);\nconsole.log(val); // [[0.05035809800028801, 0.0626462921500206, -0.061827320605516434...]]\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n## Sentence Transformers\n\nChroma can also use any [Sentence Transformers](https://www.sbert.net/) model to create embeddings.\n\nYou can pass in an optional `model_name` argument, which lets you choose which Sentence Transformers model to use. By default, Chroma uses `all-MiniLM-L6-v2`. You can see a list of all available models [here](https://www.sbert.net/docs/pretrained_models.html).\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\nsentence_transformer_ef = embedding_functions.SentenceTransformerEmbeddingFunction(\n model_name=\"all-MiniLM-L6-v2\"\n)\n```\n{% /Tab %}\n\n", - "070fe511-a8db-4ec8-b85c-64bf36bc8188": "{% Tab label=\"typescript\" %}\n```typescript\nimport { DefaultEmbeddingFunction } from \"chromadb\";\nconst modelName = \"all-MiniLM-L6-v2\";\nconst defaultEF = new DefaultEmbeddingFunction(modelName);\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n## Custom Embedding Functions\n\nYou can create your own embedding function to use with Chroma, it just needs to implement the `EmbeddingFunction` protocol.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\nfrom chromadb import Documents, EmbeddingFunction, Embeddings\n\nclass MyEmbeddingFunction(EmbeddingFunction):\n def __call__(self, input: Documents) -> Embeddings:\n # embed the documents somehow\n return embeddings\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nclass MyEmbeddingFunction {\n private api_key: string;\n\n constructor(api_key: string) {\n this.api_key = api_key;\n }\n\n public async generate(texts: string[]): Promise {\n // do things to turn texts into embeddings with an api_key perhaps\n return embeddings;\n }\n}\n```\n\n# Multimodal", - "f608d1bb-2cb6-4a97-bb64-8d8dfc19f15a": "\n\n{% Banner type=\"note\" %}\nMultimodal support is currently available only in Python. Javascript/Typescript support coming soon! \n{% /Banner %}\n\nChroma supports multimodal collections, i.e. collections which can store, and can be queried by, multiple modalities of data.\n\n[Try it out in Colab](https://githubtocolab.com/chroma-core/chroma/blob/main/examples/multimodal/multimodal_retrieval.ipynb)\n\n## Multi-modal Embedding Functions\n\nChroma supports multi-modal embedding functions, which can be used to embed data from multiple modalities into a single embedding space.\n\nChroma has the OpenCLIP embedding function built in, which supports both text and images.\n\n```python\nfrom chromadb.utils.embedding_functions import OpenCLIPEmbeddingFunction\nembedding_function = OpenCLIPEmbeddingFunction()\n```\n\n## Data Loaders\n\nChroma supports data loaders, for storing and querying with data stored outside Chroma itself, via URI. Chroma will not store this data, but will instead store the URI, and load the data from the URI when needed.\n\nChroma has a data loader for loading images from a filesystem built in.\n\n```python\nfrom", - "e39bb547-ec5a-4b04-bb10-69361dd66c39": " chromadb.utils.data_loaders import ImageLoader\ndata_loader = ImageLoader()\n```\n\n## Multi-modal Collections\n\nYou can create a multi-modal collection by passing in a multi-modal embedding function. In order to load data from a URI, you must also pass in a data loader.\n\n```python\nimport chromadb\n\nclient = chromadb.Client()\n\ncollection = client.create_collection(\n name='multimodal_collection',\n embedding_function=embedding_function,\n data_loader=data_loader)\n\n```\n\n### Adding data\n\nYou can add data to a multi-modal collection by specifying the data modality. For now, images are supported:\n\n```python\ncollection.add(\n ids=['id1', 'id2', 'id3'],\n images=[...] # A list of numpy arrays representing images\n)\n```\n\nNote that Chroma will not store the data for you, and you will have to maintain a mapping from IDs to data yourself.\n\nHowever, you can use Chroma in combination with data stored elsewhere, by adding it via URI. Note that this requires that you have specified a data loader when creating the collection.\n\n```python\ncollection.add(\n ids=['id1', 'id2', 'id3'],\n uris=[...] #", - "e616ec9c-2223-4d25-87c8-73540a747ed5": " A list of strings representing URIs to data\n)\n```\n\nSince the embedding function is multi-modal, you can also add text to the same collection:\n\n```python\ncollection.add(\n ids=['id4', 'id5', 'id6'],\n documents=[\"This is a document\", \"This is another document\", \"This is a third document\"]\n)\n```\n\n### Querying\n\nYou can query a multi-modal collection with any of the modalities that it supports. For example, you can query with images:\n\n```python\nresults = collection.query(\n query_images=[...] # A list of numpy arrays representing images\n)\n```\n\nOr with text:\n\n```python\nresults = collection.query(\n query_texts=[\"This is a query document\", \"This is another query document\"]\n)\n```\n\nIf a data loader is set for the collection, you can also query with URIs which reference data stored elsewhere of the supported modalities:\n\n```python\nresults = collection.query(\n query_uris=[...] # A list of strings representing URIs to data\n)\n```\n\nAdditionally, if a data loader is set for the collection, and URIs are available, you can include the data in the results:\n\n```python\nresults", - "3ff9f5dc-e4e1-406a-80dc-f9123a07466b": " = collection.query(\n query_images=[...], # # list of numpy arrays representing images\n includes=['data']\n)\n```\n\nThis will automatically call the data loader for any available URIs, and include the data in the results. `uris` are also available as an `includes` field.\n\n### Updating\n\nYou can update a multi-modal collection by specifying the data modality, in the same way as `add`. For now, images are supported:\n\n```python\ncollection.update(\n ids=['id1', 'id2', 'id3'],\n images=[...] # A list of numpy arrays representing images\n)\n```\n\nNote that a given entry with a specific ID can only have one associated modality at a time. Updates will over-write the existing modality, so for example, an entry which originally has corresponding text and updated with an image, will no longer have that text after an update with images.\n", - "bee959ea-60dd-4d81-93b2-e5e2f56e3093": "\n\n### Framework Integrations\n\nChroma maintains integrations with many popular tools. These tools can be used to define the business logic of an AI-native application, curate data, fine-tune embedding spaces and more.\n\nWe welcome pull requests to add new Integrations to the community.\n\n{% special_table %}\n{% /special_table %}\n\n| | Python | JS |\n| --------------------------------------- | ------ | ------------ |\n| [DeepEval](./frameworks/deepeval) | \u2713 | - |\n| [Langchain](./frameworks/langchain) | \u2713 | \u2713 |\n| [LlamaIndex](./frameworks/llamaindex) | \u2713 | \u2713 |\n| [Braintrust](./frameworks/braintrust) | \u2713 | \u2713 |\n| [OpenLLMetry](./frameworks/openllmetry) | \u2713 | Coming Soon! |\n| [Streamlit](./frameworks/streamlit) | \u2713 | - |\n| [Haystack](./frameworks/haystack) | \u2713 | - |\n| [OpenLIT](./frameworks/openlit) | \u2713 | Coming Soon! |\n| [", - "b3f09f7d-8a32-4a7b-9b00-3ebce7a2e998": "Anthropic MCP](./frameworks/anthropic-mcp) | \u2713 | Coming Soon! |\n\n---\nid: 'cohere'\nname: 'Cohere'\n---\n\n# Cohere\n\nChroma also provides a convenient wrapper around Cohere's embedding API. This embedding function runs remotely on Cohere\u2019s servers, and requires an API key. You can get an API key by signing up for an account at [Cohere](https://dashboard.cohere.ai/welcome/register).\n\n{% Tabs %}\n{% Tab label=\"python\" %}\n\nThis embedding function relies on the `cohere` python package, which you can install with `pip install cohere`.\n\n```python\nimport chromadb.utils.embedding_functions as embedding_functions\ncohere_ef = embedding_functions.CohereEmbeddingFunction(api_key=\"YOUR_API_KEY\", model_name=\"large\")\ncohere_ef(input=[\"document1\",\"document2\"])\n```\n\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n\n```typescript\nimport { CohereEmbeddingFunction } from 'chromadb';\n\nconst embedder = new CohereEmbeddingFunction(\"apiKey\")\n\n// use directly\nconst embeddings = embedder.generate([\"document1\",\"document2\"])\n\n// pass documents to query for", - "a13ea680-48f9-49c5-809b-a944d87a11aa": " .add and .query\nconst collection = await client.createCollection({name: \"name\", embeddingFunction: embedder})\nconst collectionGet = await client.getCollection({name:\"name\", embeddingFunction: embedder})\n```\n\n{% /Tab %}\n\n{% /Tabs %}\n\nYou can pass in an optional `model_name` argument, which lets you choose which Cohere embeddings model to use. By default, Chroma uses `large` model. You can see the available models under `Get embeddings` section [here](https://docs.cohere.ai/reference/embed).\n\n### Multilingual model example\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n\n```python\ncohere_ef = embedding_functions.CohereEmbeddingFunction(\n api_key=\"YOUR_API_KEY\",\n model_name=\"multilingual-22-12\")\n\nmultilingual_texts = [ 'Hello from Cohere!', '\u0645\u0631\u062d\u0628\u064b\u0627 \u0645\u0646 \u0643\u0648\u0647\u064a\u0631!',\n 'Hallo von Cohere!', 'Bonjour de Cohere!',\n '\u00a1Hola desde Cohere!', 'Ol\u00e1 do Cohere!',\n 'Ciao da Cohere!', '\u60a8\u597d\uff0c\u6765\u81ea Cohere\uff01',\n '\u0915\u094b\u0939", - "e4e9f6d7-2f12-4b79-af87-9e9f3e8d42a7": "\u093f\u0905\u0930 \u0938\u0947 \u0928\u092e\u0938\u094d\u0924\u0947!' ]\n\ncohere_ef(input=multilingual_texts)\n\n```\n\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n\n```typescript\nimport { CohereEmbeddingFunction } from 'chromadb';\n\nconst embedder = new CohereEmbeddingFunction(\"apiKey\")\n\nmultilingual_texts = [ 'Hello from Cohere!', '\u0645\u0631\u062d\u0628\u064b\u0627 \u0645\u0646 \u0643\u0648\u0647\u064a\u0631!',\n 'Hallo von Cohere!', 'Bonjour de Cohere!',\n '\u00a1Hola desde Cohere!', 'Ol\u00e1 do Cohere!',\n 'Ciao da Cohere!', '\u60a8\u597d\uff0c\u6765\u81ea Cohere\uff01',\n '\u0915\u094b\u0939\u093f\u0905\u0930 \u0938\u0947 \u0928\u092e\u0938\u094d\u0924\u0947!' ]\n\nconst embeddings = embedder.generate(multilingual_texts)\n\n```\n\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nFor more information on multilingual model you can read [here](https://docs.cohere.ai/docs/multilingual-language-models).\n\n---\nid: google-gemini\nname: \"Google Gemini\"\n---\n\n# Google Gemini\n\nChroma provides a convenient wrapper around Google's Generative AI embedding API. This embedding", - "6ab6b522-8557-4225-b7bf-9a5c94a3c55a": " function runs remotely on Google's servers, and requires an API key.\n\nYou can get an API key by signing up for an account at [Google MakerSuite](https://makersuite.google.com/).\n\n{% Tabs %}\n\n{% Tab label=\"python\" %}\n\nThis embedding function relies on the `google-generativeai` python package, which you can install with `pip install google-generativeai`.\n\n```python\n# import\nimport chromadb.utils.embedding_functions as embedding_functions\n\n# use directly\ngoogle_ef = embedding_functions.GoogleGenerativeAiEmbeddingFunction(api_key=\"YOUR_API_KEY\")\ngoogle_ef([\"document1\",\"document2\"])\n\n# pass documents to query for .add and .query\ncollection = client.create_collection(name=\"name\", embedding_function=google_ef)\ncollection = client.get_collection(name=\"name\", embedding_function=google_ef)\n```\n\nYou can view a more [complete example](https://github.com/chroma-core/chroma/tree/main/examples/gemini) chatting over documents with Gemini embedding and langauge models.\n\nFor more info - please visit the [official Google python docs](https://ai.google.dev/tutorials/python_quickstart).\n\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n\nThis embedding function relies", - "97331935-c3c2-480a-ad00-2528a711ec2f": " on the `@google/generative-ai` npm package, which you can install with e.g. `npm install @google/generative-ai`.\n\n```typescript\nimport { ChromaClient, GoogleGenerativeAiEmbeddingFunction } from \"chromadb\";\nconst embedder = new GoogleGenerativeAiEmbeddingFunction({\n googleApiKey: \"\",\n});\n\n// use directly\nconst embeddings = await embedder.generate([\"document1\", \"document2\"]);\n\n// pass documents to query for .add and .query\nconst collection = await client.createCollection({\n name: \"name\",\n embeddingFunction: embedder,\n});\nconst collectionGet = await client.getCollection({\n name: \"name\",\n embeddingFunction: embedder,\n});\n```\n\nYou can view a more [complete example using Node](https://github.com/chroma-core/chroma/blob/main/clients/js/examples/node/app.js).\n\nFor more info - please visit the [official Google JS docs](https://ai.google.dev/tutorials/node_quickstart).\n\n{% /Tab %}\n\n{% /Tabs %}\n\n---\nid: hugging-face-server\nname: 'Hugging Face Server'\n---\n\n# Hugging Face Server\n\nChroma provides a convenient wrapper for Hugging", - "df4e7fb5-5a08-4199-b424-528cb4b5c338": "Face Text Embedding Server, a standalone server that provides text embeddings via a REST API. You can read more about it [**here**](https://github.com/huggingface/text-embeddings-inference).\n\n## Setting Up The Server\n\nTo run the embedding server locally you can run the following command from the root of the Chroma repository. The docker compose command will run Chroma and the embedding server together.\n\n```terminal\ndocker compose -f examples/server_side_embeddings/huggingface/docker-compose.yml up -d\n```\n\nor\n\n```terminal\ndocker run -p 8001:80 -d -rm --name huggingface-embedding-server ghcr.io/huggingface/text-embeddings-inference:cpu-0.3.0 --model-id BAAI/bge-small-en-v1.5 --revision -main\n```\n\n{% Banner type=\"note\" %}\nThe above docker command will run the server with the `BAAI/bge-small-en-v1.5` model. You can find more information about running the server in docker [**here**](https://github.com/huggingface/text-embeddings-inference#docker).\n{% /Banner %}\n\n## Usage\n\n{% TabbedCode", - "cf53149b-6ba8-4d81-a77a-4ee713da83e2": "Block %}\n\n{% Tab label=\"python\" %}\n\n```python\nfrom chromadb.utils.embedding_functions import HuggingFaceEmbeddingServer\nhuggingface_ef = HuggingFaceEmbeddingServer(url=\"http://localhost:8001/embed\")\n```\n\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n\n\n```typescript\nimport {HuggingFaceEmbeddingServerFunction} from 'chromadb';\nconst embedder = new HuggingFaceEmbeddingServerFunction({url:\"http://localhost:8001/embed\"})\n\n// use directly\nconst embeddings = embedder.generate([\"document1\",\"document2\"])\n\n// pass documents to query for .add and .query\nlet collection = await client.createCollection({name: \"name\", embeddingFunction: embedder})\ncollection = await client.getCollection({name: \"name\", embeddingFunction: embedder})\n```\n\n{% /Tab %}\n{% /TabbedCodeBlock %}\n\nThe embedding model is configured on the server side. Check the docker-compose file in `examples/server_side_embeddings/huggingface/docker-compose.yml` for an example of how to configure the server.\n\n---\nid: hugging-face\nname: Hugging Face\n---\n\n# Hugging Face\n\nChroma also provides a convenient", - "8629d0ec-3284-4eb0-8cd4-a0bb40e7da6c": " wrapper around HuggingFace's embedding API. This embedding function runs remotely on HuggingFace's servers, and requires an API key. You can get an API key by signing up for an account at [HuggingFace](https://huggingface.co/).\n\n{% tabs group=\"code-lang\" hideTabs=true %}\n{% tab label=\"Python\" %}\n\n```python\nimport chromadb.utils.embedding_functions as embedding_functions\nhuggingface_ef = embedding_functions.HuggingFaceEmbeddingFunction(\n api_key=\"YOUR_API_KEY\",\n model_name=\"sentence-transformers/all-MiniLM-L6-v2\"\n)\n```\n\nYou can pass in an optional `model_name` argument, which lets you choose which HuggingFace model to use. By default, Chroma uses `sentence-transformers/all-MiniLM-L6-v2`. You can see a list of all available models [here](https://huggingface.co/models).\n\n---\nid: instructor\nname: Instructor\n---\n\n# Instructor\n\nThe [instructor-embeddings](https://github.com/HKUNLP/instructor-embedding) library is another option, especially when running on a machine with a cuda-capable GPU. They are a good local alternative to OpenAI", - "27a5fd08-b44b-472c-bd62-8d89a6616329": " (see the [Massive Text Embedding Benchmark](https://huggingface.co/blog/mteb) rankings). The embedding function requires the InstructorEmbedding package. To install it, run ```pip install InstructorEmbedding```.\n\nThere are three models available. The default is `hkunlp/instructor-base`, and for better performance you can use `hkunlp/instructor-large` or `hkunlp/instructor-xl`. You can also specify whether to use `cpu` (default) or `cuda`. For example:\n\n```python\n#uses base model and cpu\nimport chromadb.utils.embedding_functions as embedding_functions\nef = embedding_functions.InstructorEmbeddingFunction()\n```\nor\n```python\nimport chromadb.utils.embedding_functions as embedding_functions\nef = embedding_functions.InstructorEmbeddingFunction(\nmodel_name=\"hkunlp/instructor-xl\", device=\"cuda\")\n```\nKeep in mind that the large and xl models are 1.5GB and 5GB respectively, and are best suited to running on a GPU.\n\n---\nid: jina-ai\nname: Jina AI\n---\n\n# JinaAI\n\nChroma provides a convenient wrapper around JinaAI's embedding API. This embedding function", - "957f6f4b-11e3-4933-aca8-3749aea1c3ef": " runs remotely on JinaAI's servers, and requires an API key. You can get an API key by signing up for an account at [JinaAI](https://jina.ai/embeddings/).\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n\n```python\nimport chromadb.utils.embedding_functions as embedding_functions\njinaai_ef = embedding_functions.JinaEmbeddingFunction(\n api_key=\"YOUR_API_KEY\",\n model_name=\"jina-embeddings-v2-base-en\"\n )\njinaai_ef(input=[\"This is my first text to embed\", \"This is my second document\"])\n```\n\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n\n```typescript\nimport { JinaEmbeddingFunction } from 'chromadb';\n\nconst embedder = new JinaEmbeddingFunction({\n jinaai_api_key: 'jina_****',\n model_name: 'jina-embeddings-v2-base-en',\n});\n\n// use directly\nconst embeddings = embedder.generate(['document1', 'document2']);\n\n// pass documents to query for .add and .query\nconst collection = await client.createCollection({name: \"name\", embeddingFunction: embedder})\nconst collection", - "96e4f18a-034c-489a-ae06-f3bf97b38bbe": "Get = await client.getCollection({name:\"name\", embeddingFunction: embedder})\n```\n\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nYou can pass in an optional `model_name` argument, which lets you choose which Jina model to use. By default, Chroma uses `jina-embedding-v2-base-en`.\n\n---\nid: ollama\nname: Ollama\n---\n\n# Ollama\n\nChroma provides a convenient wrapper around [Ollama](https://github.com/ollama/ollama)'\ns [embeddings API](https://github.com/ollama/ollama/blob/main/docs/api.md#generate-embeddings). You can use\nthe `OllamaEmbeddingFunction` embedding function to generate embeddings for your documents with\na [model](https://github.com/ollama/ollama?tab=readme-ov-file#model-library) of your choice.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n\n```python\nfrom chromadb.utils.embedding_functions.ollama_embedding_function import (\n OllamaEmbeddingFunction,\n)\n\nollama_ef = OllamaEmbeddingFunction(\n url=\"http://localhost", - "a947038e-a485-407f-8dbb-8a0788670c40": ":11434\",\n model_name=\"llama2\",\n)\n\nembeddings = ollama_ef([\"This is my first text to embed\",\n \"This is my second document\"])\n```\n\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n\n```typescript\nimport { OllamaEmbeddingFunction } from \"chromadb\";\nconst embedder = new OllamaEmbeddingFunction({\n url: \"http://127.0.0.1:11434/\",\n model: \"llama2\"\n})\n\n// use directly\nconst embeddings = embedder.generate([\"document1\", \"document2\"])\n\n// pass documents to query for .add and .query\nlet collection = await client.createCollection({\n name: \"name\",\n embeddingFunction: embedder\n})\ncollection = await client.getCollection({\n name: \"name\",\n embeddingFunction: embedder\n})\n```\n\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n---\nid: 'roboflow'\nname: Roboflow\n---\n\n# Roboflow\n\nYou can use [Roboflow Inference](https://inference.roboflow.com) with Chroma to calculate multi-modal text and image embeddings with CLIP. through", - "8b8647b7-6b4e-44cb-a14e-d5d01b624b4f": " the `RoboflowEmbeddingFunction` class. Inference can be used through the Roboflow cloud, or run on your hardware.\n\n## Roboflow Cloud Inference\n\nTo run Inference through the Roboflow cloud, you will need an API key. [Learn how to retrieve a Roboflow API key](https://docs.roboflow.com/api-reference/authentication#retrieve-an-api-key).\n\nYou can pass it directly on creation of the `RoboflowEmbeddingFunction`:\n\n```python\nfrom chromadb.utils.embedding_functions import RoboflowEmbeddingFunction\n\nroboflow_ef = RoboflowEmbeddingFunction(api_key=API_KEY)\n```\n\nAlternatively, you can set your API key as an environment variable:\n\n```terminal\nexport ROBOFLOW_API_KEY=YOUR_API_KEY\n```\n\nThen, you can create the `RoboflowEmbeddingFunction` without passing an API key directly:\n\n```python\nfrom chromadb.utils.embedding_functions import RoboflowEmbeddingFunction\n\nroboflow_ef = RoboflowEmbeddingFunction()\n```\n\n## Local Inference\n\nYou can run Inference on your own hardware.\n\nTo install Inference, you will need Docker installed. Follow the [official Docker installation", - "d748be5c-4041-4c2e-abef-e3270f1b9ead": " instructions](https://docs.docker.com/engine/install/) for guidance on how to install Docker on the device on which you are working.\n\nThen, you can install Inference with pip:\n\n```terminal\npip install inference inference-cli\n```\n\nWith Inference installed, you can start an Inference server. This server will run in the background. The server will accept HTTP requests from the `RoboflowEmbeddingFunction` to calculate CLIP text and image embeddings for use in your application:\n\nTo start an Inference server, run:\n\n```terminal\ninference server start\n```\n\nYour Inference server will run at `http://localhost:9001`.\n\nThen, you can create the `RoboflowEmbeddingFunction`:\n\n```python\nfrom chromadb.utils.embedding_functions import RoboflowEmbeddingFunction\n\nroboflow_ef = RoboflowEmbeddingFunction(api_key=API_KEY, server_url=\"http://localhost:9001\")\n```\n\nThis function will calculate embeddings using your local Inference server instead of the Roboflow cloud.\n\nFor a full tutorial on using Roboflow Inference with Chroma, refer to the [Roboflow Chroma integration tutorial](https://github.com/chroma-core/chroma/blob/main", - "24212bb5-8d77-455f-addf-1652a1adcc4e": "/examples/use_with/roboflow/embeddings.ipynb).\n\n---\nid: 'voyageai'\nname: 'VoyageAI'\n---\n\n# VoyageAI\n\nChroma also provides a convenient wrapper around VoyageAI's embedding API. This embedding function runs remotely on VoyageAI\u2019s servers, and requires an API key. You can get an API key by signing up for an account at [VoyageAI](https://dash.voyageai.com/).\n\n{% Tabs %}\n{% Tab label=\"python\" %}\n\nThis embedding function relies on the `voyageai` python package, which you can install with `pip install voyageai`.\n\n```python\nimport chromadb.utils.embedding_functions as embedding_functions\nvoyageai_ef = embedding_functions.VoyageAIEmbeddingFunction(api_key=\"YOUR_API_KEY\", model_name=\"voyage-3-large\")\nvoyageai_ef(input=[\"document1\",\"document2\"])\n```\n\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n\n```typescript\nimport { VoyageAIEmbeddingFunction } from 'chromadb';\n\nconst embedder = new VoyageAIEmbeddingFunction(\"apiKey\", \"model_name\")\n\n// use directly\nconst embeddings = embedder.generate([\"document1\",\"document", - "44524bf2-cc15-41dd-b52a-e8d8ee2899e8": "2\"])\n\n// pass documents to query for .add and .query\nconst collection = await client.createCollection({name: \"name\", embeddingFunction: embedder})\nconst collectionGet = await client.getCollection({name: \"name\", embeddingFunction: embedder})\n```\n\n{% /Tab %}\n\n{% /Tabs %}\n\n### Multilingual model example\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n\n```python\nvoyageai_ef = embedding_functions.VoyageAIEmbeddingFunction(\n api_key=\"YOUR_API_KEY\",\n model_name=\"voyage-3-large\")\n\nmultilingual_texts = [ 'Hello from VoyageAI!', '\u0645\u0631\u062d\u0628\u0627\u064b \u0645\u0646 VoyageAI!!',\n 'Hallo von VoyageAI!', 'Bonjour de VoyageAI!',\n '\u00a1Hola desde VoyageAI!', 'Ol\u00e1 do VoyageAI!',\n 'Ciao da VoyageAI!', '\u60a8\u597d\uff0c\u6765\u81ea VoyageAI\uff01',\n '\u0915\u094b\u0939\u093f\u0905\u0930 \u0938\u0947 VoyageAI!' ]\n\nvoyageai_ef(input=multilingual_texts)\n\n```\n\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n\n```typescript\nimport { VoyageAIEmbeddingFunction } from 'chromadb';\n\n", - "b26597ba-cb71-44b6-9fe0-cf6235d9aaab": "const embedder = new VoyageAIEmbeddingFunction(\"apiKey\", \"voyage-3-large\")\n\nmultilingual_texts = [ 'Hello from VoyageAI!', '\u0645\u0631\u062d\u0628\u0627\u064b \u0645\u0646 VoyageAI!!',\n 'Hallo von VoyageAI!', 'Bonjour de VoyageAI!',\n '\u00a1Hola desde VoyageAI!', 'Ol\u00e1 do VoyageAI!',\n 'Ciao da VoyageAI!', '\u60a8\u597d\uff0c\u6765\u81ea VoyageAI\uff01',\n '\u0915\u094b\u0939\u093f\u0905\u0930 \u0938\u0947 VoyageAI!' ]\n\nconst embeddings = embedder.generate(multilingual_texts)\n\n```\n\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nFor further details on VoyageAI's models check the [documentation](https://docs.voyageai.com/docs/introduction) and the [blogs](https://blog.voyageai.com/).\n\n---\nid: anthropic-mcp\nname: Anthropic MCP\n---\n\n# Anthropic MCP Integration\n\n## What is MCP?\n\nThe Model Context Protocol (MCP) is an open protocol that standardizes how AI applications communicate with data sources and tools. Think of MCP like a USB-C port for AI applications - it provides a universal way to connect AI models like Claude to different services and", - "5216ebcb-157d-42a2-8d29-a44f7207e4af": " data sources.\n\nMCP follows a client-server architecture:\n- **MCP Hosts**: Applications like Claude Desktop that want to access data through MCP\n- **MCP Clients**: Protocol clients that maintain connections with servers\n- **MCP Servers**: Lightweight programs that expose specific capabilities (like Chroma's vector database)\n- **Data Sources**: Your local or remote data that MCP servers can securely access\n\n## What is the Chroma MCP Server?\n\nThe Chroma MCP server allows Claude to directly interact with Chroma's vector database capabilities through this standardized protocol. This enables powerful features like:\n\n- Persistent memory across conversations\n- Semantic search through previous chats\n- Document management and retrieval\n- Vector and keyword search capabilities\n- Metadata management and filtering\n\n## Prerequisites\n\nBefore setting up the Chroma MCP server, ensure you have:\n\n1. Claude Desktop installed (Windows or macOS)\n2. Python 3.10+ installed\n3. `uvx` installed (`curl -LsSf https://astral.sh/uv/install.sh | sh`)\n\n## Setup Guide\n\n### 1. Configure MCP Server\n\n1. Open Claude Desktop\n2. Click on the Claude menu and select \"Settings...\"\n![mcp-settings](/", - "4d89aa54-808c-4784-9997-b87ac7bf8787": "mcp-settings.png)\n3. Click on \"Developer\" in the left sidebar\n![mcp-developer](/mcp-developer.png)\n4. Click \"Edit Config\" to open your configuration file\n\nAdd the following configuration:\n\n```json\n{\n \"mcpServers\": {\n \"chroma\": {\n \"command\": \"uvx\",\n \"args\": [\n \"chroma-mcp\",\n \"--client-type\",\n \"persistent\",\n \"--data-dir\",\n \"/path/to/your/data/directory\"\n ]\n }\n }\n}\n```\n\nReplace `/path/to/your/data/directory` with where you want Chroma to store its data, for example:\n- macOS: `/Users/username/Documents/chroma-data`\n- Windows: `C:\\\\Users\\\\username\\\\Documents\\\\chroma-data`\n\n### 2. Restart and Verify\n\n1. Restart Claude Desktop completely\n2. Look for the hammer \ud83d\udd28 icon in the bottom right of your chat input\n![mcp-hammer](/mcp-hammer.png)\n3. Click it to see available Chroma tools\n![mcp-tools](/mcp-tools.png)\n\nIf you don't see the tools, check the logs at", - "e3c81a62-54d9-49cf-ada2-49ce40f484f7": ":\n- macOS: `~/Library/Logs/Claude/mcp*.log`\n- Windows: `%APPDATA%\\Claude\\logs\\mcp*.log`\n\n## Client Types\n\nThe Chroma MCP server supports multiple client types to suit different needs:\n\n### 1. Ephemeral Client (Default)\nBy default, the server will use the ephemeral client.\n```json\n{\n \"mcpServers\": {\n \"chroma\": {\n \"command\": \"uvx\",\n \"args\": [\n \"chroma-mcp\",\n ]\n }\n }\n}\n```\n- Stores data in memory only\n- Data is cleared when the server restarts\n- Useful for temporary sessions or testing\n\n### 2. Persistent Client\n```json\n{\n \"mcpServers\": {\n \"chroma\": {\n \"command\": \"uvx\",\n \"args\": [\n \"chroma-mcp\",\n \"--client-type\",\n \"persistent\",\n \"--data-dir\",\n \"/path/to/your/data/directory\"\n ]\n }\n }\n}\n```\n- Stores data persistently on your local machine\n- Data survives between restarts\n- Best for personal use and long-term memory\n\n\n", - "ba406ae3-fa12-4500-9c69-acbd0c35a481": "### 3. Self-Hosted Client\n```json\n{\n \"mcpServers\": {\n \"chroma\": {\n \"command\": \"uvx\",\n \"args\": [\n \"chroma-mcp\",\n \"--client-type\",\n \"http\",\n \"--host\",\n \"http://localhost:8000\",\n \"--port\",\n \"8000\",\n \"--custom-auth-credentials\",\n \"username:password\",\n \"--ssl\",\n \"true\"\n ]\n }\n }\n}\n```\n- Connects to your own Chroma server\n- Full control over data and infrastructure\n- Suitable for team environments\n\n### 4. Cloud Client\n```json\n{\n \"mcpServers\": {\n \"chroma\": {\n \"command\": \"uvx\",\n \"args\": [\n \"chroma-mcp\",\n \"--client-type\",\n \"cloud\",\n \"--tenant\",\n \"your-tenant-id\",\n \"--database\",\n \"your-database-name\",\n \"--api-key\",\n \"your-api-key\"\n ]\n }\n }\n}\n```\n- Connects to Chroma Cloud or other hosted instances\n- Scalable and managed infrastructure\n- Best for production", - "ef5c61f0-3b1f-4d57-ad57-573ac5012652": " deployments\n\n## Using Chroma with Claude\n\n### Team Knowledge Base Example\n\nLet's say your team maintains a knowledge base of customer support interactions. By storing these in Chroma Cloud, team members can use Claude to quickly access and learn from past support cases.\n\nFirst, set up your shared knowledge base:\n\n```python\nimport chromadb\nfrom datetime import datetime\n\n# Connect to Chroma Cloud\nclient = chromadb.HttpClient(\n ssl=True,\n host='api.trychroma.com',\n tenant='your-tenant-id',\n database='support-kb',\n headers={\n 'x-chroma-token': 'YOUR_API_KEY'\n }\n)\n\n# Create a collection for support cases\ncollection = client.create_collection(\"support_cases\")\n\n# Add some example support cases\nsupport_cases = [\n {\n \"case\": \"Customer reported issues connecting their IoT devices to the dashboard.\",\n \"resolution\": \"Guided customer through firewall configuration and port forwarding setup.\",\n \"category\": \"connectivity\",\n \"date\": \"2024-03-15\"\n },\n {\n \"case\": \"User couldn't access admin features after recent update.\",\n \"resolution\": \"Discovered role permissions weren't migrated correctly. Applied fix", - "c4666bba-41ea-4f3c-b134-49e52024b871": " and documented process.\",\n \"category\": \"permissions\",\n \"date\": \"2024-03-16\"\n }\n]\n\n# Add documents to collection\ncollection.add(\n documents=[case[\"case\"] + \"\\n\" + case[\"resolution\"] for case in support_cases],\n metadatas=[{\n \"category\": case[\"category\"],\n \"date\": case[\"date\"]\n } for case in support_cases],\n ids=[f\"case_{i}\" for i in range(len(support_cases))]\n)\n```\n\nNow team members can use Claude to access this knowledge.\n\nIn your claude config, add the following:\n```json\n{\n \"mcpServers\": {\n \"chroma\": {\n \"command\": \"uvx\",\n \"args\": [\n \"chroma-mcp\",\n \"--client-type\",\n \"cloud\",\n \"--tenant\",\n \"your-tenant-id\",\n \"--database\",\n \"support-kb\",\n \"--api-key\",\n \"YOUR_API_KEY\"\n ]\n }\n }\n}\n```\n\nNow you can use the knowledge base in your chats:\n```\nClaude, I'm having trouble helping a customer with IoT device connectivity.\nCan you check our support knowledge", - "f3fcb391-766a-4e56-b2f8-3821f869b4fd": " base for similar cases and suggest a solution?\n```\n\nClaude will:\n1. Search the shared knowledge base for relevant cases\n2. Consider the context and solutions from similar past issues\n3. Provide recommendations based on previous successful resolutions\n\nThis setup is particularly powerful because:\n- All support team members have access to the same knowledge base\n- Claude can learn from the entire team's experience\n- Solutions are standardized across the organization\n- New team members can quickly get up to speed on common issues\n\n### Project Memory Example\n\nClaude's context window has limits - long conversations eventually get truncated, and chats don't persist between sessions. Using Chroma as an external memory store solves these limitations, allowing Claude to reference past conversations and maintain context across multiple sessions.\n\nFirst, tell Claude to use Chroma for memory as part of the project setup:\n```\nRemember, you have access to Chroma tools.\nAt any point if the user references previous chats or memory, check chroma for similar conversations.\nTry to use retrieved information where possible.\n```\n\n![mcp-instructions](/mcp-instructions.png)\n\nThis prompt instructs Claude to:\n- Proactively check Chroma when memory-related topics come up\n- Search for semantically similar", - "c81fc79b-c558-4778-9448-c6bac4578929": " past conversations\n- Incorporate relevant historical context into responses\n\nTo store the current conversation:\n```\nPlease chunk our conversation into small chunks and store it in Chroma for future reference.\n```\n\nClaude will:\n1. Break the conversation into smaller chunks (typically 512-1024 tokens)\n - Chunking is necessary because:\n - Large texts are harder to search semantically\n - Smaller chunks help retrieve more precise context\n - It prevents token limits in future retrievals\n2. Generate embeddings for each chunk\n3. Add metadata like timestamps and detected topics\n4. Store everything in your Chroma collection\n\n![mcp-store](/mcp-store.png)\n\nLater, you can access past conversations naturally:\n```\nWhat did we discuss previously about the authentication system?\n```\n\nClaude will:\n1. Search Chroma for chunks semantically related to authentication\n2. Filter by timestamp metadata for last week's discussions\n3. Incorporate the relevant historical context into its response\n\n![mcp-search](/mcp-search.png)\n\nThis setup is particularly useful for:\n- Long-running projects where context gets lost\n- Teams where multiple people interact with Claude\n- Complex discussions that reference past decisions\n- Maint", - "60906e9e-fc4f-44e4-99d9-779e3a9be39d": "aining consistent context across multiple chat sessions\n\n### Advanced Features\n\nThe Chroma MCP server supports:\n\n- **Collection Management**: Create and organize separate collections for different projects\n- **Document Operations**: Add, update, or delete documents\n- **Search Capabilities**:\n - Vector similarity search\n - Keyword-based search\n - Metadata filtering\n- **Batch Processing**: Efficient handling of multiple operations\n\n## Troubleshooting\n\nIf you encounter issues:\n\n1. Verify your configuration file syntax\n2. Ensure all paths are absolute and valid\n3. Try using full paths for `uvx` with `which uvx` and using that path in the config\n4. Check the Claude logs (paths listed above)\n\n## Resources\n\n- [Model Context Protocol Documentation](https://modelcontextprotocol.io/introduction)\n- [Chroma MCP Server Documentation](https://github.com/chroma-core/chroma-mcp)\n- [Claude Desktop Guide](https://docs.anthropic.com/claude/docs/claude-desktop)\n\n\n---\nid: braintrust\nname: Braintrust\n---\n\n# Braintrust\n\n[Braintrust](https://www.braintrustdata.com) is an enterprise-grade stack for building AI products including: evaluations, prompt", - "213c54c1-f494-4bca-8998-a9d8a1b04fef": " playground, dataset management, tracing, etc.\n\nBraintrust provides a Typescript and Python library to run and log evaluations and integrates well with Chroma.\n\n- [Tutorial: Evaluate Chroma Retrieval app w/ Braintrust](https://www.braintrustdata.com/docs/examples/rag)\n\nExample evaluation script in Python:\n(refer to the tutorial above to get the full implementation)\n```python\nfrom autoevals.llm import *\nfrom braintrust import Eval\n\nPROJECT_NAME=\"Chroma_Eval\"\n\nfrom openai import OpenAI\n\nclient = OpenAI()\nleven_evaluator = LevenshteinScorer()\n\nasync def pipeline_a(input, hooks=None):\n # Get a relevant fact from Chroma\n relevant = collection.query(\n query_texts=[input],\n n_results=1,\n )\n relevant_text = ','.join(relevant[\"documents\"][0])\n prompt = \"\"\"\n You are an assistant called BT. Help the user.\n Relevant information: {relevant}\n Question: {question}\n Answer:\n \"\"\".format(question=input, relevant=relevant_text)\n messages = [{\"role\": \"system\", \"content\": prompt}]\n response = client.chat.completions.create(\n model=\"gpt-", - "1fd549fa-2214-41c6-8f99-06e51f29340e": "3.5-turbo\",\n messages=messages,\n temperature=0,\n max_tokens=100,\n )\n\n result = response.choices[0].message.content\n return result\n\n# Run an evaluation and log to Braintrust\nawait Eval(\n PROJECT_NAME,\n # define your test cases\n data = lambda:[{\"input\": \"What is my eye color?\", \"expected\": \"Brown\"}],\n # define your retrieval pipeline w/ Chroma above\n task = pipeline_a,\n # use a prebuilt scoring function or define your own :)\n scores=[leven_evaluator],\n)\n```\n\nLearn more: [docs](https://www.braintrustdata.com/docs).\n\n---\nid: deepeval\nname: DeepEval\n---\n\n# DeepEval\n\n[DeepEval](https://docs.confident-ai.com/docs/integrations-chroma) is the open-source LLM evaluation framework. It provides 20+ research-backed metrics to help you evaluate and pick the best hyperparameters for your LLM system.\n\nWhen building a RAG system, you can use DeepEval to pick the best parameters for your **Choma retriever** for optimal retrieval performance and accuracy: `n_results`, `", - "6045885f-46ac-48cd-98da-06bf5d7af59d": "distance_function`, `embedding_model`, `chunk_size`, etc.\n\n{% Banner type=\"tip\" %}\nFor more information on how to use DeepEval, see the [DeepEval docs](https://docs.confident-ai.com/docs/getting-started).\n{% /Banner %}\n\n## Getting Started\n\n### Step 1: Installation\n\n```CLI\npip install deepeval\n```\n\n### Step 2: Preparing a Test Case\n\nPrepare a query, generate a response using your RAG pipeline, and store the retrieval context from your Chroma retriever to create an `LLMTestCase` for evaluation.\n\n```python\n...\n\ndef chroma_retriever(query):\n query_embedding = model.encode(query).tolist() # Replace with your embedding model\n res = collection.query(\n query_embeddings=[query_embedding],\n n_results=3\n )\n return res[\"metadatas\"][0][0][\"text\"]\n\nquery = \"How does Chroma work?\"\nretrieval_context = search(query)\nactual_output = generate(query, retrieval_context) # Replace with your LLM function\n\ntest_case = LLMTestCase(\n input=query,\n retrieval_context=retrieval_context,\n actual_output=actual_output\n)\n", - "f9503bd0-7fb3-42c6-a034-79e9345f3a90": "```\n\n### Step 3: Evaluation\n\nDefine retriever metrics like `Contextual Precision`, `Contextual Recall`, and `Contextual Relevancy` to evaluate test cases. Recall ensures enough vectors are retrieved, while relevancy reduces noise by filtering out irrelevant ones.\n\n{% Banner type=\"tip\" %}\nBalancing recall and relevancy is key. `distance_function` and `embedding_model` affects recall, while `n_results` and `chunk_size` impact relevancy. \n{% /Banner %}\n\n```python\nfrom deepeval.metrics import (\n ContextualPrecisionMetric,\n ContextualRecallMetric,\n ContextualRelevancyMetric\n)\nfrom deepeval import evaluate\n...\n\nevaluate(\n [test_case],\n [\n ContextualPrecisionMetric(),\n ContextualRecallMetric(),\n ContextualRelevancyMetric(),\n ],\n)\n```\n\n### 4. Visualize and Optimize\n\nTo visualize evaluation results, log in to the [Confident AI (DeepEval platform)](https://www.confident-ai.com/) by running:\n\n```\ndeepeval login\n```\n\nWhen logged in, running `evaluate` will automatically send evaluation results to Confident AI, where you can visualize", - "48cd4ca7-7e91-4481-9f5d-cff6622d4554": " and analyze performance metrics, identify failing retriever hyperparameters, and optimize your Chroma retriever for better accuracy.\n\n![](https://github.com/confident-ai/deepeval/raw/main/assets/demo.gif)\n\n{% Banner type=\"tip\" %}\nTo learn more about how to use the platform, please see [this Quickstart Guide](https://docs.confident-ai.com/confident-ai/confident-ai-introduction).\n{% /Banner %}\n\n## Support\n\nFor any question or issue with integration you can reach out to the DeepEval team on [Discord](https://discord.com/invite/a3K9c8GRGt).\n\n---\nid: haystack\nname: Haystack\n---\n\n# Haystack\n\n[Haystack](https://github.com/deepset-ai/haystack) is an open-source LLM framework in Python. It provides [embedders](https://docs.haystack.deepset.ai/v2.0/docs/embedders), [generators](https://docs.haystack.deepset.ai/v2.0/docs/generators) and [rankers](https://docs.haystack.deepset.ai/v2.0/docs/rankers) via a number of LLM providers,", - "24e39261-611e-46c8-b5df-383479b184ae": " tooling for [preprocessing](https://docs.haystack.deepset.ai/v2.0/docs/preprocessors) and data preparation, connectors to a number of vector databases including Chroma and more. Haystack allows you to build custom LLM applications using both components readily available in Haystack and [custom components](https://docs.haystack.deepset.ai/v2.0/docs/custom-components). Some of the most common applications you can build with Haystack are retrieval-augmented generation pipelines (RAG), question-answering and semantic search.\n\n![](https://img.shields.io/github/stars/deepset-ai/haystack.svg?style=social&label=Star&maxAge=2400)\n\n|[Docs](https://docs.haystack.deepset.ai/v2.0/docs) | [Github](https://github.com/deepset-ai/haystack) | [Haystack Integrations](https://haystack.deepset.ai/integrations) | [Tutorials](https://haystack.deepset.ai/tutorials) |\n\nYou can use Chroma together with Haystack by installing the integration and using the `ChromaDocumentStore`\n\n### Installation\n\n```terminal\npip install chroma-h", - "fe8d26af-66c6-4fa1-a221-c65154754653": "aystack\n```\n\n### Usage\n\n- The [Chroma Integration page](https://haystack.deepset.ai/integrations/chroma-documentstore)\n- [Chroma + Haystack Example](https://colab.research.google.com/drive/1YpDetI8BRbObPDEVdfqUcwhEX9UUXP-m?usp=sharing)\n\n#### Write documents into a ChromaDocumentStore\n\n```python\nimport os\nfrom pathlib import Path\n\nfrom haystack import Pipeline\nfrom haystack.components.converters import TextFileToDocument\nfrom haystack.components.writers import DocumentWriter\nfrom chroma_haystack import ChromaDocumentStore\n\nfile_paths = [\"data\" / Path(name) for name in os.listdir(\"data\")]\n\ndocument_store = ChromaDocumentStore()\n\nindexing = Pipeline()\nindexing.add_component(\"converter\", TextFileToDocument())\nindexing.add_component(\"writer\", DocumentWriter(document_store))\n\nindexing.connect(\"converter\", \"writer\")\nindexing.run({\"converter\": {\"sources\": file_paths}})\n```\n\n#### Build RAG on top of Chroma\n\n```python\nfrom chroma_haystack.retriever import ChromaQueryRetriever\nfrom haystack.components.generators import", - "fb4394da-5b13-42a0-a17e-11227ed18e2f": " HuggingFaceTGIGenerator\nfrom haystack.components.builders import PromptBuilder\n\nprompt = \"\"\"\nAnswer the query based on the provided context.\nIf the context does not contain the answer, say 'Answer not found'.\nContext:\n{% for doc in documents %}\n {{ doc.content }}\n{% endfor %}\nquery: {{query}}\nAnswer:\n\"\"\"\nprompt_builder = PromptBuilder(template=prompt)\n\nllm = HuggingFaceTGIGenerator(model=\"mistralai/Mixtral-8x7B-Instruct-v0.1\", token='YOUR_HF_TOKEN')\nllm.warm_up()\nretriever = ChromaQueryRetriever(document_store)\n\nquerying = Pipeline()\nquerying.add_component(\"retriever\", retriever)\nquerying.add_component(\"prompt_builder\", prompt_builder)\nquerying.add_component(\"llm\", llm)\n\nquerying.connect(\"retriever.documents\", \"prompt_builder.documents\")\nquerying.connect(\"prompt_builder\", \"llm\")\n\nresults = querying.run({\"retriever\": {\"queries\": [query], \"top_k\": 3},\n \"prompt_builder\": {\"query\": query}})\n```\n\n---\nid: langchain\nname: Langchain\n---\n\n# Langchain\n\n## Langchain -", - "ce0fa44c-2d74-45d9-be31-aa5bc589f5fc": " Python\n\n- [LangChain + Chroma](https://blog.langchain.dev/langchain-chroma/) on the LangChain blog\n- [Harrison's `chroma-langchain` demo repo](https://github.com/hwchase17/chroma-langchain)\n - [question answering over documents](https://github.com/hwchase17/chroma-langchain/blob/master/qa.ipynb) - ([Replit version](https://replit.com/@swyx/LangChainChromaStarter#main.py))\n - [to use Chroma as a persistent database](https://github.com/hwchase17/chroma-langchain/blob/master/persistent-qa.ipynb)\n- Tutorials\n - [Chroma and LangChain tutorial](https://github.com/grumpyp/chroma-langchain-tutorial) - The demo showcases how to pull data from the English Wikipedia using their API. The project also demonstrates how to vectorize data in chunks and get embeddings using OpenAI embeddings model.\n - [Create a Voice-based ChatGPT Clone That Can Search on the Internet and local files](https://betterprogramming.pub/how-to-create-a-voice-based-chatgpt-clone-that-can-search-on", - "335fa782-393f-4111-9706-90c96a19f23c": "-the-internet-24d7f570ea8)\n- [LangChain's Chroma Documentation](https://python.langchain.com/docs/integrations/vectorstores/chroma)\n\n\n## Langchain - JS\n\n- [LangChainJS Chroma Documentation](https://js.langchain.com/docs/modules/indexes/vector_stores/integrations/chroma)\n\n---\nid: llamaindex\nname: LlamaIndex\n---\n\n# LlamaIndex\n\n- `LlamaIndex` [Vector Store page](https://docs.llamaindex.ai/en/stable/examples/vector_stores/ChromaIndexDemo.html)\n- [Demo](https://github.com/jerryjliu/llama_index/blob/main/docs/examples/vector_stores/ChromaIndexDemo.ipynb)\n- [Chroma Loader on Llamahub](https://llamahub.ai/l/chroma)\n\n---\nid: openlit\nname: OpenLIT\n---\n\n# OpenLIT\n\n[OpenLIT](https://github.com/openlit/openlit) is an OpenTelemetry-native LLM Application Observability tool and includes OpenTelemetry auto-instrumention for Chroma with just a single line of code helping you ensure your applications are monitored seamlessly, providing", - "8252b2c5-9835-407e-8424-baa46bfc2a7c": " critical insights to improve performance, operations and reliability.\n\nFor more information on how to use OpenLIT, see the [OpenLIT docs](https://docs.openlit.io/).\n\n## Getting Started\n\n### Step 1: Install OpenLIT\n\nOpen your command line or terminal and run:\n\n```bash\npip install openlit\n```\n\n### Step 2: Initialize OpenLIT in your Application\nIntegrating OpenLIT into LLM applications is straightforward. Start monitoring for your LLM Application with just **two lines of code**:\n\n```python\nimport openlit\n\nopenlit.init()\n```\n\nTo forward telemetry data to an HTTP OTLP endpoint, such as the OpenTelemetry Collector, set the `otlp_endpoint` parameter with the desired endpoint. Alternatively, you can configure the endpoint by setting the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable as recommended in the OpenTelemetry documentation.\n\n> \ud83d\udca1 Info: If you don't provide `otlp_endpoint` function argument or set the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable, OpenLIT directs the trace directly to your console, which can be useful during development.\nTo send telemetry to OpenTelemetry backends requiring authentication, set", - "84bafda8-31cb-40c7-a32a-18618ecaa877": " the `otlp_headers` parameter with its desired value. Alternatively, you can configure the endpoint by setting the `OTEL_EXPORTER_OTLP_HEADERS` environment variable as recommended in the OpenTelemetry documentation.\n\n### Step 3: Visualize and Optimize!\n\n![](https://github.com/openlit/.github/blob/main/profile/assets/openlit-client-1.png?raw=true)\n\nWith the LLM Observability data now being collected by OpenLIT, the next step is to visualize and analyze this data to get insights into your LLM application\u2019s performance, behavior, and identify areas of improvement.\n\nTo begin exploring your LLM Application's performance data within the OpenLIT UI, please see the [Quickstart Guide](https://docs.openlit.io/latest/quickstart).\n\nIf you want to integrate and send metrics and traces to your existing observability tools like Promethues+Jaeger, Grafana or more, refer to the [Official Documentation for OpenLIT Connections](https://docs.openlit.io/latest/connections/intro) for detailed instructions.\n\n\n## Support\n\nFor any question or issue with integration you can reach out to the OpenLIT team on [Slack](https://join.slack.com/t/openlit/shared_invite", - "bfb638d9-8fbf-4c90-89bc-fe7a0d254c3f": "/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ) or via [email](mailto:contact@openlit.io).\n\n---\nid: openLLMetry\nname: OpenLLMetry\n---\n\n# OpenLLMetry\n\n[OpenLLMetry](https://www.traceloop.com/openllmetry) provides observability for systems using Chroma. It allows tracing calls to Chroma, OpenAI, and other services.\nIt gives visibility to query and index calls as well as LLM prompts and completions.\nFor more information on how to use OpenLLMetry, see the [OpenLLMetry docs](https://www.traceloop.com/docs/openllmetry).\n\n![](/openllmetry.png)\n\n### Example\n\nInstall OpenLLMetry SDK by running:\n\n```terminal\npip install traceloop-sdk\n```\n\nThen, initialize the SDK in your application:\n\n```python\nfrom traceloop.sdk import Traceloop\n\nTraceloop.init()\n```\n\n### Configuration\n\nOpenLLMetry can be configured to send traces to any observability platform that supports OpenTelemetry - Datadog,", - "f7c0810c-7946-459e-9518-123610ec2ab7": " Honeycomb, Dynatrace, New Relic, etc. See the [OpenLLMetry docs](https://www.traceloop.com/openllmetry/provider/chroma) for more information.\n\n---\nid: streamlit\nname: Streamlit\n---\n\n# Streamlit\n\nStreamlit is an open-source Python library that makes it easy to create and share beautiful, custom web apps for machine learning and data science. In just a few minutes you can build and deploy powerful data apps.\n\n![](https://img.shields.io/github/stars/streamlit/streamlit.svg?style=social&label=Star&maxAge=2400)\n\n[Apache 2.0 License](https://github.com/streamlit/streamlit/blob/develop/LICENSE)  • [Site](https://streamlit.io/)\n\n{% special_table %}\n{% /special_table %}\n\n| Languages | Docs | Github |\n|--|--|--|\n| Python | [Docs](https://docs.streamlit.io/) | [Code](https://github.com/streamlit/streamlit)\n\n### Install\n\nInstall Streamlit: {% br %}{% /br %}\n`pip install streamlit`\n\nInstall `streamlit-chromadb-connection`, which connects your Stream", - "3872c15c-c37b-4ed9-8db1-afa801f5facc": "lit app to Chroma through [`st.connection`](https://docs.streamlit.io/1.11.0/library/api-reference/connections/st.connection): {% br %}{% /br %}\n`pip install streamlit-chromadb-connection`\n\n### Main Benefits\n\n- Easy to get started with Streamlit's straightforward syntax\n- Built-in [chatbot functionality](https://docs.streamlit.io/library/api-reference/chat)\n- Pre-built integration with Chroma via `streamlit-chromadb-connection`\n- Deploy apps for free on [Streamlit Community Cloud](https://share.streamlit.io/)\n\n### Simple Example\n\n#### Python\n\n```python\nimport streamlit as st\nfrom streamlit_chromadb_connection.chromadb_connection import ChromadbConnection\n\nconfiguration = {\n \"client\": \"PersistentClient\",\n \"path\": \"/tmp/.chroma\"\n}\n\ncollection_name = \"documents_collection\"\n\nconn = st.connection(\"chromadb\",\n type=ChromaDBConnection,\n **configuration)\ndocuments_collection_df = conn.get_collection_data(collection_name)\nst.dataframe(documents_collection_df)\n```\n\n### Resources\n\n- [Instructions for using `streamlit-chromadb-connection` to connect your Streamlit app to Chroma](", - "9ebe35ae-b85f-4a96-9eda-31b90811a91a": "https://github.com/Dev317/streamlit_chromadb_connection/blob/main/README.md)\n- [Demo app for `streamlit-chromadb-connection`](https://app-chromadbconnection-mfzxl3nzozmaxh3mrkd6zm.streamlit.app/)\n- [Streamlit's `st.connection` documentation](https://docs.streamlit.io/library/api-reference/connections/st.connection)\n- [Guide to using vector databases with Streamlit](https://pub.towardsai.net/vector-databases-for-your-streamlit-ai-apps-56cd0af7bbba)\n\n#### Tutorials\n\n- [Build an \"Ask the Doc\" app using Chroma, Streamlit, and LangChain](https://blog.streamlit.io/langchain-tutorial-4-build-an-ask-the-doc-app/)\n- [Summarize documents with Chroma, Streamlit, and LangChain](https://alphasec.io/summarize-documents-with-langchain-and-chroma/)\n- [Build a custom chatbot with Chroma, Streamlit, and LangChain](https://blog.streamlit.io/how-in-app-feedback-can-increase-your-chatbots-performance/)\n- [Build a RAG bot using Chroma, Streamlit", - "3e7969be-bd70-4a48-aa6d-69fc54311d9e": ", and LangChain](https://levelup.gitconnected.com/building-a-generative-ai-app-with-streamlit-and-openai-95ec31fe8efd)\n- [Build a PDF QA chatbot with Chroma, Streamlit, and OpenAI](https://www.confident-ai.com/blog/how-to-build-a-pdf-qa-chatbot-using-openai-and-chromadb)\n\n", - "edad6320-29db-4310-9a25-9f3a12753780": "# Migration\n\nSchema and data format changes are a necessary evil of evolving software. We take changes seriously and make them infrequently and only when necessary.\n\nChroma's commitment is whenever schema or data format change, we will provide a seamless and easy-to-use migration tool to move to the new schema/format.\n\nSpecifically we will announce schema changes on:\n\n- Discord ([#migrations channel](https://discord.com/channels/1073293645303795742/1129286514845691975))\n- Github ([here](https://github.com/chroma-core/chroma/issues))\n- Email listserv [Sign up](https://airtable.com/shrHaErIs1j9F97BE)\n\nWe will aim to provide:\n\n- a description of the change and the rationale for the change.\n- a CLI migration tool you can run\n- a video walkthrough of using the tool\n\n## Migration Log\n\n### v1.0.0\n\nIn this release, we've rewritten much of Chroma in Rust. Performance has significantly improved across the board.\n\n**Breaking changes**\n\nChroma no longer provides built-in authentication implementations.\n\n**Chroma in-process changes**\n\nThis section is applicable to you if you use Chroma via\n\n```python\n", - "a260b545-cafb-4cdc-86ee-ca7103ff0db9": "import chromadb\n\nclient = chromadb.Client()\n# or\nclient = chromadb.EphemeralClient()\n# or\nclient = chromadb.PersistentClient()\n```\n\nThe new Rust implementation ignores these settings:\n\n- `chroma_server_nofile`\n- `chroma_server_thread_pool_size`\n- `chroma_memory_limit_bytes`\n- `chroma_segment_cache_policy`\n\n**Chroma CLI changes**\n\nThis section is applicable to you if you run a Chroma server using the CLI (`chroma run`).\n\nSettings that you may have previously provided to the server using environment variables, like `CHROMA_SERVER_CORS_ALLOW_ORIGINS` or `CHROMA_OTEL_COLLECTION_ENDPOINT`, are now provided using a configuration file. For example:\n\n```terminal\nchroma run --config ./config.yaml\n```\n\nCheck out a full sample configuration file [here](https://github.com/chroma-core/chroma/blob/main/rust/frontend/sample_configs/single_node_full.yaml).\n\n\n**Chroma in Docker changes**\n\nThis section is applicable to you if you run Chroma using a Docker container.\n\nSettings that you previously provided to the container using environment variables, like `CHROMA_SERVER_CORS_ALLOW_ORIGINS` or `CHROMA_OT", - "5a4fcd4a-b1bb-4d9f-afa3-e1bfb2b2da9b": "EL_COLLECTION_ENDPOINT`, are now provided to the container using a configuration file. See the [Docker documentation](../production/containers/docker#configuration) for more information.\n\nThe default data location in the container has changed from `/chroma/chroma` to `/data`. For example, if you previously started the container with:\n\n```terminal\ndocker run -p 8000:8000 -v ./chroma:/chroma/chroma chroma-core/chroma\n```\n\nyou should now start it with:\n\n```terminal\ndocker run -p 8000:8000 -v ./chroma:/data chroma-core/chroma\n```\n\n\n### v0.6.0\n\nPreviously, `list_collections` returned a list of `Collection` objects. This could lead to some errors if any of your collections were created with a custom embedding function (i.e. not the default). So moving forward, `list_collections` will only return collections names.\n\nFor example, if you created all your collections with the `OpenAIEmbeddingFunction` , this is how you will use `list_collections` and `get_collection` correctly:\n\n```python\ncollection_names = client.list_collections()\nef = OpenAIEmbeddingFunction(...)\ncollections =", - "579df900-4665-4ef2-97b1-b4810743c085": " [\n\tclient.get_collection(name=name, embedding_function=ef)\n\tfor name in collection_names\n]\n```\n\nIn the future, we plan on supporting embedding function persistence, so `list_collections` can return properly configured `Collection` objects, and you won\u2019t need to supply the correct embedding function to `get_collection`.\n\nAdditionally, we have dropped support for Python 3.8\n\n### v0.5.17\n\nWe no longer support sending empty lists or dictionaries for metadata filtering, ID filtering, etc. For example,\n\n```python\ncollection.get(\n\tids=[\"id1\", \"id2\", \"id3\", ...],\n\twhere={}\n)\n```\n\nis not supported. Instead, use:\n\n```python\ncollection.get(ids=[\"id1\", \"id2\", \"id3\", ...])\n```\n\n### v0.5.12\n\nThe operators `$ne` (not equal) and `$nin` (not in) in `where` clauses have been updated:\n* Previously: They only matched records that had the specified key.\n* Now: They also match records that don't have the specified key at all.\n\nIn other words, `$ne` and `$nin` now match the complement set of records (the exact opposite) that", - "a852f5d6-597b-435e-85df-d7633d154682": " `$eq` (equals) and `$in` (in) would match, respectively.\n\nThe `$not_contains` operator in the `where_document` clause has also been updated:\n* Previously: It only matched records that had a document field.\n* Now: It also matches records that don't have a document field at all.\n\nIn other words, `$not_contains` now matches the exact opposite set of records that `$contains` would match.\n\n`RateLimitingProvider` is now deprecated and replaced by `RateLimitEnforcer`. This new interface allows you to wrap server calls with rate limiting logic. The default `SimpleRateLimitEnforcer` implementation allows all requests, but you can create custom implementations for more advanced rate limiting strategies.\n### v0.5.11\n\nThe results returned by `collection.get()` is now ordered by internal ids. Whereas previously, the results were ordered by user provided ids, although this behavior was not explicitly documented. We would like to make the change because using user provided ids may not be ideal for performance in hosted Chroma, and we hope to propagate the change to local Chroma for consistency of behavior. In general, newer documents in Chroma has larger internal ids.\n\nA subsequent change in behavior is `", - "aa8f5324-f1c9-4b52-8cc6-3cf717d57907": "limit` and `offset`, which depends on the order of returned results. For example, if you have a collection named `coll` of documents with ids `[\"3\", \"2\", \"1\", \"0\"]` inserted in this order, then previously `coll.get(limit=2, offset=2)[\"ids\"]` gives you `[\"2\", \"3\"]`, while currently this will give you `[\"1\", \"0\"]`.\n\nWe have also modified the behavior of `client.get_or_create`. Previously, if a collection already existed and the `metadata` argument was provided, the existing collection's metadata would be overwritten with the new values. This has now changed. If the collection already exists, get_or_create will simply return the existing collection with the specified name, and any additional arguments\u2014including `metadata`\u2014will be ignored.\n\nFinally, the embeddings returned from `collection.get()`, `collection.query()`, and `collection.peek()` are now represented as 2-dimensional NumPy arrays instead of Python lists. When adding embeddings, you can still use either a Python list or a NumPy array. If your request returns multiple embeddings, the result will be a Python list containing 2-dimensional NumPy arrays. This change is part", - "3b3f9ddd-a500-41c6-a04c-3f603401c3c3": " of our effort to enhance performance in Local Chroma by using NumPy arrays for internal representation of embeddings.\n\n### v0.5.6\n\nChroma internally uses a write-ahead log. In all versions prior to v0.5.6, this log was never pruned. This resulted in the data directory being much larger than it needed to be, as well as the directory size not decreasing by the expected amount after deleting a collection.\n\nIn v0.5.6 the write-ahead log is pruned automatically. However, this is not enabled by default for existing databases. After upgrading, you should run `chroma utils vacuum` once to reduce your database size and enable continuous pruning. See the [CLI reference](/reference/cli#vacuuming) for more details.\n\nThis does not need to be run regularly and does not need to be run on new databases created with v0.5.6 or later.\n\n### v0.5.1\n\nOn the Python client, the `max_batch_size` property was removed. It wasn't previously documented, but if you were reading it, you should now use `get_max_batch_size()`.\n\nThe first time this is run, it makes a HTTP request. We made this", - "cf57fea2-9b57-497c-a374-acacfb30e669": " a method to make it more clear that it's potentially a blocking operation.\n\n### Auth overhaul - April 20, 2024\n\n**If you are not using Chroma's [built-in auth system](https://docs.trychroma.com/deployment/auth), you do not need to take any action.**\n\nThis release overhauls and simplifies our authentication and authorization systems.\nIf you are you using Chroma's built-in auth system, you will need to update your configuration and\nany code you wrote to implement your own authentication or authorization providers.\nThis change is mostly to pay down some of Chroma's technical debt and make future changes easier,\nbut it also changes and simplifies user configuration.\nIf you are not using Chroma's built-in auth system, you do not need to take any action.\n\nPreviously, Chroma's authentication and authorization relied on many objects with many configuration options, including:\n\n- `chroma_server_auth_provider`\n- `chroma_server_auth_configuration_provider`\n- `chroma_server_auth_credentials_provider`\n- `chroma_client_auth_credentials_provider`\n- `chroma_client_auth_protocol_adapter`\n\nand others.\n\nWe have consolidated these into three classes:\n\n- `ClientAuthProvider`\n- `ServerAuthenticationProvider`\n-", - "3410b4a9-aa3c-4f33-bbdc-f129d6e19658": " `ServerAuthorizationProvider`\n\n`ClientAuthProvider`s are now responsible for their own configuration and credential management. Credentials can be given to them with the `chroma_client_auth_credentials` setting. The value for `chroma_client_auth_credentials` depends on the `ServerAuthenticationProvider`; for `TokenAuthenticationServerProvider` it should just be the token, and for `BasicAuthenticationServerProvider` it should be `username:password`.\n\n`ServerAuthenticationProvider`s are responsible for turning a request's authorization information into a `UserIdentity` containing any information necessary to make an authorization decision. They are now responsible for their own configuration and credential management. Configured via the `chroma_server_authn_credentials` and `chroma_server_authn_credentials_file` settings.\n\n`ServerAuthorizationProvider`s are responsible for turning information about the request and the `UserIdentity` which issued the request into an authorization decision. Configured via the `chroma_server_authz_config` and `chroma_server_authz_config_file` settings.\n\n_Either `_authn_credentials` or `authn_credentials_file` can be set, never both. Same for `authz_config` and `authz_config_file`. The value of the config (or data in the config file", - "fd932b28-8294-4c18-9d1c-112fe17fc909": ") will depend on your authn and authz providers. See [here](https://github.com/chroma-core/chroma/tree/main/examples/basic_functionality/authz) for more information._\n\nThe two auth systems Chroma ships with are `Basic` and `Token`. We have a small migration guide for each.\n\n#### Basic\n\nIf you're using `Token` auth, your server configuration might look like:\n\n```yaml\nCHROMA_SERVER_AUTH_CREDENTIALS=\"admin:admin\"\nCHROMA_SERVER_AUTH_CREDENTIALS_FILE=\"./example_file\"\nCHROMA_SERVER_AUTH_CREDENTIALS_PROVIDER=\"chromadb.auth.providers.HtpasswdConfigurationServerAuthCredentialsProvider\"\nCHROMA_SERVER_AUTH_PROVIDER=\"chromadb.auth.basic.BasicAuthServerProvider\"\n```\n\n_Note: Only one of `AUTH_CREDENTIALS` and `AUTH_CREDENTIALS_FILE` can be set, but this guide shows how to migrate both._\n\nAnd your corresponding client configation:\n\n```yaml\nCHROMA_CLIENT_AUTH_PROVIDER=\"chromadb.auth.token.TokenAuthClientProvider\"\nCHROMA_CLIENT_AUTH_CREDENTIALS=\"admin:admin\"\n```\n\nTo migrate to the new server configuration, simply change it to:\n\n```yaml\nCHROMA_SERVER_AUTHN_PROVIDER", - "81cc20f6-4fa6-4a3c-afd7-071930407c85": "=\"chromadb.auth.token_authn.TokenAuthenticationServerProvider\"\nCHROMA_SERVER_AUTHN_CREDENTIALS=\"test-token\"\nCHROMA_SERVER_AUTHN_CREDENTIALS_FILE=\"./example_file\"\n```\n\nNew client configuration:\n\n```yaml\nCHROMA_CLIENT_AUTH_CREDENTIALS=\"test-token\"\nCHROMA_CLIENT_AUTH_PROVIDER=\"chromadb.auth.basic_authn.BasicAuthClientProvider\"\n```\n\n#### Token\n\nIf you're using `Token` auth, your server configuration might look like:\n\n```yaml\nCHROMA_SERVER_AUTH_CREDENTIALS=\"test-token\"\nCHROMA_SERVER_AUTH_CREDENTIALS_FILE=\"./example_file\"\nCHROMA_SERVER_AUTH_CREDENTIALS_PROVIDER=\"chromadb.auth.token.TokenConfigServerAuthCredentialsProvider\"\nCHROMA_SERVER_AUTH_PROVIDER=\"chromadb.auth.token.TokenAuthServerProvider\"\nCHROMA_SERVER_AUTH_TOKEN_TRANSPORT_HEADER=\"AUTHORIZATION\"\n```\n\n_Note: Only one of `AUTH_CREDENTIALS` and `AUTH_CREDENTIALS_FILE` can be set, but this guide shows how to migrate both._\n\nAnd your corresponding client configation:\n\n```yaml\nCHROMA_CLIENT_AUTH_PROVIDER=\"chromadb.auth.token.TokenAuthClientProvider\"\nCHROMA_CLIENT_AUTH_CREDENTIALS=\"test-token\"\n", - "dd3aa7d4-4c37-456e-9c25-3c0e3f1b0e0d": "CHROMA_CLIENT_AUTH_TOKEN_TRANSPORT_HEADER=\"AUTHORIZATION\"\n```\n\nTo migrate to the new server configuration, simply change it to:\n\n```yaml\nCHROMA_SERVER_AUTHN_PROVIDER=\"chromadb.auth.token_authn.TokenAuthenticationServerProvider\"\nCHROMA_SERVER_AUTHN_CREDENTIALS=\"test-token\"\nCHROMA_SERVER_AUTHN_CREDENTIALS_FILE=\"./example_file\"\nCHROMA_AUTH_TOKEN_TRANSPORT_HEADER=\"AUTHORIZATION\"\n```\n\nNew client configuration:\n\n```yaml\nCHROMA_CLIENT_AUTH_CREDENTIALS=\"test-token\"\nCHROMA_CLIENT_AUTH_PROVIDER=\"chromadb.auth.token_authn.TokenAuthClientProvider\"\nCHROMA_AUTH_TOKEN_TRANSPORT_HEADER=\"AUTHORIZATION\"\n```\n\n#### Reference of changed configuration values\n\n- Overall config\n - `chroma_client_auth_token_transport_header`: renamed to `chroma_auth_token_transport_header`.\n - `chroma_server_auth_token_transport_header`: renamed to `chroma_auth_token_transport_header`.\n- Client config\n - `chroma_client_auth_credentials_provider`: deleted. Functionality is now in `chroma_client_auth_provider`.\n - `chroma_client_auth_protocol_adapter`: deleted. Functionality is now in `chroma_client_auth_provider`.\n - `", - "9a0748dd-aa48-4d7f-b272-73a3fceec226": "chroma_client_auth_credentials_file`: deleted. Functionality is now in `chroma_client_auth_credentials`.\n - These changes also apply to the Typescript client.\n- Server authn\n - `chroma_server_auth_provider`: Renamed to `chroma_server_authn_provider`.\n - `chroma_server_auth_configuration_provider`: deleted. Functionality is now in `chroma_server_authn_provider`.\n - `chroma_server_auth_credentials_provider`: deleted. Functionality is now in `chroma_server_authn_provider`.\n - `chroma_server_auth_credentials_file`: renamed to `chroma_server_authn_credentials_file`.\n - `chroma_server_auth_credentials`: renamed to `chroma_server_authn_credentials`.\n - `chroma_server_auth_configuration_file`: renamed to `chroma_server_authn_configuration_file`.\n- Server authz\n - `chroma_server_authz_ignore_paths`: deleted. Functionality is now in `chroma_server_auth_ignore_paths`.\n\nTo see the full changes, you can read the [PR](https://github.com/chroma-core/chroma/pull/1970/files) or reach out to the Chroma team on [Discord](https://discord.gg/MMeYNT", - "709ff2d5-38e9-481c-8d9f-c16859933de3": "mh3x).\n\n### Migration to 0.4.16 - November 7, 2023\n\nThis release adds support for multi-modal embeddings, with an accompanying change to the definitions of `EmbeddingFunction`.\nThis change mainly affects users who have implemented their own `EmbeddingFunction` classes. If you are using Chroma's built-in embedding functions, you do not need to take any action.\n\n**EmbeddingFunction**\n\nPreviously, `EmbeddingFunction`s were defined as:\n\n```python\nclass EmbeddingFunction(Protocol):\n def __call__(self, texts: Documents) -> Embeddings:\n ...\n```\n\nAfter this update, `EmbeddingFunction`s are defined as:\n\n```python\nEmbeddable = Union[Documents, Images]\nD = TypeVar(\"D\", bound=Embeddable, contravariant=True)\n\nclass EmbeddingFunction(Protocol[D]):\n def __call__(self, input: D) -> Embeddings:\n ...\n```\n\nThe key differences are:\n\n- `EmbeddingFunction` is now generic, and takes a type parameter `D` which is a subtype of `Embeddable`. This allows us to define `EmbeddingFunction`s which can embed multiple modalities.\n- `", - "05317095-b882-4191-ae71-f3a3eb72b545": "__call__` now takes a single argument, `input`, to support data of any type `D`. The `texts` argument has been removed.\n\n### Migration from >0.4.0 to 0.4.0 - July 17, 2023\n\nWhat's new in this version?\n\n- New easy way to create clients\n- Changed storage method\n- `.persist()` removed, `.reset()` no longer on by default\n\n**New Clients**\n\n```python\n### in-memory ephemeral client\n\n# before\nimport chromadb\nclient = chromadb.Client()\n\n# after\nimport chromadb\nclient = chromadb.EphemeralClient()\n\n\n### persistent client\n\n# before\nimport chromadb\nfrom chromadb.config import Settings\nclient = chromadb.Client(Settings(\n chroma_db_impl=\"duckdb+parquet\",\n persist_directory=\"/path/to/persist/directory\" # Optional, defaults to .chromadb/ in the current directory\n))\n\n# after\nimport chromadb\nclient = chromadb.PersistentClient(path=\"/path/to/persist/directory\")\n\n\n### http client (to talk to server backend)\n\n# before\nimport chromadb\nfrom chromadb.config import Settings\nclient = chromadb.Client(Settings(ch", - "09f8b89c-27ce-4fd7-a8bd-97f7c2dc3e0e": "roma_api_impl=\"rest\",\n chroma_server_host=\"localhost\",\n chroma_server_http_port=\"8000\"\n ))\n\n# after\nimport chromadb\nclient = chromadb.HttpClient(host=\"localhost\", port=\"8000\")\n\n```\n\nYou can still also access the underlying `.Client()` method. If you want to turn off telemetry, all clients support custom settings:\n\n```python\nimport chromadb\nfrom chromadb.config import Settings\nclient = chromadb.PersistentClient(\n path=\"/path/to/persist/directory\",\n settings=Settings(anonymized_telemetry=False))\n```\n\n**New data layout**\n\nThis version of Chroma drops `duckdb` and `clickhouse` in favor of `sqlite` for metadata storage. This means migrating data over. We have created a migration CLI utility to do this.\n\nIf you upgrade to `0.4.0` and try to access data stored in the old way, you will see this error message\n\n> You are using a deprecated configuration of Chroma. Please pip install chroma-migrate and run `chroma-migrate` to upgrade your configuration. See https://docs.trychroma.com/deployment/migration for more information or join our discord at https://", - "e3a27357-f6e6-4b35-9cef-656e4ed7ab9d": "discord.gg/MMeYNTmh3x for help!\n\nHere is how to install and use the CLI:\n\n```terminal\npip install chroma-migrate\nchroma-migrate\n```\n\n![](/chroma-migrate.png)\n\nIf you need any help with this migration, please reach out! We are on [Discord](https://discord.com/channels/1073293645303795742/1129286514845691975) ready to help.\n\n**Persist & Reset**\n\n`.persist()` was in the old version of Chroma because writes were only flushed when forced to. Chroma `0.4.0` saves all writes to disk instantly and so `persist` is no longer needed.\n\n`.reset()`, which resets the entire database, used to by enabled-by-default which felt wrong. `0.4.0` has it disabled-by-default. You can enable it again by passing `allow_reset=True` to a Settings object. For example:\n\n```python\nimport chromadb\nfrom chromadb.config import Settings\nclient = chromadb.PersistentClient(path=\"./path/to/chroma\", settings=Settings(allow_reset=True))\n```\n\n# Troubleshooting\n\nThis page is a list of common gotchas or", - "cfefb49a-3328-4f1b-a74c-2385afc499d7": " issues and how to fix them.\n\nIf you don't see your problem listed here, please also search the [Github Issues](https://github.com/chroma-core/chroma/issues).\n\n## Chroma JS-Client failures on NextJS projects\n\nWhen using Chroma with Next.js, be sure to do any embedding in the server - client-side embedding is not supported.\n\nNext.js v15.2.1 includes a fix for embedding functions used by Chroma. If you're using an earlier version of Next.js, you may need to add this configuration to your `next.config.{js|ts}` file:\n\n```typescript\nconst nextConfig = {\n serverExternalPackages: ['chromadb', 'chromadb-default-embed'],\n};\nmodule.exports = nextConfig\n```\n\nIn addition, make sure you're using the latest of the `chromadb` package. Version v2.0.0 includes some important fixes for Next.js environments.\n\n\n## Cannot return the results in a contiguous 2D array. Probably ef or M is too small\n\nThis error happens when the HNSW index fails to retrieve the requested number of results for a query, given its structure and your data. he way to resolve this is to either decrease the number of", - "fc0216bb-1be7-4073-9f97-7b000e4dc7de": " results you request from a query (n_result), or increase the HNSW parameters `M`, `ef_construction`, and `ef_search`. You can read more about HNSW configurations [here](/docs/collections/configure).\n\n## Using .get or .query, embeddings say `None`\n\nThis is actually not an error. Embeddings are quite large and heavy to send back. Most application don't use the underlying embeddings and so, by default, chroma does not send them back.\n\nTo send them back: add `include=[\"embeddings\", \"documents\", \"metadatas\", \"distances\"]` to your query to return all information.\n\nFor example:\n\n```python\nresults = collection.query(\n query_texts=\"hello\",\n n_results=1,\n include=[\"embeddings\", \"documents\", \"metadatas\", \"distances\"],\n)\n```\n\n{% note type=\"tip\" %}\nWe may change `None` to something else to more clearly communicate why they were not returned.\n{% /note %}\n\n\n## Build error when running `pip install chromadb`\n\nIf you encounter an error like this during setup\n\n```\nFailed to build hnswlib\nERROR: Could not build wheels for hnsw", - "0b978b27-b452-41ec-b0ec-8524f573dd5a": "lib, which is required to install pyproject.toml-based projects\n```\n\nTry these few tips from the [community](https://github.com/chroma-core/chroma/issues/221):\n\n1. If you get the error: `clang: error: the clang compiler does not support '-march=native'`, set this ENV variable, `export HNSWLIB_NO_NATIVE=1`\n2. If on Mac, install/update xcode dev tools, `xcode-select --install`\n3. If on Windows, try [these steps](https://github.com/chroma-core/chroma/issues/250#issuecomment-1540934224)\n\n## SQLite\n\nChroma requires SQLite > 3.35, if you encounter issues with having too low of a SQLite version please try the following.\n\n1. Install the latest version of Python 3.10, sometimes lower versions of python are bundled with older versions of SQLite.\n2. If you are on a Linux system, you can install pysqlite3-binary, `pip install pysqlite3-binary` and then override the default\n sqlite3 library before running Chroma with the steps [here](https://gist.github.com/defulmere/8b9695", - "1d0932ca-5fa7-4e2f-84e3-b018d49f27c6": "e415a44271061cc8e272f3c300).\n Alternatively you can compile SQLite from scratch and replace the library in your python installation with the latest version as documented [here](https://github.com/coleifer/pysqlite3#building-a-statically-linked-library).\n3. If you are on Windows, you can manually download the latest version of SQLite from https://www.sqlite.org/download.html and\n replace the DLL in your python installation's DLLs folder with the latest version. You can find your python installation path by running `os.path.dirname(sys.executable)` in python.\n4. If you are using a Debian based Docker container, older Debian versions do not have an up to date SQLite, please use `bookworm` or higher.\n\n## Illegal instruction (core dumped)\n\nIf you encounter an error like this during setup and are using Docker - you may have built the library on a machine with a different CPU architecture than the one you are running it on. Try rebuilding the Docker image on the machine you are running it on.\n\n## My data directory is too large\n\nIf you were using Chroma prior to v0.5.6, you may be able to significantly shrink your database by [vac", - "edfe877c-8ac0-4fef-a8cb-4a447e1a3c1c": "uuming it](/reference/cli#vacuuming). After vacuuming once, automatic pruning (a new feature in v0.5.6) is enabled and will keep your database size in check.", - "e998db17-4b7a-457d-9eca-07158d7e33e8": "# Adding Data to Chroma Collections\n\nAdd data to Chroma with `.add`.\n\nRaw documents:\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\ncollection.add(\n documents=[\"lorem ipsum...\", \"doc2\", \"doc3\", ...],\n metadatas=[{\"chapter\": \"3\", \"verse\": \"16\"}, {\"chapter\": \"3\", \"verse\": \"5\"}, {\"chapter\": \"29\", \"verse\": \"11\"}, ...],\n ids=[\"id1\", \"id2\", \"id3\", ...]\n)\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nawait collection.add({\n ids: [\"id1\", \"id2\", \"id3\", ...],\n metadatas: [{\"chapter\": \"3\", \"verse\": \"16\"}, {\"chapter\": \"3\", \"verse\": \"5\"}, {\"chapter\": \"29\", \"verse\": \"11\"}, ...],\n documents: [\"lorem ipsum...\", \"doc2\", \"doc3\", ...],\n});\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nIf Chroma is passed a list of `documents`, it will automatically tokenize and embed them", - "d5b2c1e8-fd7c-4934-9992-07bc8d3734cf": " with the collection's embedding function (the default will be used if none was supplied at collection creation). Chroma will also store the `documents` themselves. If the documents are too large to embed using the chosen embedding function, an exception will be raised.\n\nEach document must have a unique associated `id`. Trying to `.add` the same ID twice will result in only the initial value being stored. An optional list of `metadata` dictionaries can be supplied for each document, to store additional information and enable filtering.\n\nAlternatively, you can supply a list of document-associated `embeddings` directly, and Chroma will store the associated documents without embedding them itself.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\ncollection.add(\n documents=[\"doc1\", \"doc2\", \"doc3\", ...],\n embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],\n metadatas=[{\"chapter\": \"3\", \"verse\": \"16\"}, {\"chapter\": \"3\", \"verse\": \"5\"}, {\"chapter\": \"", - "bca06d64-c6ef-4bda-a7ec-087c53308c47": "29\", \"verse\": \"11\"}, ...],\n ids=[\"id1\", \"id2\", \"id3\", ...]\n)\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nawait collection.add({\n ids: [\"id1\", \"id2\", \"id3\", ...],\n embeddings: [[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],\n metadatas: [{\"chapter\": \"3\", \"verse\": \"16\"}, {\"chapter\": \"3\", \"verse\": \"5\"}, {\"chapter\": \"29\", \"verse\": \"11\"}, ...],\n documents: [\"lorem ipsum...\", \"doc2\", \"doc3\", ...],\n})\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nIf the supplied `embeddings` are not the same dimension as the collection, an exception will be raised.\n\nYou can also store documents elsewhere, and just supply a list of `embeddings` and `metadata` to Chroma. You can use the `ids` to associate the embeddings", - "23829ba6-9082-4747-86fc-41321b4e9525": " with your documents stored elsewhere.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\ncollection.add(\n embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],\n metadatas=[{\"chapter\": \"3\", \"verse\": \"16\"}, {\"chapter\": \"3\", \"verse\": \"5\"}, {\"chapter\": \"29\", \"verse\": \"11\"}, ...],\n ids=[\"id1\", \"id2\", \"id3\", ...]\n)\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nawait collection.add({\n ids: [\"id1\", \"id2\", \"id3\", ...],\n embeddings: [[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],\n metadatas: [{\"chapter\": \"3\", \"verse\": \"16\"}, {\"chapter\": \"3\", \"verse\": \"", - "d10dab6c-4868-41a8-ba31-5e11c4b00e31": "5\"}, {\"chapter\": \"29\", \"verse\": \"11\"}, ...],\n})\n```\n\n# Configuring Chroma Collections\n\nYou can configure the embedding space of a collection by setting special keys on a collection's metadata. These configurations will help you customize your Chroma collections for different data, accuracy and performance requirements.\n\n* `hnsw:space` defines the distance function of the embedding space. The default is `l2` (squared L2 norm), and other possible values are `cosine` (cosine similarity), and `ip` (inner product).\n\n| Distance | parameter | Equation |\n| ----------------- | :-------: |-----------------------------------------------------------------------------------------------------------------------------------------------------------:|\n| Squared L2 | `l2` | {% Latex %} d = \\\\sum\\\\left(A_i-B_i\\\\right)^2 {% /Latex %} |\n| Inner product | `ip` | {% Latex %} d = 1.0 - \\\\sum\\\\left(A_i \\\\times B_i\\\\right) {% /Latex %} |\n| Cosine similarity | `cosine` | {% Latex %} d = 1.0 - \\\\", - "fd28f5aa-e19f-4689-bb62-e17081cf9b4b": "frac{\\\\sum\\\\left(A_i \\\\times B_i\\\\right)}{\\\\sqrt{\\\\sum\\\\left(A_i^2\\\\right)} \\\\cdot \\\\sqrt{\\\\sum\\\\left(B_i^2\\\\right)}} {% /Latex %} |\n\n* `hnsw:construction_ef` determines the size of the candidate list used to select neighbors during index creation. A higher value improves index quality at the cost of more memory and time, while a lower value speeds up construction with reduced accuracy. The default value is `100`.\n* `hnsw:search_ef` determines the size of the dynamic candidate list used while searching for the nearest neighbors. A higher value improves recall and accuracy by exploring more potential neighbors but increases query time and computational cost, while a lower value results in faster but less accurate searches. The default value is `100`.\n* `hnsw:M` is the maximum number of neighbors (connections) that each node in the graph can have during the construction of the index. A higher value results in a denser graph, leading to better recall and accuracy during searches but increases memory usage and construction time. A lower value creates a sparser graph, reducing memory usage and construction time but at the cost of lower search", - "e55135e8-736b-4c9b-a22c-9b08aabd8efb": " accuracy and recall. The default value is `16`.\n* `hnsw:num_threads` specifies the number of threads to use during index construction or search operations. The default value is `multiprocessing.cpu_count()` (available CPU cores).\n\nHere is an example of how you can create a collection and configure it with custom HNSW settings:\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\ncollection = client.create_collection(\n name=\"my_collection\", \n embedding_function=emb_fn,\n metadata={\n \"hnsw:space\": \"cosine\",\n \"hnsw:search_ef\": 100\n }\n)\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nlet collection = await client.createCollection({\n name: \"my_collection\",\n embeddingFunction: emb_fn,\n metadata: {\n \"hnsw:space\": \"cosine\",\n \"hnsw:search_ef\": 100\n }\n});\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nYou can learn more in our [Embeddings section](../embeddings/embedding-functions).\n\n## Fine-Tuning HNSW Parameters\n\nWe use an HNSW (", - "cfce40b3-e50d-4530-a598-0ee73799886d": "Hierarchical Navigable Small World) index to perform approximate nearest neighbor (ANN) search for a given embedding. In this context, **Recall** refers to how many of the true nearest neighbors were retrieved.\n\nIncreasing `search_ef` normally improves recall, but slows down query time. Similarly, increasing `construction_ef` improves recall, but increases the memory usage and runtime when creating the index.\n\nChoosing the right values for your HNSW parameters depends on your data, embedding function, and requirements for recall, and performance. You may need to experiment with different construction and search values to find the values that meet your requirements.\n\nFor example, for a dataset with 50,000 embeddings of 2048 dimensions, generated by\n\n```python\nembeddings = np.random.randn(50000, 2048).astype(np.float32).tolist()\n```\n\nwe set up two Chroma collections:\n* The first is configured with `hnsw:ef_search: 10`. When querying using a specific embedding from the set (with `id = 1`), the query takes `0.00529` seconds, and we get back embeddings with distances:\n\n```\n[3629.019775390625, 3666.576", - "1cf76854-f1ba-4010-a1e4-2df18eebf33c": "904296875, 3684.57080078125]\n``` \n\n* The second collection is configured with `hnsw:ef_search: 100` and `hnsw:ef_construction:1000`. When issuing the same query, this time it takes `0.00753` seconds (about 42% slower), but with better results as measured by their distance:\n\n```\n[0.0, 3620.593994140625, 3623.275390625]\n```\n\nIn this example, when querying with the test embedding (`id=1`), the first collection failed to find the embedding itself, despite it being in the collection (where it should have appeared as a result with a distance of `0.0`). The second collection, while slightly slower, successfully found the query embedding itself (shown by the `0.0` distance) and returned closer neighbors overall, demonstrating better accuracy at the cost of performance.\n\n# Create, Get, and Delete Chroma Collections\n\nChroma lets you manage collections of embeddings, using the `collection` primitive.\n\nChroma uses collection names in the url, so there are a few restrictions on naming them:\n\n- The length of the name must be between ", - "5f1f7a80-4f2e-433a-9d02-57f89b5e343f": "3 and 63 characters.\n- The name must start and end with a lowercase letter or a digit, and it can contain dots, dashes, and underscores in between.\n- The name must not contain two consecutive dots.\n- The name must not be a valid IP address.\n\nChroma collections are created with a name and an optional embedding function.\n\n{% Banner type=\"note\" %}\nIf you supply an embedding function, you must supply it every time you get the collection.\n{% /Banner %}\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\ncollection = client.create_collection(name=\"my_collection\", embedding_function=emb_fn)\ncollection = client.get_collection(name=\"my_collection\", embedding_function=emb_fn)\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nlet collection = await client.createCollection({\n name: \"my_collection\",\n embeddingFunction: emb_fn,\n});\n\ncollection = await client.getCollection({\n name: \"my_collection\",\n embeddingFunction: emb_fn,\n});\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nThe embedding function takes text as input and embeds it. If no embedding function is supplied, Chroma will use [sentence", - "e5b64414-8da6-49fa-9c6c-db32a3a2a5e4": " transformer](https://www.sbert.net/index.html) as a default. You can learn more about [embedding functions](../embeddings/embedding-functions), and how to create your own.\n\nWhen creating collections, you can pass the optional `metadata` argument to add a mapping of metadata key-value pairs to your collections. This can be useful for adding general about the collection like creation time, description of the data stored in the collection, and more.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\nfrom datetime import datetime\n\ncollection = client.create_collection(\n name=\"my_collection\", \n embedding_function=emb_fn,\n metadata={\n \"description\": \"my first Chroma collection\",\n \"created\": str(datetime.now())\n } \n)\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nlet collection = await client.createCollection({\n name: \"my_collection\",\n embeddingFunction: emb_fn,\n metadata: {\n description: \"my first Chroma collection\",\n created: (new Date()).toString()\n }\n});\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nThe collection metadata is also used to configure the embedding space of", - "2dbea9d3-c6c2-48fe-8c0e-3f9d5114b24a": " a collection. Learn more about it in [Configuring Chroma Collections](./configure).\n\nThe Chroma client allows you to get and delete existing collections by their name. It also offers a `get or create` method to get a collection if it exists, or create it otherwise.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\ncollection = client.get_collection(name=\"test\") # Get a collection object from an existing collection, by name. Will raise an exception if it's not found.\ncollection = client.get_or_create_collection(name=\"test\") # Get a collection object from an existing collection, by name. If it doesn't exist, create it.\nclient.delete_collection(name=\"my_collection\") # Delete a collection and all associated embeddings, documents, and metadata. \u26a0\ufe0f This is destructive and not reversible\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nconst collection = await client.getCollection({ name: \"test\" }); // Get a collection object from an existing collection, by name. Will raise an exception of it's not found.\ncollection = await client.getOrCreateCollection({ name: \"test\" }); // Get a collection object from an existing collection,", - "e8af7863-4666-4f95-8144-0ca6a39c64d3": " by name. If it doesn't exist, create it.\nawait client.deleteCollection(collection); // Delete a collection and all associated embeddings, documents, and metadata. \u26a0\ufe0f This is destructive and not reversible\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nCollections have a few useful convenience methods.\n\n* `peek()` - returns a list of the first 10 items in the collection.\n* `count()` - returns the number of items in the collection.\n* `modify()` - rename the collection\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\ncollection.peek() \ncollection.count() \ncollection.modify(name=\"new_name\")\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nawait collection.peek();\nawait collection.count();\nawait collection.modify({ name: \"new_name\" })\n```\n\n# Deleting Data from Chroma Collections\n\nChroma supports deleting items from a collection by `id` using `.delete`. The embeddings, documents, and metadata associated with each item will be deleted.\n\n{% Banner type=\"warn\" %}\nNaturally, this is a destructive operation, and cannot be undone.\n{% /Banner %}\n\n`.delete` also supports the `where", - "07a42cc9-4ff3-47de-a7b4-6824f793ce4f": "` filter. If no `ids` are supplied, it will delete all items in the collection that match the `where` filter.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\ncollection.delete(\n ids=[\"id1\", \"id2\", \"id3\",...],\n\twhere={\"chapter\": \"20\"}\n)\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nawait collection.delete({\n ids: [\"id1\", \"id2\", \"id3\",...], //ids\n where: {\"chapter\": \"20\"} //where\n})\n```", - "390fa818-b955-4ceb-81a9-1bbe53f64376": "# Deployment\n\n{% Banner type=\"tip\" %}\n\n**Hosted Chroma**\n\nChroma Cloud, our fully managed hosted service is here. [Sign up here](https://trychroma.com/signup) for early access.\n\n{% /Banner %}\n\n{% Banner type=\"tip\" %}\n\nIf you are using Chroma in production, please fill out [this form](https://airtable.com/appqd02UuQXCK5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users.\nThis is the best place to\n\n1. Get support with building with Chroma in prod.\n2. Stay up-to-date with exciting new features.\n3. Get swag!\n\nWe would love to help you think through the design of your system, or if you would be a good fit for our upcoming distributed cloud service.\n\n{% /Banner %}\n\nYou can run Chroma single-node in [client/server mode](./chroma-server/client-server-mode), and easily deploy it. In this section, we also show you how to make sure your Chroma server is secure and reliable, and how to understand its performance at scale.\n\n\n### Containers\n*", - "8d4bd4bd-004f-4aeb-87dc-8b0e0ff3820d": " [Docker](./containers/docker)\n* Kubernetes - Coming Soon!\n\n### Cloud Providers\n\n* [AWS](./cloud-providers/aws)\n* [GCP](./cloud-providers/gcp)\n* [Azure](./cloud-providers/azure)\n\n***\n\n### Administration\n\nRunning a server in production requires a few additional steps to ensure the server is secure and reliable.\n\n* [Performance](./administration/performance)\n* [Observability](./administration/observability)\n* [Migration](./administration/migration)\n\n# Observability\n\n\n## Backend Observability\n\nChroma is instrumented with [OpenTelemetry](https://opentelemetry.io/) hooks for observability.\n\n{% note type=\"default\" title=\"Telemetry vs Observability\" %}\n\"[Telemetry](../../docs/overview/telemetry)\" refers to anonymous product usage statistics we collect. \"Observability\" refers to metrics, logging, and tracing which can be used by anyone operating a Chroma deployment. Observability features listed on this page are **never** sent back to Chroma; they are for end-users to better understand how their Chroma deployment is behaving.\n{% /note %}\n\n### Available Observability\n\nChroma currently only exports OpenTelemetry [traces](", - "d1c3c089-33f9-482b-86d4-ef4f950b56cf": "https://opentelemetry.io/docs/concepts/signals/traces/). Traces allow a Chroma operator to understand how requests flow through the system and quickly identify bottlenecks.\n\n### Configuration\n\nTracing is configured with three environment variables:\n\n- `CHROMA_OPEN_TELEMETRY__ENDPOINT`: where to send observability data. Example: `api.honeycomb.com`.\n- `CHROMA_OPEN_TELEMETRY__SERVICE_NAME`: Service name for OTel traces. Default: `chromadb`.\n- `OTEL_EXPORTER_OTLP_HEADERS`: Headers to use when sending observability data. Often used to send API and app keys. For example `{\"x-honeycomb-team\": \"abc\"}`.\n\nWe also have dedicated observability guides for various deployments:\n* [Docker](../containers/docker#observability-with-docker)\n* [AWS](../cloud-providers/aws#observability-with-AWS)\n* [GCP](../cloud-providers/gcp#observability-with-GCP)\n* [Azure](../cloud-providers/azure#observability-with-Azure)\n\n## Client (SDK) Observability\n\nSeveral observability platforms offer built-in integrations for Chroma, allowing you to", - "36e7fc5b-5e21-49df-8a09-75dfdc07e48a": " monitor your application's interactions with the Chroma server:\n- [OpenLLMetry Integration](../../integrations/frameworks/openllmetry).\n- [OpenLIT Integration](../../integrations/frameworks/openlit).\n\n# Single-Node Chroma: Performance and Limitations\n\n\nThe single-node version of Chroma is designed to be easy to deploy and maintain, while still providing robust performance that satisfies a broad range of production applications.\n\nTo help you understand when single-node Chroma is a good fit for your use case, we have performed a series of stress tests and performance experiments to probe the system\u2019s capabilities and discover its limitations and edge cases. We analyzed these boundaries across a range of hardware configurations, to determine what sort of deployment is appropriate for different workloads.\n\nThis document describes these findings, as well as some general principles for getting the most out of your Chroma deployment.\n\n## Results Summary\n\nRoughly speaking, here is the sort of performance you can expect from Chroma on different EC2 instance types with a very typical workload:\n\n- 1024 dimensional embeddings\n- Small documents (100-200 words)\n- Three metadata fields per record.\n\n| Instance Type | System RAM | Approx. Max Collection Size | Mean Latency", - "e5e609ca-a7ce-4729-8738-0cb41beb71a7": " (insert) | 99.9% Latency (insert) | Mean Latency (query) | 99.9% Latency (query) | Monthly Cost |\n|-----------------|------------|-----------------------------|-----------------------|------------------------|----------------------|-----------------------|--------------|\n| **t3.small** | 2 | 250,000 | 55ms | 250ms | 22ms | 72ms | $15.936 |\n| **t3.medium** | 4 | 700,000 | 37ms | 120ms | 14ms | 41ms | $31.072 |\n| **t3.large** | 8 | 1,700,000 | 30ms | 100ms | 13ms | 35ms | $61.344 |\n| **t3.xlarge** | 16 | 3,600,000 | 30ms | 100ms | 13ms | 30ms | $121.888 |\n| **t3.2xlarge** ", - "ac408ae9-0135-4e3b-9e6a-695cafcb2c1c": " | 32 | 7,500,000 | 30ms | 100ms | 13ms | 30ms | $242.976 |\n| **r7i.2xlarge** | 64 | 15,000,000 | 13ms | 50ms | 7ms | 13ms | $386.944 |\n\n{% br %}{% /br %}\n\nDeploying Chroma on a system with less than 2GB of RAM is **not** recommended.\n\nNote that the latency figures in this table are for small collections. Latency increases as collections grow: see [Latency and collection size](./performance#latency-and-collection-size) below for a full analysis.\n\n## Memory and collection size\n\nChroma uses a fork of [`hnswlib`](https://github.com/nmslib/hnswlib) to efficiently index and search over embedding vectors. The HNSW algorithm requires that the embedding index reside in system RAM to query or update.\n\nAs such, the amount of available system memory defines an upper bound on the size of a Chroma collection (or multiple collections, if they are being used concurrently", - "e69e12c2-a605-456f-b2f7-bdf6ace96e96": ".) If a collection grows larger than available memory, insert and query latency spike rapidly as the operating system begins swapping memory to disk. The memory layout of the index is not amenable to swapping, and the system quickly becomes unusable.\n\nTherefore, users should always plan on having enough RAM provisioned to accommodate the anticipated total number of embeddings.\n\nTo analyze how much RAM is required, we launched an an instance of Chroma on variously sized EC2 instances, then inserted embeddings until each system became non-responsive. As expected, this failure point corresponded linearly to RAM and embedding count.\n\nFor 1024 dimensional embeddings, with three metadata records and a small document per embedding, this works out to `N = R * 0.245` where `N` is the max collection size in millions, and `R` is the amount of system RAM required in gigabytes. Remember, you wil also need reserve at least a gigabyte for the system\u2019s other needs, in addition to the memory required by Chroma.\n\nThis pattern holds true up through about 7 million embeddings, which is as far as we tested. At this point Chroma is still fast and stable, and we did not find a strict upper bound on the size of", - "9a2c19c0-5b0f-47d8-9e4a-376b0a5d2084": " a Chroma database.\n\n## Disk space and collection size\n\nChroma durably persists each collection to disk. The amount of space required is a combination of the space required to save the HNSW embedding index, and the space required by the sqlite database used to store documents and embedding metadata.\n\nThe calculations for persisting the HNSW index are similar to that for calculating RAM size. As a rule of thumb, just make sure a system\u2019s storage is at least as big as its RAM, plus several gigabytes to account for the overhead of the operating system and other applications.\n\nThe amount of space required by the sqlite database is highly variable, and depends entirely on whether documents and metadata are being saved in Chroma, and if so, how large they are. Fully exploring all permutations of this are beyond the scope of the experiments we were able to run.\n\nHowever, as a single data point, the sqlite database for a collection with ~40k documents of 1000 words each, and ~600k metadata entries was about 1.7gb.\n\nThere is no strict upper bound on the size of the metadata database: sqlite itself supports databases into the terabyte range, and can page to disk effectively.\n\nIn most realistic use cases,", - "914223eb-b2cd-4f7a-9edc-0c617b3afefd": " it\u2019s likely that the size and performance of the HNSW index in RAM becomes the limiting factor on a Chroma collection\u2019s size long before the metadata database does.\n\n## Latency and collection size\n\nAs collections get larger and the size of the index grows, inserts and queries both take longer to complete. The rate of increase starts out fairly flat then grow roughly linearly, with the inflection point and slope depending on the quantity and speed of CPUs available.\n\n### Query Latency\n\n![query-latency](/query-latency.png)\n\n### Insert Latency\n\n![insert-latency](/insert-latency.png)\n\n{% note type=\"tip\" title=\"\" %}\nIf you\u2019re using multiple collections, performance looks quite similar, based on the total number of embeddings across collections. Splitting collections into multiple smaller collections doesn\u2019t help, but it doesn\u2019t hurt, either, as long as they all fit in memory at once.\n{% /note %}\n\n## Concurrency\n\nAlthough aspects of HNSW\u2019s algorithm are multithreaded internally, only one thread can read or write to a given index at a time. For the most part, single-node Chroma is fundamentally single threaded. If an operation is executed while another is still in progress", - "8946b92d-8e9c-424f-9078-7a91f61baa36": ", it blocks until the first one is complete.\n\nThis means that under concurrent load, the average latency of each request will increase.\n\nWhen writing, the increased latency is more pronounced with larger batch sizes, as the system is more completely saturated. We have experimentally verified this: as the number of concurrent writers is increased, average latency increases linearly.\n\n![concurrent-writes](/concurrent-writes.png)\n\n![concurrent-queries](/concurrent-queries.png)\n\nDespite the effect on latency, Chroma does remain stable with high concurrent load. Too many concurrent users can eventually increase latency to the point where the system does not perform acceptably, but this typically only happens with larger batch sizes. As the above graphs shows, the system remains usable with dozens to hundreds of operations per second.\n\nSee the [Insert Throughput](./performance#insert-throughput) section below for a discussion of optimizing user count for maximum throughput when the concurrency is under your control, such as when inserting bulk data.\n\n# CPU speed, core count & type\n\nAs a CPU bound application, it\u2019s not surprising that CPU speed and type makes a difference for average latency.\n\nAs the data demonstrates, although it is not fully parallelized, Chroma can", - "dbe55a9c-f1bb-4be6-8176-af95814b69a0": " still take some advantage of multiple CPU cores for better throughput.\n\n![cpu-mean-query-latency](/cpu-mean-query-latency.png)\n\n{% note type=\"tip\" title=\"\" %}\nNote the slightly increased latency for the t3.2xlarge instance. Logically, it should be faster than the other t3 series instances, since it has the same class of CPU, and more of them.\n\nThis data point is left in as an important reminder that the performance of EC2 instances is slightly variable, and it\u2019s entirely possible to end up with an instance that has performance differences for no discernible reason.\n{% /note %}\n\n# Insert Throughput\n\nA question that is often relevant is: given bulk data to insert, how fast is it possible to do so, and what\u2019s the best way to insert a lot of data quickly?\n\nThe first important factor to consider is the number of concurrent insert requests.\n\nAs mentioned in the [Concurrency](./performance#concurrency) section above, actual insertion throughput does not benefit from concurrency. However, there is some amount of network and HTTP overhead which can be parallelized. Therefore, to saturate Chroma while keeping latencies as low as possible, we recommend 2 concurrent client processes or threads", - "20919873-34ad-42d6-a43e-6b0f8665c693": " inserting as fast as possible.\n\nThe second factor to consider is the batch size of each request. Performance is mostly linear with respect to batch size, with a constant overhead to process the HTTP request itself.\n\nExperimentation confirms this: overall throughput (total number of embeddings inserted, across batch size and request count) remains fairly flat between batch sizes of 100-500:\n\n![concurrent-inserts](/concurrent-inserts.png)\n\nGiven that smaller batches have lower, more consistent latency and are less likely to lead to timeout errors, we recommend batches on the smaller side of this curve: anything between 50 and 250 is a reasonable choice.\n\n## Conclusion\n\nUsers should feel comfortable relying on Chroma for use cases approaching tens of millions of embeddings, when deployed on the right hardware. It\u2019s average and upper-bound latency for both reads and writes make it a good platform for all but the largest AI-based applications, supporting potentially thousands of simultaneous human users (depending on your application\u2019s backend access patterns.)\n\nAs a single-node solution, though, it won\u2019t scale forever. If you find your needs exceeding the parameters laid out in this analysis, we are extremely interested in hearing from you. Please fill out [this form](https://airtable.com/app", - "a7784723-1203-4795-a4ef-c7fbbe1600ba": "qd02UuQXCK5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users. We would love to help you think through the design of your system, whether Chroma has a place in it, or if you would be a good fit for our upcoming distributed cloud service.\n\n# Running Chroma in Client-Server Mode\n\nChroma can also be configured to run in client/server mode. In this mode, the Chroma client connects to a Chroma server running in a separate process.\n\nThis means that you can deploy single-node Chroma to a [Docker container](../containers/docker), or a machine hosted by a cloud provider like [AWS](../cloud-providers/aws), [GCP](../cloud-providers/gcp), [Azure](../cloud-providers/azure), and others. Then, you can access your Chroma server from your application using our `HttpClient` (or `ChromaClient` for JS/TS users).\n\nYou can quickly experiment locally with Chroma in client/server mode by using our CLI:\n\n```terminal\nchroma run --path /db_path\n```\n\n{% Tabs %}\n\n{% Tab", - "50b11ae2-a52e-4fd1-91ee-5cf5f4eaa773": " label=\"python\" %}\n\nThen use the Chroma `HttpClient` to connect to the server:\n\n```python\nimport chromadb\nchroma_client = chromadb.HttpClient(host='localhost', port=8000)\n```\n\nChroma also provides an `AsyncHttpClient`. The behaviors and method signatures are identical to the synchronous client, but all methods that would block are now async:\n\n```python\nimport asyncio\nimport chromadb\n\nasync def main():\n client = await chromadb.AsyncHttpClient()\n collection = await client.create_collection(name=\"my_collection\")\n await collection.add(\n documents=[\"hello world\"],\n ids=[\"id1\"]\n )\n\nasyncio.run(main())\n```\n\nIf you intend to deploy your Chroma server, you may want to consider our [thin-client package](./thin-client) for client-side interactions.\n\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n\nThen instantiate a new `ChromaClient`. The default is to connect to a Chroma server running on localhost.\n\n```typescript\n// CJS\nconst { ChromaClient } = require(\"chromadb\");\n// ESM\nimport { ChromaClient } from \"chromadb\";\n\nconst client = new ChromaClient();\n```\n\n{% /", - "52e590ab-5417-4996-bb7e-ed1d4360a508": "Tab %}\n\n{% /Tabs %}\n\n# Chroma's Thin-Client\n\n\nIf you are running Chroma in client-server mode in a Python or JavaScript application, you may not need the full Chroma library. Instead, you can use the lightweight client-only library.\n\nIn this case, you can install the `chromadb-client` package **instead** of our `chromadb` package.\n\nThe `chromadb-client` package is a lightweight HTTP client for the server with a minimal dependency footprint.\n\n\n```terminal\n# Python\npip install chromadb-client\n# JS\nnpm install chromadb-client\n```\n\n```python\n# Python\nimport chromadb\n# Example setup of the client to connect to your chroma server\nclient = chromadb.HttpClient(host='localhost', port=8000)\n\n# Or for async usage:\nasync def main():\n client = await chromadb.AsyncHttpClient(host='localhost', port=8000)\n```\n\n```javascript\n// JavaScript\nimport { ChromaClient } from \"chromadb-client\";\nconst client = new ChromaClient({ path: \"http://localhost:8000\" })\n```\n\nNote that the `chromadb-client` package is a subset of the full Chroma library and does", - "147d5d2e-a3cb-48a3-a808-2f0ea2b95fa5": " not include all the dependencies. If you want to use the full Chroma library, you can install the `chromadb` package instead.\n\nMost importantly, the thin-client package has no default embedding functions. If you `add()` documents without embeddings, you must have manually specified an embedding function and installed the dependencies for it.\n\n# AWS Deployment\n\n{% Banner type=\"tip\" %}\n\n**Hosted Chroma**\n\nChroma Cloud, our fully managed hosted service is here. [Sign up here](https://trychroma.com/signup) for early access.\n\n{% /Banner %}\n\n{% Banner type=\"tip\" %}\n\nIf you are using Chroma in production, please fill out [this form](https://airtable.com/appqd02UuQXCK5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users.\nThis is the best place to\n\n1. Get support with building with Chroma in prod.\n2. Stay up-to-date with exciting new features.\n3. Get swag!\n\nWe would love to help you think through the design of your system, or if you would be a good fit for our upcoming distributed cloud service", - "b9c60a28-2d10-482a-b3a3-ab544eb61e28": ".\n\n{% /Banner %}\n\n## A Simple AWS Deployment\n\nYou can deploy Chroma on a long-running server, and connect to it\nremotely.\n\nThere are many possible configurations, but for convenience we have\nprovided a very simple AWS CloudFormation template to experiment with\ndeploying Chroma to EC2 on AWS.\n\n{% Banner type=\"warn\" %}\n\nChroma and its underlying database [need at least 2GB of RAM](./performance#results-summary),\nwhich means it won't fit on the 1gb instances provided as part of the\nAWS Free Tier. This template uses a [`t3.small`](https://aws.amazon.com/ec2/instance-types/t3/#Product%20Details) EC2 instance, which\ncosts about two cents an hour, or $15 for a full month, and gives you 2GiB of memory. If you follow these\ninstructions, AWS will bill you accordingly.\n\n{% /Banner %}\n\n{% Banner type=\"warn\" %}\n\nIn this guide we show you how to secure your endpoint using [Chroma's\nnative authentication support](./aws#authentication-with-aws). Alternatively, you can put it behind\n[AWS API Gateway](https://aws.amazon.com", - "b3c779de-e8d6-4c9c-8605-a4820f73532d": "/api-gateway/) or add your own\nauthenticating proxy. This basic stack doesn't support any kind of authentication;\nanyone who knows your server IP will be able to add and query for\nembeddings.\n\n{% /Banner %}\n\n{% Banner type=\"warn\" %}\n\nBy default, this template saves all data on a single\nvolume. When you delete or replace it, the data will disappear. For\nserious production use (with high availability, backups, etc.) please\nread and understand the CloudFormation template and use it as a basis\nfor what you need, or reach out to the Chroma team for assistance.\n\n{% /Banner %}\n\n### Step 1: Get an AWS Account\n\nYou will need an AWS Account. You can use one you already have, or\n[create a new one](https://aws.amazon.com).\n\n### Step 2: Get credentials\n\nFor this example, we will be using the AWS command line\ninterface. There are\n[several ways](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-prereqs.html)\nto configure the AWS CLI, but for the purposes of these examples we\nwill presume that you have\n[obtained an", - "ea2144ce-b306-4597-866f-5f7b760aae06": " AWS access key](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html)\nand will be using environment variables to configure AWS.\n\nExport the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables in your shell:\n\n```terminal\nexport AWS_ACCESS_KEY_ID=**\\*\\***\\*\\*\\*\\***\\*\\***\nexport AWS_SECRET_ACCESS_KEY=****\\*\\*****\\*\\*****\\*\\*****\n```\n\nYou can also configure AWS to use a region of your choice using the\n`AWS_REGION` environment variable:\n\n```terminal\nexport AWS_REGION=us-east-1\n```\n\n### Step 3: Run CloudFormation\n\nChroma publishes a [CloudFormation template](https://s3.amazonaws.com/public.trychroma.com/cloudformation/latest/chroma.cf.json) to S3 for each release.\n\nTo launch the template using AWS CloudFormation, run the following command line invocation.\n\nReplace `--stack-name my-chroma-stack` with a different stack name, if you wish.\n\n```terminal\naws cloudformation create-stack --stack-name my-chroma-stack --template-url https://s3.amazonaws.com/public.trychroma.com/cloudformation/latest/chroma.cf.json\n```\n\nWait a few minutes", - "45779bb9-5fbe-49b7-889b-28c15a5936ab": " for the server to boot up, and Chroma will be\navailable! You can get the public IP address of your new Chroma server using the AWS console, or using the following command:\n\n```terminal\naws cloudformation describe-stacks --stack-name my-chroma-stack --query 'Stacks[0].Outputs'\n```\n\nNote that even after the IP address of your instance is available, it may still take a few minutes for Chroma to be up and running.\n\n#### Customize the Stack (optional)\n\nThe CloudFormation template allows you to pass particular key/value\npairs to override aspects of the stack. Available keys are:\n\n- `InstanceType` - the AWS instance type to run (default: `t3.small`)\n- `KeyName` - the AWS EC2 KeyPair to use, allowing to access the instance via SSH (default: none)\n\nTo set a CloudFormation stack's parameters using the AWS CLI, use the\n`--parameters` command line option. Parameters must be specified using\nthe format `ParameterName={parameter},ParameterValue={value}`.\n\nFor example, the following command launches a new stack similar to the\nabove, but on a `m5.4xlarge` EC2 instance, and adding a", - "f0115587-fc49-42d2-b00d-3dd852003ebf": " KeyPair named\n`mykey` so anyone with the associated private key can SSH into the\nmachine:\n\n```terminal\naws cloudformation create-stack --stack-name my-chroma-stack --template-url https://s3.amazonaws.com/public.trychroma.com/cloudformation/latest/chroma.cf.json \\\n --parameters ParameterKey=KeyName,ParameterValue=mykey \\\n ParameterKey=InstanceType,ParameterValue=m5.4xlarge\n```\n\n### Step 4: Chroma Client Set-Up\n\nOnce your EC2 instance is up and running with Chroma, all\nyou need to do is configure your `HttpClient` to use the server's IP address and port\n`8000`. Since you are running a Chroma server on AWS, our [thin-client package](../chroma-server/python-thin-client) may be enough for your application.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n\n```python\nimport chromadb\n\nchroma_client = chromadb.HttpClient(\n host=\"\",\n port=8000\n)\nchroma_client.heartbeat()\n```\n\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n\n```typescript\nimport { ChromaClient } from \"chromadb", - "fb7857e5-b3ee-4b0a-a6b4-ebf6559648c7": "\";\n\nconst chromaClient = new ChromaClient({\n path: \"\",\n port: 8000\n})\nchromaClient.heartbeat()\n```\n\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n### Step 5: Clean Up (optional).\n\nTo destroy the stack and remove all AWS resources, use the AWS CLI `delete-stack` command.\n\n{% note type=\"warning\" title=\"Note\" %}\nThis will destroy all the data in your Chroma database,\nunless you've taken a snapshot or otherwise backed it up.\n{% /note %}\n\n```terminal\naws cloudformation delete-stack --stack-name my-chroma-stack\n```\n\n## Observability with AWS\n\nChroma is instrumented with [OpenTelemetry](https://opentelemetry.io/) hooks for observability. We currently only exports OpenTelemetry [traces](https://opentelemetry.io/docs/concepts/signals/traces/). These should allow you to understand how requests flow through the system and quickly identify bottlenecks. Check out the [observability docs](../administration/observability) for a full explanation of the available parameters.\n\nTo enable tracing on your Chroma server, simply pass your desired values as", - "e6b81cc3-7c53-492b-9ab5-8f9f8f22fd28": " arguments when creating your Cloudformation stack:\n\n```terminal\naws cloudformation create-stack --stack-name my-chroma-stack --template-url https://s3.amazonaws.com/public.trychroma.com/cloudformation/latest/chroma.cf.json \\\n --parameters ParameterKey=ChromaOtelCollectionEndpoint,ParameterValue=\"api.honeycomb.com\" \\\n ParameterKey=ChromaOtelServiceName,ParameterValue=\"chromadb\" \\\n ParameterKey=ChromaOtelCollectionHeaders,ParameterValue=\"{'x-honeycomb-team': 'abc'}\"\n```\n\n## Troubleshooting\n\n#### Error: No default VPC for this user\n\nIf you get an error saying `No default VPC for this user` when creating `ChromaInstanceSecurityGroup`, head to [AWS VPC section](https://us-east-1.console.aws.amazon.com/vpc/home?region=us-east-1#vpcs) and create a default VPC for your user.\n\n# Azure Deployment\n\n{% Banner type=\"tip\" %}\n\n**Hosted Chroma**\n\nChroma Cloud, our fully managed hosted service is here. [Sign up here](https://trychroma.com/signup) for early access.\n\n{% /Banner %}\n\n{% Banner type=\"tip\" %}\n\nIf", - "c54d36e4-c884-4c54-944c-1ed86b1f208c": " you are using Chroma in production, please fill out [this form](https://airtable.com/appqd02UuQXCK5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users.\nThis is the best place to\n\n1. Get support with building with Chroma in prod.\n2. Stay up-to-date with exciting new features.\n3. Get swag!\n\nWe would love to help you think through the design of your system, or if you would be a good fit for our upcoming distributed cloud service.\n\n{% /Banner %}\n\n## A Simple Azure Deployment\n\nYou can deploy Chroma on a long-running server, and connect to it\nremotely.\n\nFor convenience, we have\nprovided a very simple Terraform configuration to experiment with\ndeploying Chroma to Azure.\n\n{% Banner type=\"warn\" %}\nChroma and its underlying database [need at least 2GB of RAM](./performance#results-summary). When defining your VM size for the template in this example, make sure it meets this requirement.\n{% /Banner %}\n\n{% Banner type=\"warn\" %}\nIn this guide we show you how to secure your", - "59570399-cecf-4e95-b785-dc07d5fe5edc": " endpoint using [Chroma's\nnative authentication support](./azure#authentication-with-azure). Alternatively, you can put it behind\nan API Gateway or add your own\nauthenticating proxy. This basic stack doesn't support any kind of authentication;\nanyone who knows your server IP will be able to add and query for\nembeddings.\n{% /Banner %}\n\n{% Banner type=\"warn\" %}\nBy default, this template saves all data on a single\nvolume. When you delete or replace it, the data will disappear. For\nserious production use (with high availability, backups, etc.) please\nread and understand the Terraform template and use it as a basis\nfor what you need, or reach out to the Chroma team for assistance.\n{% /Banner %}\n\n### Step 1: Install Terraform\n\nDownload [Terraform](https://developer.hashicorp.com/terraform/install?product_intent=terraform) and follow the installation instructions for you OS.\n\n### Step 2: Authenticate with Azure\n\n```terminal\naz login\n```\n\n### Step 3: Configure your Azure Settings\n\nCreate a `chroma.tfvars` file. Use it to define the following variables for your Azure Resource Group name,", - "2ae301de-a349-4290-82f4-92900fe8e328": " VM size, and location. Note that this template creates a new resource group for your Chroma deployment.\n\n```text\nresource_group_name = \"your-azure-resource-group-name\"\nlocation = \"your-location\"\nmachine_type = \"Standard_B1s\"\n```\n\n### Step 4: Initialize and deploy with Terraform\n\nDownload our [Azure Terraform configuration](https://github.com/chroma-core/chroma/blob/main/deployments/azure/main.tf) to the same directory as your `chroma.tfvars` file. Then run the following commands to deploy your Chroma stack.\n\nInitialize Terraform:\n```terminal\nterraform init\n```\n\nPlan the deployment, and review it to ensure it matches your expectations:\n```terminal\nterraform plan -var-file chroma.tfvars\n```\n\nFinally, apply the deployment:\n```terminal\nterraform apply -var-file chroma.tfvars\n```\n\nAfter a few minutes, you can get the IP address of your instance with\n```terminal\nterraform output -raw public_ip_address\n```\n\n### Step 5: Chroma Client Set-Up\n\nOnce your Azure VM instance is up and running with Chroma, all\nyou need to do is configure your `HttpClient` to use the", - "bcd4455f-004a-4416-be8e-9d649a37714a": " server's IP address and port\n`8000`. Since you are running a Chroma server on Azure, our [thin-client package](../chroma-server/python-thin-client) may be enough for your application.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n\n```python\nimport chromadb\n\nchroma_client = chromadb.HttpClient(\n host=\"\",\n port=8000\n)\nchroma_client.heartbeat()\n```\n\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n\n```typescript\nimport { ChromaClient } from \"chromadb\";\n\nconst chromaClient = new ChromaClient({\n path: \"\",\n port: 8000\n})\nchromaClient.heartbeat()\n```\n\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n### Step 5: Clean Up (optional).\n\nTo destroy the stack and remove all Azure resources, use the `terraform destroy` command.\n\n```shell\nterraform destroy -var-file chroma.tfvars\n```\n\n{% Banner type=\"warn\" %}\nThis will destroy all the data in your Chroma database,\nunless you've taken a snapshot or otherwise backed it up.\n{%", - "05c87aea-4558-40fc-ac5a-0eb49145ce5f": " /Banner %}\n\n## Observability with Azure\n\nChroma is instrumented with [OpenTelemetry](https://opentelemetry.io/) hooks for observability. We currently only exports OpenTelemetry [traces](https://opentelemetry.io/docs/concepts/signals/traces/). These should allow you to understand how requests flow through the system and quickly identify bottlenecks. Check out the [observability docs](../administration/observability) for a full explanation of the available parameters.\n\nTo enable tracing on your Chroma server, simply define the following variables in your `chroma.tfvars`:\n\n```text\nchroma_otel_collection_endpoint = \"api.honeycomb.com\"\nchroma_otel_service_name = \"chromadb\"\nchroma_otel_collection_headers = \"{'x-honeycomb-team': 'abc'}\"\n```\n\n# GCP Deployment\n\n{% Banner type=\"tip\" %}\n\n**Hosted Chroma**\n\nChroma Cloud, our fully managed hosted service is here. [Sign up here](https://trychroma.com/signup) for early access.\n\n{% /Banner %}\n\n{% Banner type=\"tip\" %}\n\nIf you are using Chroma in production, please fill out [", - "511c6c3c-2fb7-4bfc-aff5-1a37446802c8": "this form](https://airtable.com/appqd02UuQXCK5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users.\nThis is the best place to\n\n1. Get support with building with Chroma in prod.\n2. Stay up-to-date with exciting new features.\n3. Get swag!\n\nWe would love to help you think through the design of your system, or if you would be a good fit for our upcoming distributed cloud service.\n\n{% /Banner %}\n\n## A Simple GCP Deployment\n\nYou can deploy Chroma on a long-running server, and connect to it\nremotely.\n\nFor convenience, we have\nprovided a very simple Terraform configuration to experiment with\ndeploying Chroma to Google Compute Engine.\n\n{% Banner type=\"warn\" %}\n\nChroma and its underlying database [need at least 2GB of RAM](./performance#results-summary),\nwhich means it won't fit on the instances provided as part of the\nGCP \"always free\" tier. This template uses an [`e2-small`](https://cloud.google.com/compute/docs/general-purpose-machines#e2_machine_types", - "d6b2f828-5c1e-4cf1-8166-9d4264e29c89": ") instance, which\ncosts about two cents an hour, or $15 for a full month, and gives you 2GiB of memory. If you follow these\ninstructions, GCP will bill you accordingly.\n\n{% /Banner %}\n\n{% Banner type=\"warn\" %}\n\nIn this guide we show you how to secure your endpoint using [Chroma's\nnative authentication support](./gcp#authentication-with-gcp). Alternatively, you can put it behind\n[GCP API Gateway](https://cloud.google.com/api-gateway/docs) or add your own\nauthenticating proxy. This basic stack doesn't support any kind of authentication;\nanyone who knows your server IP will be able to add and query for\nembeddings.\n\n{% /Banner %}\n\n{% Banner type=\"warn\" %}\n\nBy default, this template saves all data on a single\nvolume. When you delete or replace it, the data will disappear. For\nserious production use (with high availability, backups, etc.) please\nread and understand the Terraform template and use it as a basis\nfor what you need, or reach out to the Chroma team for assistance.\n\n{% /Banner %}\n\n### Step 1: Set up your G", - "0d058cda-3b4d-4f46-b45e-63b47505d031": "CP credentials\n\nIn your GCP project, create a service account for deploying Chroma. It will need the following roles:\n* Service Account User\n* Compute Admin\n* Compute Network Admin\n* Storage Admin\n\nCreate a JSON key file for this service account, and download it. Set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable to the path of your JSON key file:\n\n```terminal\nexport GOOGLE_APPLICATION_CREDENTIALS=\"/path/to/your/service-account-key.json\"\n```\n\n### Step 2: Install Terraform\n\nDownload [Terraform](https://developer.hashicorp.com/terraform/install?product_intent=terraform) and follow the installation instructions for your OS.\n\n### Step 3: Configure your GCP Settings\n\nCreate a `chroma.tfvars` file. Use it to define the following variables for your GCP project ID, region, and zone:\n\n```text\nproject_id=\"\"\nregion=\"\"\nzone=\"\"\n```\n\n### Step 4: Initialize and deploy with Terraform\n\nDownload our [GCP Terraform configuration](https://github.com/chroma-core/chroma/blob/main/deployments/gcp/main.tf) to the same directory as your `chroma", - "f00d632e-c099-4b0e-9c48-b8e17b5a40fd": ".tfvars` file. Then run the following commands to deploy your Chroma stack.\n\nInitialize Terraform:\n```terminal\nterraform init\n```\n\nPlan the deployment, and review it to ensure it matches your expectations:\n```terminal\nterraform plan -var-file chroma.tfvars\n```\nIf you did not customize our configuration, you should be deploying an `e2-small` instance.\n\nFinally, apply the deployment:\n```terminal\nterraform apply -var-file chroma.tfvars\n```\n\n#### Customize the Stack (optional)\n\nIf you want to use a machine type different from the default `e2-small`, in your `chroma.tfvars` add the `machine_type` variable and set it to your desired machine:\n\n```text\nmachine_type = \"e2-medium\"\n```\n\nAfter a few minutes, you can get the IP address of your instance with\n```terminal\nterraform output -raw chroma_instance_ip\n```\n\n### Step 5: Chroma Client Set-Up\n\nOnce your Compute Engine instance is up and running with Chroma, all\nyou need to do is configure your `HttpClient` to use the server's IP address and port\n`8000`. Since you are running a Chroma server on G", - "60a39b40-3251-4d29-9170-93392ca2e9bf": "CP, our [thin-client package](../chroma-server/python-thin-client) may be enough for your application.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n\n```python\nimport chromadb\n\nchroma_client = chromadb.HttpClient(\n host=\"\",\n port=8000\n)\nchroma_client.heartbeat()\n```\n\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n\n```typescript\nimport { ChromaClient } from \"chromadb\";\n\nconst chromaClient = new ChromaClient({\n path: \"\",\n port: 8000\n})\nchromaClient.heartbeat()\n```\n\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n### Step 5: Clean Up (optional).\n\nTo destroy the stack and remove all GCP resources, use the `terraform destroy` command.\n\n{% note type=\"warning\" title=\"Note\" %}\nThis will destroy all the data in your Chroma database,\nunless you've taken a snapshot or otherwise backed it up.\n{% /note %}\n\n```terminal\nterraform destroy -var-file chroma.tfvars\n```\n\n## Observability with GCP\n\nChroma is instrument", - "f5fdb9d4-bc83-426b-b4cf-1a32bd84ded1": "ed with [OpenTelemetry](https://opentelemetry.io/) hooks for observability. We currently only exports OpenTelemetry [traces](https://opentelemetry.io/docs/concepts/signals/traces/). These should allow you to understand how requests flow through the system and quickly identify bottlenecks. Check out the [observability docs](../administration/observability) for a full explanation of the available parameters.\n\nTo enable tracing on your Chroma server, simply define the following variables in your `chroma.tfvars`:\n\n```text\nchroma_otel_collection_endpoint = \"api.honeycomb.com\"\nchroma_otel_service_name = \"chromadb\"\nchroma_otel_collection_headers = \"{'x-honeycomb-team': 'abc'}\"\n```\n\n# Docker\n\n{% Banner type=\"tip\" %}\n\n**Hosted Chroma**\n\nChroma Cloud, our fully managed hosted service is here. [Sign up here](https://trychroma.com/signup) for early access.\n\n{% /Banner %}\n\n{% Banner type=\"tip\" %}\n\nIf you are using Chroma in production, please fill out [this form](https://airtable.com/appqd02UuQXCK", - "958fefa8-8bcc-4d19-8233-82054eb3193c": "5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users.\nThis is the best place to\n\n1. Get support with building with Chroma in prod.\n2. Stay up-to-date with exciting new features.\n3. Get swag!\n\nWe would love to help you think through the design of your system, or if you would be a good fit for our upcoming distributed cloud service.\n\n{% /Banner %}\n\n## Run Chroma in a Docker Container\n\nYou can run a Chroma server in a Docker container, and access it using the `HttpClient`. We provide images on both [docker.com](https://hub.docker.com/r/chromadb/chroma) and [ghcr.io](https://github.com/chroma-core/chroma/pkgs/container/chroma).\n\nTo start the server, run:\n\n```terminal\ndocker run -v ./chroma-data:/data -p 8000:8000 chroma-core/chroma\n```\n\nThis starts the server with the default configuration and stores data in `./chroma-data` (in your current working directory).\n\nThe Chroma client can then be configured to connect to the server running in", - "fbb55204-f024-4ab5-8231-bf89b5fbf581": " the Docker container.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\nimport chromadb\nchroma_client = chromadb.HttpClient(host='localhost', port=8000)\nchroma_client.heartbeat()\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nimport { ChromaClient } from \"chromadb\";\n\nconst chromaClient = new ChromaClient({ path: \"http://localhost:8000\" })\nchromaClient.heartbeat()\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n{% Banner type=\"tip\" %}\n\n**Client-only package**\n\nIf you're using Python, you may want to use the [client-only package](../chroma-server/python-thin-client) for a smaller install size.\n{% /Banner %}\n\n## Configuration\n\nChroma is configured using a YAML file. Check out [this config file](https://github.com/chroma-core/chroma/blob/main/rust/frontend/sample_configs/single_node_full.yaml) detailing all available options.\n\nTo use a custom config file, mount it into the container at `/config.yaml` like so:\n\n```terminal\necho \"allow_reset: true\" > config.yaml # the server will", - "931d1eb8-6acc-4f5c-97d0-9e3e0a4d5c5a": " now allow clients to reset its state\ndocker run -v ./chroma-data:/data -v ./config.yaml:/config.yaml -p 8000:8000 chroma-core/chroma\n```\n\n## Observability with Docker\n\nChroma is instrumented with [OpenTelemetry](https://opentelemetry.io/) hooks for observability. OpenTelemetry traces allow you to understand how requests flow through the system and quickly identify bottlenecks. Check out the [observability docs](../administration/observability) for a full explanation of the available parameters.\n\nHere's an example of how to create an observability stack with Docker Compose. The stack is composed of\n\n- a Chroma server\n- [OpenTelemetry Collector](https://github.com/open-telemetry/opentelemetry-collector)\n- [Zipkin](https://zipkin.io/)\n\nFirst, paste the following into a new file called `otel-collector-config.yaml`:\n\n```yaml\nreceivers:\n otlp:\n protocols:\n grpc:\n endpoint: 0.0.0.0:4317\n http:\n endpoint: 0.0.0.0:4318\n\nexporters:\n debug:\n", - "75005af4-a32d-4b56-aa98-47afdde5e861": " zipkin:\n endpoint: \"http://zipkin:9411/api/v2/spans\"\n\nservice:\n pipelines:\n traces:\n receivers: [otlp]\n exporters: [zipkin, debug]\n```\n\nThis is the configuration file for the OpenTelemetry Collector:\n* The `receivers` section specifies that the OpenTelemetry protocol (OTLP) will be used to receive data over GRPC and HTTP.\n* `exporters` defines that telemetry data is logged to the console (`debug`), and sent to a `zipkin` server (defined below in `docker-compose.yml`).\n* The `service` section ties everything together, defining a `traces` pipeline receiving data through our `otlp` receiver and exporting data to `zipkin` and via logging.\n\nNext, paste the following into a new file called `docker-compose.yml`:\n\n```yaml\nservices:\n zipkin:\n image: openzipkin/zipkin\n ports:\n - \"9411:9411\"\n depends_on: [otel-collector]\n networks:\n - internal\n otel-collector:\n image: otel/opentelemetry-collector-contrib:0.111.0", - "63393b7c-68ea-4d95-b189-e5c2189014a8": "\n command: [\"--config=/etc/otel-collector-config.yaml\"]\n volumes:\n - ${PWD}/otel-collector-config.yaml:/etc/otel-collector-config.yaml\n networks:\n - internal\n server:\n image: chroma-core/chroma\n volumes:\n - chroma_data:/data\n ports:\n - \"8000:8000\"\n networks:\n - internal\n environment:\n - CHROMA_OPEN_TELEMETRY__ENDPOINT=http://otel-collector:4317/\n - CHROMA_OPEN_TELEMETRY__SERVICE_NAME=chroma\n depends_on:\n - otel-collector\n - zipkin\n\nnetworks:\n internal:\n\nvolumes:\n chroma_data:\n```\n\nTo start the stack, run\n\n```terminal\ndocker compose up --build -d\n```\n\nOnce the stack is running, you can access Zipkin at [http://localhost:9411](http://localhost:9411) when running locally to see your traces.\n\nZipkin will show an empty view initially as no traces are created during startup. You can call the heartbeat endpoint to quickly create a sample trace:\n\n```terminal\ncurl http", - "2edf5a7b-ad76-4eed-8918-79bf5df13676": "://localhost:8000/api/v2/heartbeat\n```\n\nThen, click \"Run Query\" in Zipkin to see the trace.", - "bfbe49ef-bc87-4334-8a39-21ccf7bc70ec": "# Chroma Cloud\n\nOur fully managed hosted service, **Chroma Cloud** is here. You can now [sign up](https://trychroma.com/signup) for early access.\n\nMore documentation for Chroma Cloud users coming soon!", - "d9c5eb7b-ee5b-4198-8256-42ecbeb9b479": "# Ephemeral Client\n\nIn Python, you can run a Chroma server in-memory and connect to it with the ephemeral client:\n\n```python\nimport chromadb\n\nclient = chromadb.Client()\n```\n\nThe `Client()` method starts a Chroma server in-memory and also returns a client with which you can connect to it.\n\nThis is a great tool for experimenting with different embedding functions and retrieval techniques in a Python notebook, for example. If you don't need data persistence, the ephemeral client is a good choice for getting up and running with Chroma.\n\n# Persistent Client\n\n{% Tabs %}\n\n{% Tab label=\"python\" %}\n\nYou can configure Chroma to save and load the database from your local machine, using the `PersistentClient`. \n\nData will be persisted automatically and loaded on start (if it exists).\n\n```python\nimport chromadb\n\nclient = chromadb.PersistentClient(path=\"/path/to/save/to\")\n```\n\nThe `path` is where Chroma will store its database files on disk, and load them on start. If you don't provide a path, the default is `.chroma`\n\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n\nTo connect with the JS/TS client, you", - "da4b9689-d2c0-4218-82bc-ae087d3ba83f": " must connect to a Chroma server. \n\nTo run a Chroma server locally that will persist your data, install Chroma via `pip`:\n\n```terminal\npip install chromadb\n```\n\nAnd run the server using our CLI:\n\n```terminal\nchroma run --path ./getting-started \n```\n\nThe `path` is where Chroma will store its database files on disk, and load them on start. The default is `.chroma`.\n\nAlternatively, you can also use our official Docker image:\n\n```terminal\ndocker pull chromadb/chroma\ndocker run -p 8000:8000 chromadb/chroma\n```\n\nWith a Chroma server running locally, you can connect to it by instantiating a new `ChromaClient`:\n\n```typescript\nimport { ChromaClient } from \"chromadb\";\n\nconst client = new ChromaClient();\n```\n\nSee [Running Chroma in client-server mode](../client-server-mode) for more.\n\n{% /Tab %}\n\n{% /Tabs %}\n\nThe client object has a few useful convenience methods.\n\n* `heartbeat()` - returns a nanosecond heartbeat. Useful for making sure the client remains connected.\n* `reset()` - empties and completely resets the database.", - "a9f5d67d-eca9-4c79-9ca9-76c0c39b0bcd": " \u26a0\ufe0f This is destructive and not reversible.\n\n{% TabbedCodeBlock %}\n\n{% Tab label=\"python\" %}\n```python\nclient.heartbeat()\nclient.reset()\n```\n{% /Tab %}\n\n{% Tab label=\"typescript\" %}\n```typescript\nawait client.heartbeat();\nawait client.reset();\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n# The Python HTTP-Only Client\n\nIf you are running Chroma in client-server mode, where you run a Chroma server and client on separate machines, you may not need the full Chroma package where you run your client. Instead, you can use the lightweight client-only library.\nIn this case, you can install the `chromadb-client` package. This package is a lightweight HTTP client for the server with a minimal dependency footprint.\n\nOn your server, install chroma with\n\n```terminal\npip install chromadb\n```\n\nAnd run a Chroma server:\n\n```terminal\nchroma run --path [path/to/persist/data]\n```\n\nThen, on your client side, install the HTTP-only client: \n\n```terminal\npip install chromadb-client\n```\n\n```python\nimport chromadb\n# Example setup of the client to connect to your", - "804bd06e-a06c-40ae-8e65-3b67fcdc9e98": " chroma server\nclient = chromadb.HttpClient(host='localhost', port=8000)\n\n# Or for async usage:\nasync def main():\n client = await chromadb.AsyncHttpClient(host='localhost', port=8000)\n```\n\nNote that the `chromadb-client` package is a subset of the full Chroma library and does not include all the dependencies. If you want to use the full Chroma library, you can install the `chromadb` package instead.\nMost importantly, there is no default embedding function. If you add() documents without embeddings, you must have manually specified an embedding function and installed the dependencies for it.\n\n", - "23b672d3-b78e-4962-8566-dacd71f36b20": "\n Chroma provides a convenient wrapper around OpenAI's embedding API. This embedding function runs remotely on OpenAI's servers, and requires an API key. You can get an API key by signing up for an account at OpenAI.\n\n The following OpenAI Embedding Models are supported:\n\n text-embedding-ada-002\n text-embedding-3-small\n text-embedding-3-large\n ", - "da28e3f0-172e-4fbb-a725-a83bc597eec2": "\n import chromadb.utils.embedding_functions as embedding_functions\n\n # This embedding function relies on the openai python package, which you can install with pip install openai\n # You can pass in an optional model_name argument, which lets you choose which OpenAI embeddings model to use. By default, Chroma uses text-embedding-ada-002\n openai_ef = embedding_functions.OpenAIEmbeddingFunction(\n api_key=\"YOUR_API_KEY\",\n model_name=\"text-embedding-3-small\"\n )\n\n ", - "1bad6831-530a-464d-a1d8-6b3993f54add": "\n import chromadb.utils.embedding_functions as embedding_functions\n\n # To use the OpenAI embedding models on other platforms such as Azure, you can use the api_base and api_type parameters\n openai_ef = embedding_functions.OpenAIEmbeddingFunction(\n api_key=\"YOUR_API_KEY\",\n api_base=\"YOUR_API_BASE_PATH\",\n api_type=\"azure\",\n api_version=\"YOUR_API_VERSION\",\n model_name=\"text-embedding-3-small\"\n )\n ", - "6e8f15f0-d410-4a91-a17e-fdf6915159a1": "\n Integrations\n Embedding Integrations\n Embeddings are the A.I-native way to represent any kind of data, making them the perfect fit for working with all kinds of A.I-powered tools and algorithms. They can represent text, images, and soon audio and video. There are many options for creating embeddings, whether locally using an installed library, or by calling an API.\n\n Chroma provides lightweight wrappers around popular embedding providers, making it easy to use them in your apps. You can set an embedding function when you create a Chroma collection, which will be used automatically, or you can call them directly yourself.\n\n Python\tTypescript\n OpenAI\t\u2713\t\u2713\n Google Gemini\t\u2713\t\u2713\n Cohere\t\u2713\t\u2713\n Hugging Face\t\u2713\t-\n Instructor\t\u2713\t-\n Hugging Face Embedding Server\t\u2713\t\u2713\n Jina AI\t\u2713\t\u2713\n Roboflow\t\u2713\t-\n Ollama Embeddings\t\u2713\t\u2713\n ", - "e533be95-fd5c-431e-ab8f-2024f9230f7d": "\n # typescript\n import { OpenAIEmbeddingFunction } from 'chromadb';\n\n const embeddingFunction = new OpenAIEmbeddingFunction({\n openai_api_key: \"apiKey\",\n openai_model: \"text-embedding-3-small\"\n })\n\n // use directly\n const embeddings = embeddingFunction.generate([\"document1\",\"document2\"])\n\n // pass documents to query for .add and .query\n let collection = await client.createCollection({\n name: \"name\",\n embeddingFunction: embeddingFunction\n })\n collection = await client.getCollection({\n name: \"name\",\n embeddingFunction: embeddingFunction\n })\n ", - "810d83cd-d9f3-4684-8278-7fa791fe0a6b": "\n Chroma supports filtering queries by metadata and document contents. The where filter is used to filter by metadata.\n\n In order to filter on metadata, you must supply a where filter dictionary to the query. The dictionary must have the following structure:\n\n\n {\n \"metadata_field\": {\n : \n }\n }\n ", - "1a9dd199-f115-461e-9150-d7cec42b48c3": "\n Filtering metadata supports the following operators:\n\n $eq - equal to (string, int, float)\n $ne - not equal to (string, int, float)\n $gt - greater than (int, float)\n $gte - greater than or equal to (int, float)\n $lt - less than (int, float)\n $lte - less than or equal to (int, float)}\n }\n ", - "7be5a036-f44c-421a-b991-4502ff156fc9": "\n # Using the $eq operator is equivalent to using the where filter\n {\n \"metadata_field\": \"search_string\"\n }\n\n # is equivalent to\n\n {\n \"metadata_field\": {\n \"$eq\": \"search_string\"\n }\n }\n ", - "91733155-aced-48e8-bcc1-633e7c4dc063": "\n # An $and operator will return results that match all of the filters in the list.\n {\n \"$and\": [\n {\n \"metadata_field\": {\n : \n }\n },\n {\n \"metadata_field\": {\n : \n }\n }\n ]\n }\n\n ", - "e9844780-3e02-44bf-8c87-1fc07cacaa9e": "\n # An $or operator will return results that match any of the filters in the list.\n {\n \"$or\": [\n {\n \"metadata_field\": {\n : \n }\n },\n {\n \"metadata_field\": {\n : \n }\n }\n ]\n }\n ", - "9eb472ea-0fe8-4bc7-94d9-1f276b44b405": "\n Using inclusion operators ($in and $nin)\n The following inclusion operators are supported:\n\n $in - a value is in predefined list (string, int, float, bool)\n $nin - a value is not in predefined list (string, int, float, bool)\n An $in operator will return results where the metadata attribute is part of a provided list:\n ", - "546bed72-047c-4cd5-b972-fb9ce1f27729": "\n Running Chroma in Client-Server Mode\n Chroma can also be configured to run in client/server mode. In this mode, the Chroma client connects to a Chroma server running in a separate process.\n\n To start the Chroma server, run the following command:\n\n\n chroma run --path /db_path\n ", - "f2bed968-9bd7-4971-b96a-31aee84b3a61": "\n # Running Chroma in Client-Server Mode in Typescript\n import { ChromaClient } from \"chromadb\";\n\n const client = new ChromaClient();\n ", - "21ebdb13-c86f-4240-8eab-bedb5fc3b1eb": "\n import chromadb\n # use the Chroma HTTP client to connect to the server\n chroma_client = chromadb.HttpClient(host='localhost', port=8000)\n\n ", - "96afecb6-223c-4904-868b-a856ded61c0a": "\n import asyncio\n import chromadb\n\n # to use AsyncHttpClient instead\n async def main():\n client = await chromadb.AsyncHttpClient()\n\n collection = await client.create_collection(name=\"my_collection\")\n await collection.add(\n documents=[\"hello world\"],\n ids=[\"id1\"]\n )\n\n asyncio.run(main())\n ", - "842ac88a-2f77-452f-ac42-99cd8e715ef6": "\n collection.update(\n ids=[\"id1\", \"id2\", \"id3\", ...],\n embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],\n metadatas=[{\"chapter\": \"3\", \"verse\": \"16\"}, {\"chapter\": \"3\", \"verse\": \"5\"}, {\"chapter\": \"29\", \"verse\": \"11\"}, ...],\n documents=[\"doc1\", \"doc2\", \"doc3\", ...],\n )\n ", - "3e8cc591-aa06-4f76-90ae-ee1e284c29fd": "\n Any property of records in a collection can be updated with .update\n\n If an id is not found in the collection, an error will be logged and the update will be ignored. If documents are supplied without corresponding embeddings, the embeddings will be recomputed with the collection's embedding function.\n\n If the supplied embeddings are not the same dimension as the collection, an exception will be raised.\n ", - "43337400-f66e-46bf-a656-aef993fd7344": "\n # upsert operation updates existing items, or adds them if they don't yet exist (Python)\n collection.upsert(\n ids=[\"id1\", \"id2\", \"id3\", ...],\n embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],\n metadatas=[{\"chapter\": \"3\", \"verse\": \"16\"}, {\"chapter\": \"3\", \"verse\": \"5\"}, {\"chapter\": \"29\", \"verse\": \"11\"}, ...],\n documents=[\"doc1\", \"doc2\", \"doc3\", ...],\n )\n ", - "07741cbe-7ae8-4cb9-b841-77ea2caa7eb3": "\n await collection.update({\n ids: [\"id1\", \"id2\", \"id3\", ...], \n embeddings: [[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...], \n metadatas: [{\"chapter\": \"3\", \"verse\": \"16\"}, {\"chapter\": \"3\", \"verse\": \"5\"}, {\"chapter\": \"29\", \"verse\": \"11\"}, ...], \n documents: [\"doc1\", \"doc2\", \"doc3\", ...]\n })\n\n ", - "bc68272d-b038-4f5f-9132-74d07dd010e3": "\n # upsert operation updates existing items, or adds them if they don't yet exist (Python)\n await collection.upsert({\n ids: [\"id1\", \"id2\", \"id3\"],\n embeddings: [\n [1.1, 2.3, 3.2],\n [4.5, 6.9, 4.4],\n [1.1, 2.3, 3.2],\n ],\n metadatas: [\n { chapter: \"3\", verse: \"16\" },\n { chapter: \"3\", verse: \"5\" },\n { chapter: \"29\", verse: \"11\" },\n ],\n documents: [\"doc1\", \"doc2\", \"doc3\"],\n });\n " -} \ No newline at end of file diff --git a/sample_apps/generative_benchmarking/data/chroma_docs.txt b/sample_apps/generative_benchmarking/data/chroma_docs.txt new file mode 100644 index 00000000000..cb57625e186 --- /dev/null +++ b/sample_apps/generative_benchmarking/data/chroma_docs.txt @@ -0,0 +1,216 @@ +# Full Text Search\n\nIn order to filter on document contents, you must supply a `where_document` filter dictionary to the query. We support two filtering keys: `$contains` and `$not_contains`. The dictionary must have the following structure:\n\n```python\n# Filtering for a search_string\n{\n "$contains": "search_string"\n}\n\n# Filtering for not contains\n{\n "$not_contains": "search_string"\n}\n```\n\nYou can combine full-text search with Chroma's metadata filtering.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\ncollection.query(\n query_texts=["doc10", "thus spake zarathustra", ...],\n n_results=10,\n where={"metadata_field": "is_equal_to_this"},\n where_document={"$contains":"search_string"}\n)\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nawait collection.query({\n queryTexts: ["doc10", "thus spake zarathustra", ...],\n nResults: 10,\n where: {"metadata_field": "is_equal_to_this"},\n whereDocument: {"$contains": "search_string"}\n})\n```\n\n# Query and Get Data from +Chroma Collections\n\nChroma collections can be queried in a variety of ways, using the `.query` method.\n\nYou can query by a set of `query embeddings`.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\ncollection.query(\n query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],\n n_results=10,\n where={"metadata_field": "is_equal_to_this"},\n where_document={"$contains":"search_string"}\n)\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nconst result = await collection.query({\n queryEmbeddings: [[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],\n nResults: 10,\n where: {"metadata_field": "is_equal_to_this"},\n})\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nThe query will return the `n results` closest matches to each `query embedding`, in order.\nAn optional `where` filter dictionary can be supplied to filter by the `metadata` +associated with each document.\nAdditionally, an optional `where document` filter dictionary can be supplied to filter by contents of the document.\n\nIf the supplied `query embeddings` are not the same dimension as the collection, an exception will be raised.\n\nYou can also query by a set of `query texts`. Chroma will first embed each `query text` with the collection's embedding function, and then perform the query with the generated embedding.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\ncollection.query(\n query_texts=["doc10", "thus spake zarathustra", ...],\n n_results=10,\n where={"metadata_field": "is_equal_to_this"},\n where_document={"$contains":"search_string"}\n)\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nawait collection.query({\n queryTexts: ["doc10", "thus spake zarathustra", ...],\n nResults: 10,\n where: {"metadata_field": "is_equal_to_this"},\n whereDocument: {"$contains": "search_string"}\n})\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nYou can also retrieve items from a +collection by `id` using `.get`.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\ncollection.get(\n\tids=["id1", "id2", "id3", ...],\n\twhere={"style": "style1"}\n)\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nawait collection.get( {\n ids: ["id1", "id2", "id3", ...],\n where: {"style": "style1"}\n})\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n`.get` also supports the `where` and `where document` filters. If no `ids` are supplied, it will return all items in the collection that match the `where` and `where document` filters.\n\n### Choosing Which Data is Returned\n\nWhen using get or query you can use the `include` parameter to specify which data you want returned - any of `embeddings`, `documents`, `metadatas`, and for query, `distances`. By default, Chroma will return the `documents`, `metadatas` and in the case of query, the `distances` of the results. `embeddings` +are excluded by default for performance and the `ids` are always returned. You can specify which of these you want returned by passing an array of included field names to the includes parameter of the query or get method. Note that embeddings will be returned as a 2-d numpy array in `.get` and a python list of 2-d numpy arrays in `.query`.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\n# Only get documents and ids\ncollection.get(\n include=["documents"]\n)\n\ncollection.query(\n query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],\n include=["documents"]\n)\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\n// Only get documents and ids\nawait collection.get({\n include: ["documents"]\n})\n\nawait collection.query({\n query_embeddings: [[11.1, 12.1, 13.1], [1.1, 2.3, 3.2], ...],\n include: ["documents"]\n})\n```\n +# About\n\nWe are hiring software engineers and applied research scientists.\n\n## Who we are\n\nChroma as a project is coordinated by a small team of full-time employees who work at a company also called Chroma.\n\nWe work in the sunny Mission District in San Francisco.\n\nChroma was co-founded by [Jeff Huber](https://twitter.com/jeffreyhuber) (left, CEO) and [Anton Troynikov](https://twitter.com/atroyn) (right, now Advisor).\n\n\n## Our commitment to open source\n\nChroma is a company that builds the open-source project also called Chroma.\n\nWe are committed to building open source software because we believe in the flourishing of humanity that will be unlocked through the democratization of robust, safe, and aligned AI systems. These tools need to be available to a new developer just starting in ML as well as the organizations that scale ML to millions (and billions) of users. Open source is about expanding the horizon of what\u2019s possible.\n\nChroma is a _commercial_ open source company. What does that mean? We believe that organizing financially sustainable teams of people to work to manage, push and integrate the project enriches the health of the project and the community.\n\n +It is important that our values around this are very clear!\n\n- We are committed to building Chroma as a ubiquitous open source standard\n- A successful Chroma-based commercial product is essential for the success of the technology, and is a win-win for everyone. Simply put, many organizations will not adopt Chroma without the option of a commercially hosted solution; and the project must be backed by a company with a viable business model. We want to build an awesome project and an awesome business.\n- We will decide what we provide exclusively in the commercial product based on clear, consistent criteria.\n\nWhat code will be open source? As a general rule, any feature which an individual developer would find useful will be 100% open source forever. This approach, popularized by Gitlab, is called [buyer-based open source](https://about.gitlab.com/company/stewardship/). We believe that this is essential to accomplishing our mission.\n\nCurrently we don\u2019t have any specific plans to monetize Chroma, we are working on a hosted service that will be launched as a free technical preview to make it easier for developers to get going. We are 100% focused on building valuable open source software with the community and for the community.\n\n\n## Our +investors\n\nChroma raised an $18M seed round led by Astasia Myers from Quiet Capital. Joining the round are angels including Naval Ravikant, Max and Jack Altman, Jordan Tigani (Motherduck), Guillermo Rauch (Vercel), Akshay Kothari (Notion), Amjad Masad (Replit), Spencer Kimball (CockroachDB), and other founders and leaders from ScienceIO, Gumroad, MongoDB, Scale, Hugging Face, Jasper and more.\n\nChroma raised a pre-seed in May 2022, led by Anthony Goldbloom (Kaggle) from AIX Ventures, James Cham from Bloomberg Beta, and Nat Friedman and Daniel Gross (AI Grant).\n\nWe're excited to work with a deep set of investors and enterpreneurs who have invested in and built some of the most successful open-source projects in the world.\n\n# Contributing\n\nWe welcome all contributions, bug reports, bug fixes, documentation improvements, enhancements, and ideas.\n\n## Getting Started\nHere are some helpful links to get you started with contributing to Chroma\n\n- The Chroma codebase is hosted on [Github](https://github.com/chroma-core/chroma)\n- Issues are +tracked on [Github Issues](https://github.com/chroma-core/chroma/issues). Please report any issues you find there making sure to fill out the correct [form for the type of issue you are reporting](https://github.com/chroma-core/chroma/issues/new/choose).\n- In order to run Chroma locally you can follow the [Development Instructions](https://github.com/chroma-core/chroma/blob/main/DEVELOP.md).\n- If you want to contribute and aren't sure where to get started you can search for issues with the [Good first issue](https://github.com/chroma-core/chroma/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) tag or take a look at our [Roadmap](https://docs.trychroma.com/roadmap).\n- The Chroma documentation (including this page!) is hosted on [Github](https://github.com/chroma-core/docs) as well. If you find any issues with the documentation please report them on the Github Issues page for the documentation [here](https://github.com/chroma-core/docs/issues).\n\n\n## Contributing Code and Ideas\n\n### Pull Requests\nIn order to submit a +change to Chroma please submit a [Pull Request](https://github.com/chroma-core/chroma/compare) against Chroma or the documentation. The pull request will be reviewed by the Chroma team and if approved, will be merged into the repository. We will do our best to review pull requests in a timely manner but please be patient as we are a small team. We will work to integrate your proposed changes as quickly as possible if they align with the goals of the project. We ask that you label your pull request with a title prefix that indicates the type of change you are proposing. The following prefixes are used:\n\n```\nENH: Enhancement, new functionality\nBUG: Bug fix\nDOC: Additions/updates to documentation\nTST: Additions/updates to tests\nBLD: Updates to the build process/scripts\nPERF: Performance improvement\nTYP: Type annotations\nCLN: Code cleanup\nCHORE: Maintenance and other tasks that do not modify source or test files\n```\n\n\n### CIPs\nChroma Improvement Proposals or CIPs (pronounced "Chips") are the way to propose new features or large changes to Chroma. If you plan to make a large change to +Chroma please submit a CIP first so that the core Chroma team as well as the community can discuss the proposed change and provide feedback. A CIP should provide a concise technical specification of the feature and a rationale for why it is needed. The CIP should be submitted as a pull request to the [CIPs folder](https://github.com/chroma-core/chroma/tree/main/docs). The CIP will be reviewed by the Chroma team and if approved will be merged into the repository. To learn more about writing a CIP you can read the [guide](https://github.com/chroma-core/chroma/blob/main/docs/CIP_Chroma_Improvment_Proposals.md). CIPs are not required for small changes such as bug fixes or documentation updates.\n\nA CIP starts in the "Proposed" state, then moves to "Under Review" once the Chroma team has reviewed it and is considering it for implementation. Once the CIP is approved it will move to the "Accepted" state and the implementation can begin. Once the implementation is complete the CIP will move to the "Implemented" state. If the CIP is not approved it will move to the "Rejected" state. If the +CIP is withdrawn by the author it will move to the "Withdrawn" state.\n\n\n### Discord\nFor less fleshed out ideas you want to discuss with the community, you can join our [Discord](https://discord.gg/Fk2pH7k6) and chat with us in the #feature-ideas channel. We are always happy to discuss new ideas and features with the community.\n\n\n# Getting Started\n\nChroma is an AI-native open-source vector database. It comes with everything you need to get started built in, and runs on your machine. A [hosted version](https://trychroma.com/signup) is now available for early access!\n\n### 1. Install\n\n{% Tabs %}\n\n{% Tab label="python" %}\n\n```terminal\npip install chromadb\n```\n\n{% /Tab %}\n\n{% Tab label="typescript" %}\n\n{% TabbedUseCaseCodeBlock language="Terminal" %}\n\n{% Tab label="yarn" %}\n```terminal\nyarn add chromadb chromadb-default-embed \n```\n{% /Tab %}\n\n{% Tab label="npm" %}\n```terminal\nnpm install --save chromadb chromadb-default-embed\n```\n{% /Tab %}\n\n{% Tab +label="pnpm" %}\n```terminal\npnpm add chromadb chromadb-default-embed \n```\n{% /Tab %}\n\n{% /TabbedUseCaseCodeBlock %}\n\nInstall chroma via `pip` to easily run the backend server. Here are [instructions](https://pip.pypa.io/en/stable/installation/) for installing and running `pip`. Alternatively, you can also run Chroma in a [Docker](../../production/containers/docker) container.\n\n```terminal\npip install chromadb\n```\n\n{% /Tab %}\n\n{% /Tabs %}\n\n### 2. Create a Chroma Client\n\n{% Tabs %}\n\n{% Tab label="python" %}\n```python\nimport chromadb\nchroma_client = chromadb.Client()\n```\n{% /Tab %}\n{% Tab label="typescript" %}\n\nRun the Chroma backend:\n\n{% TabbedUseCaseCodeBlock language="Terminal" %}\n\n{% Tab label="CLI" %}\n```terminal\nchroma run --path ./getting-started \n```\n{% /Tab %}\n\n{% Tab label="Docker" %}\n```terminal\ndocker pull chromadb/chroma\ndocker run -p 8000:8000 chromadb/chroma---\n\n\n# Chrom +a\n\n**Chroma is the open-source AI application database**. Chroma makes it easy to build LLM apps by making knowledge, facts, and skills pluggable for LLMs.\n\n{% Banner type="tip" %}\nNew to Chroma? Check out the [getting started guide](./getting-started)\n{% /Banner %}\n\n![Chroma Computer](/computer.svg)\n\nChroma gives you everything you need for retrieval:\n\n- Store embeddings and their metadata\n- Vector search\n- Full-text search\n- Document storage\n- Metadata filtering\n- Multi-modal retrieval\n\nChroma runs as a server and provides `Python` and `JavaScript/TypeScript` client SDKs. Check out the [Colab demo](https://colab.research.google.com/drive/1QEzFyqnoFxq7LUGyP1vzR4iLt9PpCDXv?usp=sharing) (yes, it can run in a Jupyter notebook).\n\nChroma is licensed under [Apache 2.0](https://github.com/chroma-core/chroma/blob/main/LICENSE)\n\n### Python\nIn Python, Chroma can run in a python script or as a server. Install Chroma +with\n\n```shell\npip install chromadb\n```\n\n### JavaScript\nIn JavaScript, use the Chroma JS/TS Client to connect to a Chroma server. Install Chroma with your favorite package manager:\n\n{% TabbedUseCaseCodeBlock language="Terminal" %}\n\n{% Tab label="yarn" %}\n```terminal\nyarn add chromadb chromadb-default-embed \n```\n{% /Tab %}\n\n{% Tab label="npm" %}\n```terminal\nnpm install --save chromadb chromadb-default-embed\n```\n{% /Tab %}\n\n{% Tab label="pnpm" %}\n```terminal\npnpm install chromadb chromadb-default-embed \n```\n{% /Tab %}\n\n{% /TabbedUseCaseCodeBlock %}\n\n\nContinue with the full [getting started guide](./getting-started).\n\n\n***\n\n## Language Clients\n\n| Language | Client |\n|---------------|--------------------------------------------------------------------------------------------------------------------------|\n| Python | [`chromadb`](https://pypistats.org/packages/chromadb) (by Chroma) |\n| Javascript | [`chromadb`](https://www.npmjs.com/package/chromadb) (by Chroma) |\n| Ruby | [from @mario +chavez](https://github.com/mariochavez/chroma) |\n| Java | [from @t_azarov](https://github.com/amikos-tech/chromadb-java-client) |\n| Go | [from @t_azarov](https://github.com/amikos-tech/chroma-go) |\n| C# | [from @microsoft](https://github.com/microsoft/semantic-kernel/tree/main/dotnet/src/Connectors/Connectors.Memory.Chroma) |\n| Rust | [from @Anush008](https://crates.io/crates/chromadb) |\n| Elixir | [from @3zcurdia](https://hex.pm/packages/chroma/) |\n| Dart | [from @davidmigloz](https://pub.dev/packages/chromadb) |\n| PHP | [from @CodeWithKyrian](https://github.com/CodeWithKyrian/chromadb-php) |\n| PHP (Laravel) | [from @HelgeSverre](https://github.com/helgeSverre/chromadb) |\n| Clojure | [from @levand +](https://github.com/levand/clojure-chroma-client) |\n| R | [from @cynkra](https://cynkra.github.io/rchroma/) |\n| C++ | [from @BlackyDrum](https://github.com/BlackyDrum/chromadb-cpp) |\n\n\n{% br %}{% /br %}\n\nWe welcome [contributions](/markdoc/content/docs/overview/contributing.md) for other languages!\n\n```\n{% /Tab %}\n\n{% /TabbedUseCaseCodeBlock %}\n\nThen create a client which connects to it:\n\n{% TabbedUseCaseCodeBlock language="typescript" %}\n\n{% Tab label="ESM" %}\n```typescript\nimport { ChromaClient } from "chromadb";\nconst client = new ChromaClient();\n```\n{% /Tab %}\n\n{% Tab label="CJS" %}\n```typescript\nconst { ChromaClient } = require("chromadb");\nconst client = new ChromaClient();\n```\n{% /Tab %}\n\n{% /TabbedUseCaseCodeBlock %}\n\n{% /Tab %}\n\n{% /Tabs %}\n\n### 3. Create a collection\n\nCollections are where +you'll store your embeddings, documents, and any additional metadata. Collections index your embeddings and documents, and enable efficient retrieval and filtering. You can create a collection with a name:\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\ncollection = chroma_client.create_collection(name="my_collection")\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nconst collection = await client.createCollection({\n name: "my_collection",\n});\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n### 4. Add some text documents to the collection\n\nChroma will store your text and handle embedding and indexing automatically. You can also customize the embedding model. You must provide unique string IDs for your documents.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\ncollection.add(\n documents=[\n "This is a document about pineapple",\n "This is a document about oranges"\n ],\n ids=["id1", "id2"]\n)\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nawait collection.add({\n documents: [\n "This is a document about pineapple",\n "This is a document +about oranges",\n ],\n ids: ["id1", "id2"],\n});\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n### 5. Query the collection\n\nYou can query the collection with a list of query texts, and Chroma will return the `n` most similar results. It's that easy!\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\nresults = collection.query(\n query_texts=["This is a query document about hawaii"], # Chroma will embed this for you\n n_results=2 # how many results to return\n)\nprint(results)\n```\n\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nconst results = await collection.query({\n queryTexts: "This is a query document about hawaii", // Chroma will embed this for you\n nResults: 2, // how many results to return\n});\n\nconsole.log(results);\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nIf `n_results` is not provided, Chroma will return 10 results by default. Here we only added 2 documents, so we set `n_results=2`.\n\n### +6. Inspect Results\n\nFrom the above query - you can see that our query about `hawaii` is the semantically most similar to the document about `pineapple`.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\n{\n 'documents': [[\n 'This is a document about pineapple',\n 'This is a document about oranges'\n ]],\n 'ids': [['id1', 'id2']],\n 'distances': [[1.0404009819030762, 1.243080496788025]],\n 'uris': None,\n 'data': None,\n 'metadatas': [[None, None]],\n 'embeddings': None,\n}\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\n{\n documents: [\n [\n 'This is a document about pineapple', \n 'This is a document about oranges'\n ]\n ], \n ids: [\n ['id1', 'id2']\n ], \n distances: [[1.0404009819030762, 1.243080496788025]],\n uris: null,\n data: null,\n metadatas +: [[null, null]],\n embeddings: null\n}\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n### 7. Try it out yourself\n\nFor example - what if we tried querying with `"This is a document about florida"`?\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\nimport chromadb\nchroma_client = chromadb.Client()\n\n# switch `create_collection` to `get_or_create_collection` to avoid creating a new collection every time\ncollection = chroma_client.get_or_create_collection(name="my_collection")\n\n# switch `add` to `upsert` to avoid adding the same documents every time\ncollection.upsert(\n documents=[\n "This is a document about pineapple",\n "This is a document about oranges"\n ],\n ids=["id1", "id2"]\n)\n\nresults = collection.query(\n query_texts=["This is a query document about florida"], # Chroma will embed this for you\n n_results=2 # how many results to return\n)\n\nprint(results)\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nimport { ChromaClient } from "chromadb";\nconst client = new +ChromaClient();\n\n// switch `createCollection` to `getOrCreateCollection` to avoid creating a new collection every time\nconst collection = await client.getOrCreateCollection({\n name: "my_collection",\n});\n\n// switch `addRecords` to `upsertRecords` to avoid adding the same documents every time\nawait collection.upsert({\n documents: [\n "This is a document about pineapple",\n "This is a document about oranges",\n ],\n ids: ["id1", "id2"],\n});\n\nconst results = await collection.query({\n queryTexts: "This is a query document about florida", // Chroma will embed this for you\n nResults: 2, // how many results to return\n});\n\nconsole.log(results);\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n## Next steps\n\nIn this guide we used Chroma's [ephemeral client](../run-chroma/ephemeral-client) for simplicity. It starts a Chroma server in-memory, so any data you ingest will be lost when your program terminates. You can use the [persistent client](../run-chroma/persistent-client) or run Chroma in [client-server mode](../run-ch +roma/client-server) if you need data persistence.\n\n- Learn how to [Deploy Chroma](../../production/deployment) to a server\n- Join Chroma's [Discord Community](https://discord.com/invite/MMeYNTmh3x) to ask questions and get help\n- Follow Chroma on [Twitter (@trychroma)](https://twitter.com/trychroma) for updates\n\n# Chroma\n\n**Chroma is the open-source AI application database**. Chroma makes it easy to build LLM apps by making knowledge, facts, and skills pluggable for LLMs.\n\n{% Banner type="tip" %}\nNew to Chroma? Check out the [getting started guide](./getting-started)\n{% /Banner %}\n\n![Chroma Computer](/computer.svg)\n\nChroma gives you everything you need for retrieval:\n\n- Store embeddings and their metadata\n- Vector search\n- Full-text search\n- Document storage\n- Metadata filtering\n- Multi-modal retrieval\n\nChroma runs as a server and provides `Python` and `JavaScript/TypeScript` client SDKs. Check out the [Colab demo](https://colab.research.google.com/drive/1QEzFy +qnoFxq7LUGyP1vzR4iLt9PpCDXv?usp=sharing) (yes, it can run in a Jupyter notebook).\n\nChroma is licensed under [Apache 2.0](https://github.com/chroma-core/chroma/blob/main/LICENSE)\n\n### Python\nIn Python, Chroma can run in a python script or as a server. Install Chroma with\n\n```shell\npip install chromadb\n```\n\n### JavaScript\nIn JavaScript, use the Chroma JS/TS Client to connect to a Chroma server. Install Chroma with your favorite package manager:\n\n{% TabbedUseCaseCodeBlock language="Terminal" %}\n\n{% Tab label="yarn" %}\n```terminal\nyarn add chromadb chromadb-default-embed \n```\n{% /Tab %}\n\n{% Tab label="npm" %}\n```terminal\nnpm install --save chromadb chromadb-default-embed\n```\n{% /Tab %}\n\n{% Tab label="pnpm" %}\n```terminal\npnpm install chromadb chromadb-default-embed \n```\n{% /Tab %}\n\n{% /TabbedUseCaseCodeBlock %}\n\n\nContinue with the full [getting started guide](./getting +-started).\n\n\n***\n\n## Language Clients\n\n| Language | Client |\n|---------------|--------------------------------------------------------------------------------------------------------------------------|\n| Python | [`chromadb`](https://pypistats.org/packages/chromadb) (by Chroma) |\n| Javascript | [`chromadb`](https://www.npmjs.com/package/chromadb) (by Chroma) |\n| Ruby | [from @mariochavez](https://github.com/mariochavez/chroma) |\n| Java | [from @t_azarov](https://github.com/amikos-tech/chromadb-java-client) |\n| Go | [from @t_azarov](https://github.com/amikos-tech/chroma-go) |\n| C# | [from @microsoft](https://github.com/microsoft/semantic-kernel/tree/main/dotnet/src/Connectors/Connectors.Memory.Chroma) |\n| Rust | [from @Anush008](https://crates.io/crates/chromadb) |\n| Elixir | [from @3zcurdia](https://hex.pm/packages/chroma/) |\n| Dart | [from @david +migloz](https://pub.dev/packages/chromadb) |\n| PHP | [from @CodeWithKyrian](https://github.com/CodeWithKyrian/chromadb-php) |\n| PHP (Laravel) | [from @HelgeSverre](https://github.com/helgeSverre/chromadb) |\n| Clojure | [from @levand](https://github.com/levand/clojure-chroma-client) |\n| R | [from @cynkra](https://cynkra.github.io/rchroma/) |\n| C++ | [from @BlackyDrum](https://github.com/BlackyDrum/chromadb-cpp) |\n\n\n{% br %}{% /br %}\n\nWe welcome [contributions](/markdoc/content/docs/overview/contributing.md) for other languages!\n\n\n# Roadmap\n\nThe goal of this doc is to align *core* and *community* efforts for the project and to share what's in store for this year!\n\n**Sections**\n- What is the core Chroma team working on right now?\n- What will Chroma prioritize over the next +6mo?\n- What areas are great for community contributions?\n\n## What is the core Chroma team working on right now?\n\n- Standing up that distributed system as a managed service (aka "Hosted Chroma" - [sign up for waitlist](https://trychroma.com/signup)!)\n\n## What did the Chroma team just complete?\n\nFeatures like:\n- *New* - [Chroma 0.4](https://www.trychroma.com/blog/chroma_0.4.0) - our first production-oriented release\n- A more minimal python-client only build target\n- Google PaLM embedding support\n- OpenAI ChatGPT Retrieval Plugin\n\n## What will Chroma prioritize over the next 6mo?\n\n**Next Milestone: \u2601\ufe0f Launch Hosted Chroma**\n\n**Areas we will invest in**\n\nNot an exhaustive list, but these are some of the core team\u2019s biggest priorities over the coming few months. Use caution when contributing in these areas and please check-in with the core team first.\n\n- **Workflow**: Building tools for answer questions like: what embedding model should I use? And how should I chunk up my documents?\n- **Visualization**: Building visualization tool to give developers greater intuition +embedding spaces\n- **Query Planner**: Building tools to enable per-query and post-query transforms\n- **Developer experience**: Extending Chroma into a CLI\n- **Easier Data Sharing**: Working on formats for serialization and easier data sharing of embedding Collections\n- **Improving recall**: Fine-tuning embedding transforms through human feedback\n- **Analytical horsepower**: Clustering, deduplication, classification and more\n\n## What areas are great for community contributions?\n\nThis is where you have a lot more free reign to contribute (without having to sync with us first)!\n\nIf you're unsure about your contribution idea, feel free to chat with us (@chroma) in the `#general` channel in [our Discord](https://discord.gg/rahcMUU5XV)! We'd love to support you however we can.\n\n### Example Templates\n\nWe can always use [more integrations](../../integrations/chroma-integrations) with the rest of the AI ecosystem. Please let us know if you're working on one and need help!\n\nOther great starting points for Chroma (please send PRs for more [here](https://github.com/chroma-core/docs/tree/swyx/addRoadmap/docs)):\n- [Google Col +ab](https://colab.research.google.com/drive/1QEzFyqnoFxq7LUGyP1vzR4iLt9PpCDXv?usp=sharing)\n- [Replit Template](https://replit.com/@swyx/BasicChromaStarter?v=1)\n\nFor those integrations we do have, like LangChain and LlamaIndex, we do always want more tutorials, demos, workshops, videos, and podcasts (we've done some pods [on our blog](https://trychroma.com/interviews)).\n\n### Example Datasets\n\nIt doesn\u2019t make sense for developers to embed the same information over and over again with the same embedding model.\n\nWe'd like suggestions for:\n\n- "small" (<100 rows)\n- "medium" (<5MB)\n- "large" (>1GB)\n\ndatasets for people to stress test Chroma in a variety of scenarios.\n\n### Embeddings Comparison\n\nChroma does ship with Sentence Transformers by default for embeddings, but we are otherwise unopinionated about what embeddings you use. Having a library of information that has been embedded with many models, alongside example query sets would make it much easier for empirical work to +be done on the effectiveness of various models across different domains.\n\n- [Preliminary reading on Embeddings](https://towardsdatascience.com/neural-network-embeddings-explained-4d028e6f0526?gi=ee46baab0d8f)\n- [Huggingface Benchmark of a bunch of Embeddings](https://huggingface.co/blog/mteb)\n- [notable issues with GPT3 Embeddings](https://twitter.com/Nils_Reimers/status/1487014195568775173) and alternatives to consider\n\n### Experimental Algorithms\n\nIf you have a research background, please consider adding to our `ExperimentalAPI`s. For example:\n\n- Projections (t-sne, UMAP, the new hotness, the one you just wrote) and Lightweight visualization\n- Clustering (HDBSCAN, PCA)\n- Deduplication\n- Multimodal (CLIP)\n- Fine-tuning manifold with human feedback [eg](https://github.com/openai/openai-cookbook/blob/main/examples/Customizing_embeddings.ipynb)\n- Expanded vector search (MMR, Polytope)\n- Your research\n\nYou can find the REST OpenAPI spec at +`localhost:8000/openapi.json` when the backend is running.\n\nPlease [reach out](https://discord.gg/MMeYNTmh3x) and talk to us before you get too far in your projects so that we can offer technical guidance/align on roadmap.\n\n# Telemetry\n\nChroma contains a telemetry feature that collects **anonymous** usage information.\n\n### Why?\n\nWe use this information to help us understand how Chroma is used, to help us prioritize work on new features and bug fixes, and to help us improve Chroma\u2019s performance and stability.\n\n### Opting out\n\nIf you prefer to opt out of telemetry, you can do this in two ways.\n\n#### In Client Code\n\n{% Tabs %}\n\n{% Tab label="python" %}\n\nSet `anonymized_telemetry` to `False` in your client's settings:\n\n```python\nfrom chromadb.config import Settings\nclient = chromadb.Client(Settings(anonymized_telemetry=False))\n# or if using PersistentClient\nclient = chromadb.PersistentClient(path="/path/to/save/to", settings=Settings(anonymized_telemetry=False))\n```\n\n{% /Tab %}\n\n{% Tab label="typescript" %}\n\nDisable telemetry on you Chroma server +(see next section).\n\n{% /Tab %}\n\n{% /Tabs %}\n\n#### In Chroma's Backend Using Environment Variables\n\nSet `ANONYMIZED_TELEMETRY` to `False` in your shell or server environment.\n\nIf you are running Chroma on your local computer with `docker-compose` you can set this value in an `.env` file placed in the same directory as the `docker-compose.yml` file:\n\n```\nANONYMIZED_TELEMETRY=False\n```\n\n### What do you track?\n\nWe will only track usage details that help us make product decisions, specifically:\n\n- Chroma version and environment details (e.g. OS, Python version, is it running in a container, or in a jupyter notebook)\n- Usage of embedding functions that ship with Chroma and aggregated usage of custom embeddings (we collect no information about the custom embeddings themselves)\n- Client interactions with our hosted Chroma Cloud service.\n- Collection commands. We track the anonymized uuid of a collection as well as the number of items\n - `add`\n - `update`\n - `query`\n - `get`\n - `delete`\n\nWe **do not** collect personally-identifiable or sensitive information, +such as: usernames, hostnames, file names, environment variables, or hostnames of systems being tested.\n\nTo view the list of events we track, you may reference the **[code](https://github.com/chroma-core/chroma/blob/main/chromadb/telemetry/product/events.py)**\n\n### Where is telemetry information stored?\n\nWe use **[Posthog](https://posthog.com/)** to store and visualize telemetry data.\n\n{% Banner type="tip" %}\n\nPosthog is an open source platform for product analytics. Learn more about Posthog on **[posthog.com](https://posthog.com/)** or **[github.com/posthog](https://github.com/posthog/posthog)**\n\n{% /Banner %} +# Install and Run\n\nYou can install the Chroma CLI with `pip`:\n\n```terminal\npip install chromadb\n```\n\nYou can then run a Chroma server locally with the `chroma run` command:\n\n```terminal\nchroma run --path [/path/to/persist/data]\n```\n\nYour Chroma server will persist its data in the path you provide after the `path` argument. By default, \nit will save data to the `.chroma` directory.\n\nWith your Chroma server running, you can connect to it with the `HttpClient`:\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\nimport chromadb\n\nchroma_client = chromadb.HttpClient(host='localhost', port=8000)\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nimport { ChromaClient } from "chromadb";\n\nconst client = new ChromaClient();\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n# Vacuuming\n\nVacuuming shrinks and optimizes your database.\n\nVacuuming after upgrading from a version of Chroma below v0.5.6 will greatly reduce the size of your database and enable continuous database +pruning. A warning is logged during server startup if this is necessary.\n\nIn most other cases, vacuuming is unnecessary. **It does not need to be run regularly**.\n\nVacuuming blocks all reads and writes to your database while it's running, so we recommend shutting down your Chroma server before vacuuming (although it's not strictly required).\n\nTo vacuum your database, run:\n\n```bash\nchroma utils vacuum --path \n```\n\nFor large databases, expect this to take up to a few minutes.\n\n +# Chroma Reference\n\n## Client APIs\n\nChroma currently maintains 1st party clients for Python and Javascript. For other clients in other languages, use their repos for documentation.\n\n`Client` - is the object that wraps a connection to a backing Chroma DB\n\n`Collection` - is the object that wraps a collection\n\n\n{% special_table %}\n{% /special_table %}\n\n| | Client | Collection |\n|--------------|-----------------------|-----------------------------------|\n| Python | [Client](./python/client) | [Collection](./python/collection) |\n| Javascript | [Client](./js/client) | [Collection](./js/collection) |\n\n***\n\n## Backend API\n\nChroma's backend Swagger REST API docs are viewable by running Chroma and navigating to `http://localhost:8000/docs`.\n\n```bash\npip install chromadb\nchroma run\nopen http://localhost:8000/docs\n```\n\n# JS Client\n\n## Class: ChromaClient\n\n### constructor\n\n* `new ChromaClient(params?)`\n\nCreates a new ChromaClient instance.\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `ChromaClient +Params` | The parameters for creating a new client |\n\n**Example**\n\n```typescript\nconst client = new ChromaClient({\n path: "http://localhost:8000"\n});\n```\n\n## Methods\n\n### countCollections\n\n* `countCollections(): Promise`\n\nCounts all collections.\n\n#### Returns\n\n`Promise`\n\nA promise that resolves to the number of collections.\n\n**Throws**\n\nIf there is an issue counting the collections.\n\n**Example**\n\n```typescript\nconst collections = await client.countCollections();\n```\n\n### createCollection\n\n* `createCollection(params): Promise`\n\nCreates a new collection with the specified properties.\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `CreateCollectionParams` | The parameters for creating a new collection. |\n\n#### Returns\n\n`Promise`\n\nA promise that resolves to the created collection.\n\n**Throws**\n\n* If the client is unable to connect to the server.\n* If there is an issue creating the collection.\n\n**Example**\n\n```typescript\nconst collection = await client.createCollection({\n name: "my_collection",\n metadata: {\n "description": "My first collection"\n }\n});\n`` +`\n\n### deleteCollection\n\n* `deleteCollection(params): Promise`\n\nDeletes a collection with the specified name.\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `DeleteCollectionParams` | The parameters for deleting a collection. |\n\n#### Returns\n\n`Promise`\n\nA promise that resolves when the collection is deleted.\n\n**Throws**\n\nIf there is an issue deleting the collection.\n\n**Example**\n\n```typescript\nawait client.deleteCollection({\n name: "my_collection"\n});\n```\n\n### getCollection\n\n`getCollection(params): Promise`\n\nGets a collection with the specified name.\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `GetCollectionParams` | The parameters for getting a collection. |\n\n#### Returns\n\n`Promise`\n\nA promise that resolves to the collection.\n\n**Throws**\n\nIf there is an issue getting the collection.\n\n**Example**\n\n```typescript\nconst collection = await client.getCollection({\n name: "my_collection"\n});\n```\n\n### getOrCreateCollection\n\n* `getOrCreateCollection(params): Promise`\n\nGets or creates a collection with the +specified properties.\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `CreateCollectionParams` | The parameters for creating a new collection. |\n\n#### Returns\n\n`Promise`\n\nA promise that resolves to the got or created collection.\n\n**Throws**\n\nIf there is an issue getting or creating the collection.\n\n**Example**\n\n```typescript\nconst collection = await client.getOrCreateCollection({\n name: "my_collection",\n metadata: {\n "description": "My first collection"\n }\n});\n```\n\n### heartbeat\n\n* `heartbeat(): Promise`\n\nReturns a heartbeat from the Chroma API.\n\n#### Returns\n\n`Promise`\n\nA promise that resolves to the heartbeat from the Chroma API.\n\n**Throws**\n\nIf the client is unable to connect to the server.\n\n**Example**\n\n```typescript\nconst heartbeat = await client.heartbeat();\n```\n\n### listCollections\n\n* `listCollections(params?): Promise`\n\nLists all collections.\n\n#### Parameters\n\n| Name | Type |\n|:---------| :------ |\n| `params` | `ListCollectionsParams` |\n\n#### Returns\n\n`Promise`\n\nA promise that resolves to +a list of collection names.\n\n**Throws**\n\nIf there is an issue listing the collections.\n\n**Example**\n\n```typescript\nconst collections = await client.listCollections({\n limit: 10,\n offset: 0,\n});\n```\n\n### reset\n\n* `reset(): Promise`\n\nResets the state of the object by making an API call to the reset endpoint.\n\n#### Returns\n\n`Promise`\n\nA promise that resolves when the reset operation is complete.\n\n**Throws**\n\n* If the client is unable to connect to the server.\n* If the server experienced an error while the state.\n\n**Example**\n\n```typescript\nawait client.reset();\n```\n\n### version\n\n* `version(): Promise`\n\nReturns the version of the Chroma API.\n\n#### Returns\n\n`Promise`\n\nA promise that resolves to the version of the Chroma API.\n\n**Throws**\n\nIf the client is unable to connect to the server.\n\n**Example**\n\n```typescript\nconst version = await client.version();\n```\n# Class: Collection\n\n## Properties\n\n* `id: string`\n* `metadata: CollectionMetadata`\n* `name: string`\n\n## Methods\n\n### add\n\n* `add(params): Promise`\n\nAdd items to the collection\n\n +#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `AddRecordsParams` | The parameters for the query. |\n\n#### Returns\n\n`Promise`\n\n- The response from the API.\n\n**Example**\n\n```typescript\nconst response = await collection.add({\n ids: ["id1", "id2"],\n embeddings: [[1, 2, 3], [4, 5, 6]],\n metadatas: [{ "key": "value" }, { "key": "value" }],\n documents: ["document1", "document2"]\n});\n```\n\n### count\n\n* `count(): Promise`\n\nCount the number of items in the collection\n\n#### Returns\n\n`Promise`\n\n- The number of items in the collection.\n\n**Example**\n\n```typescript\nconst count = await collection.count();\n```\n\n### delete\n\n* `delete(params?): Promise`\n\nDeletes items from the collection.\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `DeleteParams` | The parameters for deleting items from the collection. |\n\n#### Returns\n\n`Promise +`\n\nA promise that resolves to the IDs of the deleted items.\n\n**Throws**\n\nIf there is an issue deleting items from the collection.\n\n**Example**\n\n```typescript\nconst results = await collection.delete({\n ids: "some_id",\n where: {"name": {"$eq": "John Doe"}},\n whereDocument: {"$contains":"search_string"}\n});\n```\n\n### get\n\n* `get(params?): Promise`\n\nGet items from the collection\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `BaseGetParams` | The parameters for the query. |\n\n#### Returns\n\n`Promise`\n\nThe response from the server.\n\n**Example**\n\n```typescript\nconst response = await collection.get({\n ids: ["id1", "id2"],\n where: { "key": "value" },\n limit: 10,\n offset: 0,\n include: ["embeddings", "metadatas", "documents"],\n whereDocument: { $contains: "value" },\n});\n```\n\n### modify\n\n* `modify(params): Promise`\n\nModify the collection name or metadata\n\n#### +Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `Object` | The parameters for the query. |\n| `params.metadata?` | `CollectionMetadata` | Optional new metadata for the collection. |\n| `params.name?` | `string` | Optional new name for the collection. |\n\n#### Returns\n\n`Promise`\n\nThe response from the API.\n\n**Example**\n\n```typescript\nconst response = await client.updateCollection({\n name: "new name",\n metadata: { "key": "value" },\n});\n```\n\n### peek\n\n* `peek(params?): Promise`\n\nPeek inside the collection\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `PeekParams` | The parameters for the query. |\n\n#### Returns\n\n`Promise`\n\nA promise that resolves to the query results.\n\n**Throws**\n\nIf there is an issue executing the query.\n\n**Example**\n\n```typescript\nconst results = await collection.peek({\n limit: 10\n});\n```\n\n### query\n\n* `query(params): Promise`\n\nPerforms a query on the collection using the specified parameters.\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `QueryRecordsParams` | The parameters for the query. |\n\n#### Returns\n\n`Promise`\n\nA promise that resolves to the query results.\n\n**Throws**\n\nIf there is an issue executing the query.\n\n**Example**\n\n```typescript\n// Query the collection using embeddings\nconst embeddingsResults = await collection.query({\n queryEmbeddings: [[0.1, 0.2, ...], ...],\n nResults: 10,\n where: {"name": {"$eq": "John Doe"}},\n include: ["metadata", "document"]\n});\n\n// Query the collection using query text\nconst textResults = await collection.query({\n queryTexts: "some text",\n nResults: 10,\n where: {"name": {"$eq": "John Doe"}},\n include: ["metadata", "document"]\n});\n```\n\n### update\n\n* `update(params): Promise`\n\nUpdate items in the collection\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | : +------ |\n| `params` | `UpdateRecordsParams` | The parameters for the query. |\n\n#### Returns\n\n`Promise`\n\n**Example**\n\n```typescript\nconst response = await collection.update({\n ids: ["id1", "id2"],\n embeddings: [[1, 2, 3], [4, 5, 6]],\n metadatas: [{ "key": "value" }, { "key": "value" }],\n documents: ["document1", "document2"],\n});\n```\n\n### upsert\n\n* `upsert(params): Promise`\n\nUpsert items to the collection\n\n#### Parameters\n\n| Name | Type | Description |\n| :------ | :------ | :------ |\n| `params` | `AddRecordsParams` | The parameters for the query. |\n\n#### Returns\n\n`Promise`\n\n**Example**\n\n```typescript\nconst response = await collection.upsert({\n ids: ["id1", "id2"],\n embeddings: [[1, 2, 3], [4, 5, 6]],\n metadatas: [{ "key": "value" }, { "key": "value" }],\n documents: ["document1", " +document2"],\n});\n```\n\n# Python Client\n\n## configure\n\n```python\ndef configure(**kwargs) -> None\n```\n\nOverride Chroma's default settings, environment variables or .env files\n\n## EphemeralClient\n\n```python\ndef EphemeralClient(settings: Optional[Settings] = None,\n tenant: str = DEFAULT_TENANT,\n database: str = DEFAULT_DATABASE) -> ClientAPI\n```\n\nCreates an in-memory instance of Chroma. This is useful for testing and\ndevelopment, but not recommended for production use.\n\n**Arguments**:\n\n- `tenant` - The tenant to use for this client. Defaults to the default tenant.\n- `database` - The database to use for this client. Defaults to the default database.\n\n## PersistentClient\n\n```python\ndef PersistentClient(path: str = "./chroma",\n settings: Optional[Settings] = None,\n tenant: str = DEFAULT_TENANT,\n database: str = DEFAULT_DATABASE) -> ClientAPI\n```\n\nCreates a persistent instance of Chroma that saves to disk. This is useful for\ntesting and development, but not recommended for production use.\n\n**Arguments**:\n\n- `path` - The directory to save Chroma's +data to. Defaults to "./chroma".\n- `tenant` - The tenant to use for this client. Defaults to the default tenant.\n- `database` - The database to use for this client. Defaults to the default database.\n\n## HttpClient\n\n```python\ndef HttpClient(host: str = "localhost",\n port: int = 8000,\n ssl: bool = False,\n headers: Optional[Dict[str, str]] = None,\n settings: Optional[Settings] = None,\n tenant: str = DEFAULT_TENANT,\n database: str = DEFAULT_DATABASE) -> ClientAPI\n```\n\nCreates a client that connects to a remote Chroma server. This supports\nmany clients connecting to the same server, and is the recommended way to\nuse Chroma in production.\n\n**Arguments**:\n\n- `host` - The hostname of the Chroma server. Defaults to "localhost".\n- `port` - The port of the Chroma server. Defaults to "8000".\n- `ssl` - Whether to use SSL to connect to the Chroma server. Defaults to False.\n- `headers` - A dictionary of headers to send to the Chroma server. Defaults to {}.\n- `settings` - A +dictionary of settings to communicate with the chroma server.\n- `tenant` - The tenant to use for this client. Defaults to the default tenant.\n- `database` - The database to use for this client. Defaults to the default database.\n\n## AsyncHttpClient\n\n```python\nasync def AsyncHttpClient(host: str = "localhost",\n port: int = 8000,\n ssl: bool = False,\n headers: Optional[Dict[str, str]] = None,\n settings: Optional[Settings] = None,\n tenant: str = DEFAULT_TENANT,\n database: str = DEFAULT_DATABASE) -> AsyncClientAPI\n```\n\nCreates an async client that connects to a remote Chroma server. This supports\nmany clients connecting to the same server, and is the recommended way to\nuse Chroma in production.\n\n**Arguments**:\n\n- `host` - The hostname of the Chroma server. Defaults to "localhost".\n- `port` - The port of the Chroma server. Defaults to "8000".\n- `ssl` - Whether to use SSL to connect to the Chroma server. Defaults to False.\n- `headers` - A dictionary of headers to send to the Chroma server. Defaults to {} +.\n- `settings` - A dictionary of settings to communicate with the chroma server.\n- `tenant` - The tenant to use for this client. Defaults to the default tenant.\n- `database` - The database to use for this client. Defaults to the default database.\n\n## CloudClient\n\n```python\ndef CloudClient(tenant: str,\n database: str,\n api_key: Optional[str] = None,\n settings: Optional[Settings] = None,\n *,\n cloud_host: str = "api.trychroma.com",\n cloud_port: int = 8000,\n enable_ssl: bool = True) -> ClientAPI\n```\n\nCreates a client to connect to a tenant and database on the Chroma cloud.\n\n**Arguments**:\n\n- `tenant` - The tenant to use for this client.\n- `database` - The database to use for this client.\n- `api_key` - The api key to use for this client.\n\n## Client\n\n```python\ndef Client(settings: Settings = __settings,\n tenant: str = DEFAULT_TENANT,\n database: str = DEFAULT_DATABASE) -> ClientAPI\n```\n\nReturn a running `chroma.API` instance\n\n**Arguments**:\n\n* +`tenant`: The tenant to use for this client. Defaults to the `default` tenant.\n* `database`: The database to use for this client. Defaults to the `default` database.\n\n## AdminClient\n\n```python\ndef AdminClient(settings: Settings = Settings()) -> AdminAPI\n```\n\nCreates an admin client that can be used to create tenants and databases.\n\n***\n\n# BaseClient Methods\n\n```python\nclass BaseAPI(ABC)\n```\n\n## heartbeat\n\n```python\ndef heartbeat() -> int\n```\n\nGet the current time in nanoseconds since epoch.\nUsed to check if the server is alive.\n\n**Returns**:\n\n- `int` - The current time in nanoseconds since epoch\n\n## count\\_collections\n\n```python\ndef count_collections() -> int\n```\n\nCount the number of collections.\n\n**Returns**:\n\n- `int` - The number of collections.\n\n\n**Examples**:\n\n```python\nclient.count_collections()\n# 1\n```\n\n## delete\\_collection\n\n```python\ndef delete_collection(name: str) -> None\n```\n\nDelete a collection with the given name.\n\n**Arguments**:\n\n- `name` - The name of the collection to delete.\n\n\n**Raises**:\n\n- `ValueError +` - If the collection does not exist.\n\n\n**Examples**:\n\n ```python\n client.delete_collection("my_collection")\n ```\n\n## reset\n\n```python\ndef reset() -> bool\n```\n\nResets the database. This will delete all collections and entries.\n\n**Returns**:\n\n- `bool` - True if the database was reset successfully.\n\n## get\\_version\n\n```python\ndef get_version() -> str\n```\n\nGet the version of Chroma.\n\n**Returns**:\n\n- `str` - The version of Chroma\n\n## get\\_settings\n\n```python\ndef get_settings() -> Settings\n```\n\nGet the settings used to initialize.\n\n**Returns**:\n\n- `Settings` - The settings used to initialize.\n\n## get\\_max\\_batch\\_size\n\n```python\ndef get_max_batch_size() -> int\n```\n\nReturn the maximum number of records that can be created or mutated in a single call.\n\n***\n\n# ClientClient Methods\n\n```python\nclass ClientAPI(BaseAPI, ABC)\n```\n\n## list\\_collections\n\n```python\ndef list_collections(limit: Optional[int] = None,\n offset: Optional[int] = None) -> Sequence[CollectionName]\n```\n\nList all collections names.\n\n +**Arguments**:\n\n- `limit` - The maximum number of entries to return. Defaults to None.\n- `offset` - The number of entries to skip before returning. Defaults to None.\n\n\n**Returns**:\n\n- `Sequence[CollectionName]` - A list of collection names. `CollectionName` is a string.\n\n\n**Examples**:\n\n```python\nclient.list_collections()\n# ['my_collection']\n```\n\n## create_collection\n\n```python\ndef create_collection(name: str,\n configuration: Optional[CollectionConfiguration] = None,\n metadata: Optional[CollectionMetadata] = None,\n embedding_function: Optional[EmbeddingFunction[\n Embeddable]] = ef.DefaultEmbeddingFunction(),\n data_loader: Optional[DataLoader[Loadable]] = None,\n get_or_create: bool = False) -> Collection\n```\n\nCreate a new collection with the given name and metadata.\n\n**Arguments**:\n\n- `name` - The name of the collection to create.\n- `metadata` - Optional metadata to associate with the collection.\n- `embedding_function` - Optional function to use to embed documents.\n Uses the default embedding function if not provided.\n- `get_or_create` - If True, return the existing collection +if it exists.\n- `data_loader` - Optional function to use to load records (documents, images, etc.)\n\n\n**Returns**:\n\n- `Collection` - The newly created collection.\n\n\n**Raises**:\n\n- `ValueError` - If the collection already exists and get_or_create is False.\n- `ValueError` - If the collection name is invalid.\n\n\n**Examples**:\n\n```python\nclient.create_collection("my_collection")\n# collection(name="my_collection", metadata={})\n\nclient.create_collection("my_collection", metadata={"foo": "bar"})\n# collection(name="my_collection", metadata={"foo": "bar"})\n```\n\n## get_collection\n\n```python\ndef get_collection(\n name: str,\n id: Optional[UUID] = None,\n embedding_function: Optional[\n EmbeddingFunction[Embeddable]] = ef.DefaultEmbeddingFunction(),\n data_loader: Optional[DataLoader[Loadable]] = None) -> Collection\n```\n\nGet a collection with the given name.\n\n**Arguments**:\n\n- `id` - The UUID of the collection to get. Id and Name are simultaneously used for lookup if provided.\n- `name` - The name of the collection to get\n- `embedding_function` +- Optional function to use to embed documents.\n Uses the default embedding function if not provided.\n- `data_loader` - Optional function to use to load records (documents, images, etc.)\n\n\n**Returns**:\n\n- `Collection` - The collection\n\n\n**Raises**:\n\n- `ValueError` - If the collection does not exist\n\n\n**Examples**:\n\n ```python\n client.get_collection("my_collection")\n # collection(name="my_collection", metadata={})\n ```\n\n## get\\_or\\_create\\_collection\n\n```python\ndef get_or_create_collection(\n name: str,\n configuration: Optional[CollectionConfiguration] = None,\n metadata: Optional[CollectionMetadata] = None,\n embedding_function: Optional[\n EmbeddingFunction[Embeddable]] = ef.DefaultEmbeddingFunction(),\n data_loader: Optional[DataLoader[Loadable]] = None) -> Collection\n```\n\nGet or create a collection with the given name and metadata.\n\n**Arguments**:\n\n- `name` - The name of the collection to get or create\n- `metadata` - Optional metadata to associate with the collection. If\n the collection alredy exists, the metadata will be ignored. If the collection does +not exist, the\n new collection will be created with the provided metadata.\n- `embedding_function` - Optional function to use to embed documents\n- `data_loader` - Optional function to use to load records (documents, images, etc.)\n\n\n**Returns**:\n\n The collection\n\n\n**Examples**:\n\n ```python\n client.get_or_create_collection("my_collection")\n # collection(name="my_collection", metadata={})\n ```\n\n## set_tenant\n\n```python\ndef set_tenant(tenant: str, database: str = DEFAULT_DATABASE) -> None\n```\n\nSet the tenant and database for the client. Raises an error if the tenant or\ndatabase does not exist.\n\n**Arguments**:\n\n- `tenant` - The tenant to set.\n- `database` - The database to set.\n\n## set_database\n\n```python\ndef set_database(database: str) -> None\n```\n\nSet the database for the client. Raises an error if the database does not exist.\n\n**Arguments**:\n\n- `database` - The database to set.\n\n## clear_system_cache\n\n```python\n@staticmethod\ndef clear_system_cache() -> None\n```\n\nClear the system cache so that new systems can be created for an +existing path.\nThis should only be used for testing purposes.\n\n***\n\n# AdminClient Methods\n\n```python\nclass AdminAPI(ABC)\n```\n\n## create_database\n\n```python\ndef create_database(name: str, tenant: str = DEFAULT_TENANT) -> None\n```\n\nCreate a new database. Raises an error if the database already exists.\n\n**Arguments**:\n\n- `database` - The name of the database to create.\n\n## get_database\n\n```python\ndef get_database(name: str, tenant: str = DEFAULT_TENANT) -> Database\n```\n\nGet a database. Raises an error if the database does not exist.\n\n**Arguments**:\n\n- `database` - The name of the database to get.\n- `tenant` - The tenant of the database to get.\n\n## delete_database\n\n```python\ndef delete_database(name: str, tenant: str = DEFAULT_TENANT) -> None\n```\n\nDelete a database and all associated collections. Raises an error if the database does not exist.\n\n**Arguments**:\n\n- `database` - The name of the database to delete.\n- `tenant` - The tenant of the database to delete.\n\n## list_databases\n\n```python\ndef list_databases(limit: +Optional[int] = None, offset: Optional[int] = None, tenant: str = DEFAULT_TENANT) -> Sequence[Database]\n```\n\nList databases for a tenant.\n\n**Arguments**:\n\n- `limit` - The maximum number of entries to return. Defaults to None.\n- `offset` - The number of entries to skip before returning. Defaults to None.\n- `tenant` - The tenant to list databases for.\n\n## create_tenant\n\n```python\ndef create_tenant(name: str) -> None\n```\n\nCreate a new tenant. Raises an error if the tenant already exists.\n\n**Arguments**:\n\n- `tenant` - The name of the tenant to create.\n\n## get_tenant\n\n```python\ndef get_tenant(name: str) -> Tenant\n```\n\nGet a tenant. Raises an error if the tenant does not exist.\n\n**Arguments**:\n\n- `tenant` - The name of the tenant to get.\n\n***\n\n# ServerClient Methods\n\n```python\nclass ServerAPI(BaseAPI, AdminAPI, Component)\n```\n\nAn API instance that extends the relevant Base API methods by passing\nin a tenant and database. This is the root component of the Chroma System\n\n---\ntitle: Collection\n---\n\n# +Python Collection\n\n```python\nclass Collection(BaseModel)\n```\n\n## count\n\n```python\ndef count() -> int\n```\n\nThe total number of embeddings added to the database\n\n**Returns**:\n\n- `int` - The total number of embeddings added to the database\n\n## add\n\n```python\ndef add(ids: OneOrMany[ID],\n embeddings: Optional[OneOrMany[Embedding]] = None,\n metadatas: Optional[OneOrMany[Metadata]] = None,\n documents: Optional[OneOrMany[Document]] = None) -> None\n```\n\nAdd embeddings to the data store.\n\n**Arguments**:\n\n- `ids` - The ids of the embeddings you wish to add\n- `embeddings` - The embeddings to add. If None, embeddings will be computed based on the documents using the embedding_function set for the Collection. Optional.\n- `metadatas` - The metadata to associate with the embeddings. When querying, you can filter on this metadata. Optional.\n- `documents` - The documents to associate with the embeddings. Optional.\n\n\n**Returns**:\n\n None\n\n\n**Raises**:\n\n- `ValueError` - If you don't provide either embeddings or documents\n- +`ValueError` - If the length of ids, embeddings, metadatas, or documents don't match\n- `ValueError` - If you don't provide an embedding function and don't provide embeddings\n- `DuplicateIDError` - If you provide an id that already exists\n\n## get\n\n```python\ndef get(ids: Optional[OneOrMany[ID]] = None,\n where: Optional[Where] = None,\n limit: Optional[int] = None,\n offset: Optional[int] = None,\n where_document: Optional[WhereDocument] = None,\n include: Include = ["metadatas", "documents"]) -> GetResult\n```\n\nGet embeddings and their associate data from the data store. If no ids or where filter is provided returns\nall embeddings up to limit starting at offset.\n\n**Arguments**:\n\n- `ids` - The ids of the embeddings to get. Optional.\n- `where` - A Where type dict used to filter results by. E.g. `{"color" : "red", "price": 4.20}`. Optional.\n- `limit` - The number of documents to return. Optional.\n- `offset` - The offset to start returning results from +. Useful for paging results with limit. Optional.\n- `where_document` - A WhereDocument type dict used to filter by the documents. E.g. `{$contains: {"text": "hello"}}`. Optional.\n- `include` - A list of what to include in the results. Can contain `"embeddings"`, `"metadatas"`, `"documents"`. Ids are always included. Defaults to `["metadatas", "documents"]`. Optional.\n\n\n**Returns**:\n\n- `GetResult` - A GetResult object containing the results.\n\n## peek\n\n```python\ndef peek(limit: int = 10) -> GetResult\n```\n\nGet the first few results in the database up to limit\n\n**Arguments**:\n\n- `limit` - The number of results to return.\n\n\n**Returns**:\n\n- `GetResult` - A GetResult object containing the results.\n\n## query\n\n```python\ndef query(\n query_embeddings: Optional[OneOrMany[Embedding]] = None,\n query_texts: Optional[OneOrMany[Document]] = None,\n n_results: int = 10,\n where: Optional[Where] = None,\n where_document: Optional[WhereDocument] = +None,\n include: Include = ["metadatas", "documents",\n "distances"]) -> QueryResult\n```\n\nGet the n_results nearest neighbor embeddings for provided query_embeddings or query_texts.\n\n**Arguments**:\n\n- `query_embeddings` - The embeddings to get the closest neighbors of. Optional.\n- `query_texts` - The document texts to get the closest neighbors of. Optional.\n- `n_results` - The number of neighbors to return for each query_embedding or query_texts. Optional.\n- `where` - A Where type dict used to filter results by. E.g. `{"color" : "red", "price": 4.20}`. Optional.\n- `where_document` - A WhereDocument type dict used to filter by the documents. E.g. `{$contains: {"text": "hello"}}`. Optional.\n- `include` - A list of what to include in the results. Can contain `"embeddings"`, `"metadatas"`, `"documents"`, `"distances"`. Ids are always included. Defaults to `["metadatas", "documents", "distances"]`. Optional.\n\n\n**Returns**:\n\n- `QueryResult` - A QueryResult object containing the +results.\n\n\n**Raises**:\n\n- `ValueError` - If you don't provide either query_embeddings or query_texts\n- `ValueError` - If you provide both query_embeddings and query_texts\n\n## modify\n\n```python\ndef modify(name: Optional[str] = None,\n metadata: Optional[CollectionMetadata] = None) -> None\n```\n\nModify the collection name or metadata\n\n**Arguments**:\n\n- `name` - The updated name for the collection. Optional.\n- `metadata` - The updated metadata for the collection. Optional.\n\n\n**Returns**:\n\n None\n\n## update\n\n```python\ndef update(ids: OneOrMany[ID],\n embeddings: Optional[OneOrMany[Embedding]] = None,\n metadatas: Optional[OneOrMany[Metadata]] = None,\n documents: Optional[OneOrMany[Document]] = None) -> None\n```\n\nUpdate the embeddings, metadatas or documents for provided ids.\n\n**Arguments**:\n\n- `ids` - The ids of the embeddings to update\n- `embeddings` - The embeddings to add. If None, embeddings will be computed based on the documents using the embedding_function set for the Collection. Optional.\n- `metad +atas` - The metadata to associate with the embeddings. When querying, you can filter on this metadata. Optional.\n- `documents` - The documents to associate with the embeddings. Optional.\n\n\n**Returns**:\n\n None\n\n## upsert\n\n```python\ndef upsert(ids: OneOrMany[ID],\n embeddings: Optional[OneOrMany[Embedding]] = None,\n metadatas: Optional[OneOrMany[Metadata]] = None,\n documents: Optional[OneOrMany[Document]] = None) -> None\n```\n\nUpdate the embeddings, metadatas or documents for provided ids, or create them if they don't exist.\n\n**Arguments**:\n\n- `ids` - The ids of the embeddings to update\n- `embeddings` - The embeddings to add. If None, embeddings will be computed based on the documents using the embedding_function set for the Collection. Optional.\n- `metadatas` - The metadata to associate with the embeddings. When querying, you can filter on this metadata. Optional.\n- `documents` - The documents to associate with the embeddings. Optional.\n\n\n**Returns**:\n\n None\n\n## delete\n\n```python\ndef delete(ids: Optional[IDs] = None,\n +where: Optional[Where] = None,\n where_document: Optional[WhereDocument] = None) -> None\n```\n\nDelete the embeddings based on ids and/or a where filter\n\n**Arguments**:\n\n- `ids` - The ids of the embeddings to delete\n- `where` - A Where type dict used to filter the delection by. E.g. `{"color" : "red", "price": 4.20}`. Optional.\n- `where_document` - A WhereDocument type dict used to filter the deletion by the document content. E.g. `{$contains: {"text": "hello"}}`. Optional.\n\n\n**Returns**:\n\n None +# Embedding Functions\n\n## Default: all-MiniLM-L6-v2\n\nBy default, Chroma uses the [Sentence Transformers](https://www.sbert.net/) `all-MiniLM-L6-v2` model to create embeddings. This embedding model can create sentence and document embeddings that can be used for a wide variety of tasks. This embedding function runs locally on your machine, and may require you download the model files (this will happen automatically).\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\nfrom chromadb.utils import embedding_functions\ndefault_ef = embedding_functions.DefaultEmbeddingFunction()\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nimport { DefaultEmbeddingFunction } from "chromadb";\nconst defaultEF = new DefaultEmbeddingFunction();\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nEmbedding functions can be linked to a collection and used whenever you call `add`, `update`, `upsert` or `query`. You can also use them directly which can be handy for debugging.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\nval = default_ef(["foo"])\nprint(val) +# [[0.05035809800028801, 0.0626462921500206, -0.061827320605516434...]]\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nconst val = defaultEf.generate(["foo"]);\nconsole.log(val); // [[0.05035809800028801, 0.0626462921500206, -0.061827320605516434...]]\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n## Sentence Transformers\n\nChroma can also use any [Sentence Transformers](https://www.sbert.net/) model to create embeddings.\n\nYou can pass in an optional `model_name` argument, which lets you choose which Sentence Transformers model to use. By default, Chroma uses `all-MiniLM-L6-v2`. You can see a list of all available models [here](https://www.sbert.net/docs/pretrained_models.html).\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\nsentence_transformer_ef = embedding_functions.SentenceTransformerEmbeddingFunction(\n model_name="all-MiniLM-L6-v2"\n)\n```\n{% /Tab %}\n\n +{% Tab label="typescript" %}\n```typescript\nimport { DefaultEmbeddingFunction } from "chromadb";\nconst modelName = "all-MiniLM-L6-v2";\nconst defaultEF = new DefaultEmbeddingFunction(modelName);\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n## Custom Embedding Functions\n\nYou can create your own embedding function to use with Chroma, it just needs to implement the `EmbeddingFunction` protocol.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\nfrom chromadb import Documents, EmbeddingFunction, Embeddings\n\nclass MyEmbeddingFunction(EmbeddingFunction):\n def __call__(self, input: Documents) -> Embeddings:\n # embed the documents somehow\n return embeddings\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nclass MyEmbeddingFunction {\n private api_key: string;\n\n constructor(api_key: string) {\n this.api_key = api_key;\n }\n\n public async generate(texts: string[]): Promise {\n // do things to turn texts into embeddings with an api_key perhaps\n return embeddings;\n }\n}\n```\n\n# Multimodal +\n\n{% Banner type="note" %}\nMultimodal support is currently available only in Python. Javascript/Typescript support coming soon! \n{% /Banner %}\n\nChroma supports multimodal collections, i.e. collections which can store, and can be queried by, multiple modalities of data.\n\n[Try it out in Colab](https://githubtocolab.com/chroma-core/chroma/blob/main/examples/multimodal/multimodal_retrieval.ipynb)\n\n## Multi-modal Embedding Functions\n\nChroma supports multi-modal embedding functions, which can be used to embed data from multiple modalities into a single embedding space.\n\nChroma has the OpenCLIP embedding function built in, which supports both text and images.\n\n```python\nfrom chromadb.utils.embedding_functions import OpenCLIPEmbeddingFunction\nembedding_function = OpenCLIPEmbeddingFunction()\n```\n\n## Data Loaders\n\nChroma supports data loaders, for storing and querying with data stored outside Chroma itself, via URI. Chroma will not store this data, but will instead store the URI, and load the data from the URI when needed.\n\nChroma has a data loader for loading images from a filesystem built in.\n\n```python\nfrom +chromadb.utils.data_loaders import ImageLoader\ndata_loader = ImageLoader()\n```\n\n## Multi-modal Collections\n\nYou can create a multi-modal collection by passing in a multi-modal embedding function. In order to load data from a URI, you must also pass in a data loader.\n\n```python\nimport chromadb\n\nclient = chromadb.Client()\n\ncollection = client.create_collection(\n name='multimodal_collection',\n embedding_function=embedding_function,\n data_loader=data_loader)\n\n```\n\n### Adding data\n\nYou can add data to a multi-modal collection by specifying the data modality. For now, images are supported:\n\n```python\ncollection.add(\n ids=['id1', 'id2', 'id3'],\n images=[...] # A list of numpy arrays representing images\n)\n```\n\nNote that Chroma will not store the data for you, and you will have to maintain a mapping from IDs to data yourself.\n\nHowever, you can use Chroma in combination with data stored elsewhere, by adding it via URI. Note that this requires that you have specified a data loader when creating the collection.\n\n```python\ncollection.add(\n ids=['id1', 'id2', 'id3'],\n uris=[...] # +A list of strings representing URIs to data\n)\n```\n\nSince the embedding function is multi-modal, you can also add text to the same collection:\n\n```python\ncollection.add(\n ids=['id4', 'id5', 'id6'],\n documents=["This is a document", "This is another document", "This is a third document"]\n)\n```\n\n### Querying\n\nYou can query a multi-modal collection with any of the modalities that it supports. For example, you can query with images:\n\n```python\nresults = collection.query(\n query_images=[...] # A list of numpy arrays representing images\n)\n```\n\nOr with text:\n\n```python\nresults = collection.query(\n query_texts=["This is a query document", "This is another query document"]\n)\n```\n\nIf a data loader is set for the collection, you can also query with URIs which reference data stored elsewhere of the supported modalities:\n\n```python\nresults = collection.query(\n query_uris=[...] # A list of strings representing URIs to data\n)\n```\n\nAdditionally, if a data loader is set for the collection, and URIs are available, you can include the data in the results:\n\n```python\nresults += collection.query(\n query_images=[...], # # list of numpy arrays representing images\n includes=['data']\n)\n```\n\nThis will automatically call the data loader for any available URIs, and include the data in the results. `uris` are also available as an `includes` field.\n\n### Updating\n\nYou can update a multi-modal collection by specifying the data modality, in the same way as `add`. For now, images are supported:\n\n```python\ncollection.update(\n ids=['id1', 'id2', 'id3'],\n images=[...] # A list of numpy arrays representing images\n)\n```\n\nNote that a given entry with a specific ID can only have one associated modality at a time. Updates will over-write the existing modality, so for example, an entry which originally has corresponding text and updated with an image, will no longer have that text after an update with images.\n +\n\n### Framework Integrations\n\nChroma maintains integrations with many popular tools. These tools can be used to define the business logic of an AI-native application, curate data, fine-tune embedding spaces and more.\n\nWe welcome pull requests to add new Integrations to the community.\n\n{% special_table %}\n{% /special_table %}\n\n| | Python | JS |\n| --------------------------------------- | ------ | ------------ |\n| [DeepEval](./frameworks/deepeval) | \u2713 | - |\n| [Langchain](./frameworks/langchain) | \u2713 | \u2713 |\n| [LlamaIndex](./frameworks/llamaindex) | \u2713 | \u2713 |\n| [Braintrust](./frameworks/braintrust) | \u2713 | \u2713 |\n| [OpenLLMetry](./frameworks/openllmetry) | \u2713 | Coming Soon! |\n| [Streamlit](./frameworks/streamlit) | \u2713 | - |\n| [Haystack](./frameworks/haystack) | \u2713 | - |\n| [OpenLIT](./frameworks/openlit) | \u2713 | Coming Soon! |\n| [ +Anthropic MCP](./frameworks/anthropic-mcp) | \u2713 | Coming Soon! |\n\n---\nid: 'cohere'\nname: 'Cohere'\n---\n\n# Cohere\n\nChroma also provides a convenient wrapper around Cohere's embedding API. This embedding function runs remotely on Cohere\u2019s servers, and requires an API key. You can get an API key by signing up for an account at [Cohere](https://dashboard.cohere.ai/welcome/register).\n\n{% Tabs %}\n{% Tab label="python" %}\n\nThis embedding function relies on the `cohere` python package, which you can install with `pip install cohere`.\n\n```python\nimport chromadb.utils.embedding_functions as embedding_functions\ncohere_ef = embedding_functions.CohereEmbeddingFunction(api_key="YOUR_API_KEY", model_name="large")\ncohere_ef(input=["document1","document2"])\n```\n\n{% /Tab %}\n\n{% Tab label="typescript" %}\n\n```typescript\nimport { CohereEmbeddingFunction } from 'chromadb';\n\nconst embedder = new CohereEmbeddingFunction("apiKey")\n\n// use directly\nconst embeddings = embedder.generate(["document1","document2"])\n\n// pass documents to query for +.add and .query\nconst collection = await client.createCollection({name: "name", embeddingFunction: embedder})\nconst collectionGet = await client.getCollection({name:"name", embeddingFunction: embedder})\n```\n\n{% /Tab %}\n\n{% /Tabs %}\n\nYou can pass in an optional `model_name` argument, which lets you choose which Cohere embeddings model to use. By default, Chroma uses `large` model. You can see the available models under `Get embeddings` section [here](https://docs.cohere.ai/reference/embed).\n\n### Multilingual model example\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n\n```python\ncohere_ef = embedding_functions.CohereEmbeddingFunction(\n api_key="YOUR_API_KEY",\n model_name="multilingual-22-12")\n\nmultilingual_texts = [ 'Hello from Cohere!', '\u0645\u0631\u062d\u0628\u064b\u0627 \u0645\u0646 \u0643\u0648\u0647\u064a\u0631!',\n 'Hallo von Cohere!', 'Bonjour de Cohere!',\n '\xa1Hola desde Cohere!', 'Ol\xe1 do Cohere!',\n 'Ciao da Cohere!', '\u60a8\u597d\uff0c\u6765\u81ea Cohere\uff01',\n '\u0915\u094b\u0939 +\u093f\u0905\u0930 \u0938\u0947 \u0928\u092e\u0938\u094d\u0924\u0947!' ]\n\ncohere_ef(input=multilingual_texts)\n\n```\n\n{% /Tab %}\n\n{% Tab label="typescript" %}\n\n```typescript\nimport { CohereEmbeddingFunction } from 'chromadb';\n\nconst embedder = new CohereEmbeddingFunction("apiKey")\n\nmultilingual_texts = [ 'Hello from Cohere!', '\u0645\u0631\u062d\u0628\u064b\u0627 \u0645\u0646 \u0643\u0648\u0647\u064a\u0631!',\n 'Hallo von Cohere!', 'Bonjour de Cohere!',\n '\xa1Hola desde Cohere!', 'Ol\xe1 do Cohere!',\n 'Ciao da Cohere!', '\u60a8\u597d\uff0c\u6765\u81ea Cohere\uff01',\n '\u0915\u094b\u0939\u093f\u0905\u0930 \u0938\u0947 \u0928\u092e\u0938\u094d\u0924\u0947!' ]\n\nconst embeddings = embedder.generate(multilingual_texts)\n\n```\n\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nFor more information on multilingual model you can read [here](https://docs.cohere.ai/docs/multilingual-language-models).\n\n---\nid: google-gemini\nname: "Google Gemini"\n---\n\n# Google Gemini\n\nChroma provides a convenient wrapper around Google's Generative AI embedding API. This embedding +function runs remotely on Google's servers, and requires an API key.\n\nYou can get an API key by signing up for an account at [Google MakerSuite](https://makersuite.google.com/).\n\n{% Tabs %}\n\n{% Tab label="python" %}\n\nThis embedding function relies on the `google-generativeai` python package, which you can install with `pip install google-generativeai`.\n\n```python\n# import\nimport chromadb.utils.embedding_functions as embedding_functions\n\n# use directly\ngoogle_ef = embedding_functions.GoogleGenerativeAiEmbeddingFunction(api_key="YOUR_API_KEY")\ngoogle_ef(["document1","document2"])\n\n# pass documents to query for .add and .query\ncollection = client.create_collection(name="name", embedding_function=google_ef)\ncollection = client.get_collection(name="name", embedding_function=google_ef)\n```\n\nYou can view a more [complete example](https://github.com/chroma-core/chroma/tree/main/examples/gemini) chatting over documents with Gemini embedding and langauge models.\n\nFor more info - please visit the [official Google python docs](https://ai.google.dev/tutorials/python_quickstart).\n\n{% /Tab %}\n\n{% Tab label="typescript" %}\n\nThis embedding function relies +on the `@google/generative-ai` npm package, which you can install with e.g. `npm install @google/generative-ai`.\n\n```typescript\nimport { ChromaClient, GoogleGenerativeAiEmbeddingFunction } from "chromadb";\nconst embedder = new GoogleGenerativeAiEmbeddingFunction({\n googleApiKey: "",\n});\n\n// use directly\nconst embeddings = await embedder.generate(["document1", "document2"]);\n\n// pass documents to query for .add and .query\nconst collection = await client.createCollection({\n name: "name",\n embeddingFunction: embedder,\n});\nconst collectionGet = await client.getCollection({\n name: "name",\n embeddingFunction: embedder,\n});\n```\n\nYou can view a more [complete example using Node](https://github.com/chroma-core/chroma/blob/main/clients/js/examples/node/app.js).\n\nFor more info - please visit the [official Google JS docs](https://ai.google.dev/tutorials/node_quickstart).\n\n{% /Tab %}\n\n{% /Tabs %}\n\n---\nid: hugging-face-server\nname: 'Hugging Face Server'\n---\n\n# Hugging Face Server\n\nChroma provides a convenient wrapper for Hugging +Face Text Embedding Server, a standalone server that provides text embeddings via a REST API. You can read more about it [**here**](https://github.com/huggingface/text-embeddings-inference).\n\n## Setting Up The Server\n\nTo run the embedding server locally you can run the following command from the root of the Chroma repository. The docker compose command will run Chroma and the embedding server together.\n\n```terminal\ndocker compose -f examples/server_side_embeddings/huggingface/docker-compose.yml up -d\n```\n\nor\n\n```terminal\ndocker run -p 8001:80 -d -rm --name huggingface-embedding-server ghcr.io/huggingface/text-embeddings-inference:cpu-0.3.0 --model-id BAAI/bge-small-en-v1.5 --revision -main\n```\n\n{% Banner type="note" %}\nThe above docker command will run the server with the `BAAI/bge-small-en-v1.5` model. You can find more information about running the server in docker [**here**](https://github.com/huggingface/text-embeddings-inference#docker).\n{% /Banner %}\n\n## Usage\n\n{% TabbedCode +Block %}\n\n{% Tab label="python" %}\n\n```python\nfrom chromadb.utils.embedding_functions import HuggingFaceEmbeddingServer\nhuggingface_ef = HuggingFaceEmbeddingServer(url="http://localhost:8001/embed")\n```\n\n{% /Tab %}\n\n{% Tab label="typescript" %}\n\n\n```typescript\nimport {HuggingFaceEmbeddingServerFunction} from 'chromadb';\nconst embedder = new HuggingFaceEmbeddingServerFunction({url:"http://localhost:8001/embed"})\n\n// use directly\nconst embeddings = embedder.generate(["document1","document2"])\n\n// pass documents to query for .add and .query\nlet collection = await client.createCollection({name: "name", embeddingFunction: embedder})\ncollection = await client.getCollection({name: "name", embeddingFunction: embedder})\n```\n\n{% /Tab %}\n{% /TabbedCodeBlock %}\n\nThe embedding model is configured on the server side. Check the docker-compose file in `examples/server_side_embeddings/huggingface/docker-compose.yml` for an example of how to configure the server.\n\n---\nid: hugging-face\nname: Hugging Face\n---\n\n# Hugging Face\n\nChroma also provides a convenient +wrapper around HuggingFace's embedding API. This embedding function runs remotely on HuggingFace's servers, and requires an API key. You can get an API key by signing up for an account at [HuggingFace](https://huggingface.co/).\n\n{% tabs group="code-lang" hideTabs=true %}\n{% tab label="Python" %}\n\n```python\nimport chromadb.utils.embedding_functions as embedding_functions\nhuggingface_ef = embedding_functions.HuggingFaceEmbeddingFunction(\n api_key="YOUR_API_KEY",\n model_name="sentence-transformers/all-MiniLM-L6-v2"\n)\n```\n\nYou can pass in an optional `model_name` argument, which lets you choose which HuggingFace model to use. By default, Chroma uses `sentence-transformers/all-MiniLM-L6-v2`. You can see a list of all available models [here](https://huggingface.co/models).\n\n---\nid: instructor\nname: Instructor\n---\n\n# Instructor\n\nThe [instructor-embeddings](https://github.com/HKUNLP/instructor-embedding) library is another option, especially when running on a machine with a cuda-capable GPU. They are a good local alternative to OpenAI +(see the [Massive Text Embedding Benchmark](https://huggingface.co/blog/mteb) rankings). The embedding function requires the InstructorEmbedding package. To install it, run ```pip install InstructorEmbedding```.\n\nThere are three models available. The default is `hkunlp/instructor-base`, and for better performance you can use `hkunlp/instructor-large` or `hkunlp/instructor-xl`. You can also specify whether to use `cpu` (default) or `cuda`. For example:\n\n```python\n#uses base model and cpu\nimport chromadb.utils.embedding_functions as embedding_functions\nef = embedding_functions.InstructorEmbeddingFunction()\n```\nor\n```python\nimport chromadb.utils.embedding_functions as embedding_functions\nef = embedding_functions.InstructorEmbeddingFunction(\nmodel_name="hkunlp/instructor-xl", device="cuda")\n```\nKeep in mind that the large and xl models are 1.5GB and 5GB respectively, and are best suited to running on a GPU.\n\n---\nid: jina-ai\nname: Jina AI\n---\n\n# JinaAI\n\nChroma provides a convenient wrapper around JinaAI's embedding API. This embedding function +runs remotely on JinaAI's servers, and requires an API key. You can get an API key by signing up for an account at [JinaAI](https://jina.ai/embeddings/).\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n\n```python\nimport chromadb.utils.embedding_functions as embedding_functions\njinaai_ef = embedding_functions.JinaEmbeddingFunction(\n api_key="YOUR_API_KEY",\n model_name="jina-embeddings-v2-base-en"\n )\njinaai_ef(input=["This is my first text to embed", "This is my second document"])\n```\n\n{% /Tab %}\n\n{% Tab label="typescript" %}\n\n```typescript\nimport { JinaEmbeddingFunction } from 'chromadb';\n\nconst embedder = new JinaEmbeddingFunction({\n jinaai_api_key: 'jina_****',\n model_name: 'jina-embeddings-v2-base-en',\n});\n\n// use directly\nconst embeddings = embedder.generate(['document1', 'document2']);\n\n// pass documents to query for .add and .query\nconst collection = await client.createCollection({name: "name", embeddingFunction: embedder})\nconst collection +Get = await client.getCollection({name:"name", embeddingFunction: embedder})\n```\n\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nYou can pass in an optional `model_name` argument, which lets you choose which Jina model to use. By default, Chroma uses `jina-embedding-v2-base-en`.\n\n---\nid: ollama\nname: Ollama\n---\n\n# Ollama\n\nChroma provides a convenient wrapper around [Ollama](https://github.com/ollama/ollama)'\ns [embeddings API](https://github.com/ollama/ollama/blob/main/docs/api.md#generate-embeddings). You can use\nthe `OllamaEmbeddingFunction` embedding function to generate embeddings for your documents with\na [model](https://github.com/ollama/ollama?tab=readme-ov-file#model-library) of your choice.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n\n```python\nfrom chromadb.utils.embedding_functions.ollama_embedding_function import (\n OllamaEmbeddingFunction,\n)\n\nollama_ef = OllamaEmbeddingFunction(\n url="http://localhost +:11434",\n model_name="llama2",\n)\n\nembeddings = ollama_ef(["This is my first text to embed",\n "This is my second document"])\n```\n\n{% /Tab %}\n\n{% Tab label="typescript" %}\n\n```typescript\nimport { OllamaEmbeddingFunction } from "chromadb";\nconst embedder = new OllamaEmbeddingFunction({\n url: "http://127.0.0.1:11434/",\n model: "llama2"\n})\n\n// use directly\nconst embeddings = embedder.generate(["document1", "document2"])\n\n// pass documents to query for .add and .query\nlet collection = await client.createCollection({\n name: "name",\n embeddingFunction: embedder\n})\ncollection = await client.getCollection({\n name: "name",\n embeddingFunction: embedder\n})\n```\n\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n---\nid: 'roboflow'\nname: Roboflow\n---\n\n# Roboflow\n\nYou can use [Roboflow Inference](https://inference.roboflow.com) with Chroma to calculate multi-modal text and image embeddings with CLIP. through +the `RoboflowEmbeddingFunction` class. Inference can be used through the Roboflow cloud, or run on your hardware.\n\n## Roboflow Cloud Inference\n\nTo run Inference through the Roboflow cloud, you will need an API key. [Learn how to retrieve a Roboflow API key](https://docs.roboflow.com/api-reference/authentication#retrieve-an-api-key).\n\nYou can pass it directly on creation of the `RoboflowEmbeddingFunction`:\n\n```python\nfrom chromadb.utils.embedding_functions import RoboflowEmbeddingFunction\n\nroboflow_ef = RoboflowEmbeddingFunction(api_key=API_KEY)\n```\n\nAlternatively, you can set your API key as an environment variable:\n\n```terminal\nexport ROBOFLOW_API_KEY=YOUR_API_KEY\n```\n\nThen, you can create the `RoboflowEmbeddingFunction` without passing an API key directly:\n\n```python\nfrom chromadb.utils.embedding_functions import RoboflowEmbeddingFunction\n\nroboflow_ef = RoboflowEmbeddingFunction()\n```\n\n## Local Inference\n\nYou can run Inference on your own hardware.\n\nTo install Inference, you will need Docker installed. Follow the [official Docker installation +instructions](https://docs.docker.com/engine/install/) for guidance on how to install Docker on the device on which you are working.\n\nThen, you can install Inference with pip:\n\n```terminal\npip install inference inference-cli\n```\n\nWith Inference installed, you can start an Inference server. This server will run in the background. The server will accept HTTP requests from the `RoboflowEmbeddingFunction` to calculate CLIP text and image embeddings for use in your application:\n\nTo start an Inference server, run:\n\n```terminal\ninference server start\n```\n\nYour Inference server will run at `http://localhost:9001`.\n\nThen, you can create the `RoboflowEmbeddingFunction`:\n\n```python\nfrom chromadb.utils.embedding_functions import RoboflowEmbeddingFunction\n\nroboflow_ef = RoboflowEmbeddingFunction(api_key=API_KEY, server_url="http://localhost:9001")\n```\n\nThis function will calculate embeddings using your local Inference server instead of the Roboflow cloud.\n\nFor a full tutorial on using Roboflow Inference with Chroma, refer to the [Roboflow Chroma integration tutorial](https://github.com/chroma-core/chroma/blob/main +/examples/use_with/roboflow/embeddings.ipynb).\n\n---\nid: 'voyageai'\nname: 'VoyageAI'\n---\n\n# VoyageAI\n\nChroma also provides a convenient wrapper around VoyageAI's embedding API. This embedding function runs remotely on VoyageAI\u2019s servers, and requires an API key. You can get an API key by signing up for an account at [VoyageAI](https://dash.voyageai.com/).\n\n{% Tabs %}\n{% Tab label="python" %}\n\nThis embedding function relies on the `voyageai` python package, which you can install with `pip install voyageai`.\n\n```python\nimport chromadb.utils.embedding_functions as embedding_functions\nvoyageai_ef = embedding_functions.VoyageAIEmbeddingFunction(api_key="YOUR_API_KEY", model_name="voyage-3-large")\nvoyageai_ef(input=["document1","document2"])\n```\n\n{% /Tab %}\n\n{% Tab label="typescript" %}\n\n```typescript\nimport { VoyageAIEmbeddingFunction } from 'chromadb';\n\nconst embedder = new VoyageAIEmbeddingFunction("apiKey", "model_name")\n\n// use directly\nconst embeddings = embedder.generate(["document1","document +2"])\n\n// pass documents to query for .add and .query\nconst collection = await client.createCollection({name: "name", embeddingFunction: embedder})\nconst collectionGet = await client.getCollection({name: "name", embeddingFunction: embedder})\n```\n\n{% /Tab %}\n\n{% /Tabs %}\n\n### Multilingual model example\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n\n```python\nvoyageai_ef = embedding_functions.VoyageAIEmbeddingFunction(\n api_key="YOUR_API_KEY",\n model_name="voyage-3-large")\n\nmultilingual_texts = [ 'Hello from VoyageAI!', '\u0645\u0631\u062d\u0628\u0627\u064b \u0645\u0646 VoyageAI!!',\n 'Hallo von VoyageAI!', 'Bonjour de VoyageAI!',\n '\xa1Hola desde VoyageAI!', 'Ol\xe1 do VoyageAI!',\n 'Ciao da VoyageAI!', '\u60a8\u597d\uff0c\u6765\u81ea VoyageAI\uff01',\n '\u0915\u094b\u0939\u093f\u0905\u0930 \u0938\u0947 VoyageAI!' ]\n\nvoyageai_ef(input=multilingual_texts)\n\n```\n\n{% /Tab %}\n\n{% Tab label="typescript" %}\n\n```typescript\nimport { VoyageAIEmbeddingFunction } from 'chromadb';\n\n +const embedder = new VoyageAIEmbeddingFunction("apiKey", "voyage-3-large")\n\nmultilingual_texts = [ 'Hello from VoyageAI!', '\u0645\u0631\u062d\u0628\u0627\u064b \u0645\u0646 VoyageAI!!',\n 'Hallo von VoyageAI!', 'Bonjour de VoyageAI!',\n '\xa1Hola desde VoyageAI!', 'Ol\xe1 do VoyageAI!',\n 'Ciao da VoyageAI!', '\u60a8\u597d\uff0c\u6765\u81ea VoyageAI\uff01',\n '\u0915\u094b\u0939\u093f\u0905\u0930 \u0938\u0947 VoyageAI!' ]\n\nconst embeddings = embedder.generate(multilingual_texts)\n\n```\n\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nFor further details on VoyageAI's models check the [documentation](https://docs.voyageai.com/docs/introduction) and the [blogs](https://blog.voyageai.com/).\n\n---\nid: anthropic-mcp\nname: Anthropic MCP\n---\n\n# Anthropic MCP Integration\n\n## What is MCP?\n\nThe Model Context Protocol (MCP) is an open protocol that standardizes how AI applications communicate with data sources and tools. Think of MCP like a USB-C port for AI applications - it provides a universal way to connect AI models like Claude to different services and +data sources.\n\nMCP follows a client-server architecture:\n- **MCP Hosts**: Applications like Claude Desktop that want to access data through MCP\n- **MCP Clients**: Protocol clients that maintain connections with servers\n- **MCP Servers**: Lightweight programs that expose specific capabilities (like Chroma's vector database)\n- **Data Sources**: Your local or remote data that MCP servers can securely access\n\n## What is the Chroma MCP Server?\n\nThe Chroma MCP server allows Claude to directly interact with Chroma's vector database capabilities through this standardized protocol. This enables powerful features like:\n\n- Persistent memory across conversations\n- Semantic search through previous chats\n- Document management and retrieval\n- Vector and keyword search capabilities\n- Metadata management and filtering\n\n## Prerequisites\n\nBefore setting up the Chroma MCP server, ensure you have:\n\n1. Claude Desktop installed (Windows or macOS)\n2. Python 3.10+ installed\n3. `uvx` installed (`curl -LsSf https://astral.sh/uv/install.sh | sh`)\n\n## Setup Guide\n\n### 1. Configure MCP Server\n\n1. Open Claude Desktop\n2. Click on the Claude menu and select "Settings..."\n![mcp-settings](/ +mcp-settings.png)\n3. Click on "Developer" in the left sidebar\n![mcp-developer](/mcp-developer.png)\n4. Click "Edit Config" to open your configuration file\n\nAdd the following configuration:\n\n```json\n{\n "mcpServers": {\n "chroma": {\n "command": "uvx",\n "args": [\n "chroma-mcp",\n "--client-type",\n "persistent",\n "--data-dir",\n "/path/to/your/data/directory"\n ]\n }\n }\n}\n```\n\nReplace `/path/to/your/data/directory` with where you want Chroma to store its data, for example:\n- macOS: `/Users/username/Documents/chroma-data`\n- Windows: `C:\\\\Users\\\\username\\\\Documents\\\\chroma-data`\n\n### 2. Restart and Verify\n\n1. Restart Claude Desktop completely\n2. Look for the hammer \U0001f528 icon in the bottom right of your chat input\n![mcp-hammer](/mcp-hammer.png)\n3. Click it to see available Chroma tools\n![mcp-tools](/mcp-tools.png)\n\nIf you don't see the tools, check the logs at +:\n- macOS: `~/Library/Logs/Claude/mcp*.log`\n- Windows: `%APPDATA%\\Claude\\logs\\mcp*.log`\n\n## Client Types\n\nThe Chroma MCP server supports multiple client types to suit different needs:\n\n### 1. Ephemeral Client (Default)\nBy default, the server will use the ephemeral client.\n```json\n{\n "mcpServers": {\n "chroma": {\n "command": "uvx",\n "args": [\n "chroma-mcp",\n ]\n }\n }\n}\n```\n- Stores data in memory only\n- Data is cleared when the server restarts\n- Useful for temporary sessions or testing\n\n### 2. Persistent Client\n```json\n{\n "mcpServers": {\n "chroma": {\n "command": "uvx",\n "args": [\n "chroma-mcp",\n "--client-type",\n "persistent",\n "--data-dir",\n "/path/to/your/data/directory"\n ]\n }\n }\n}\n```\n- Stores data persistently on your local machine\n- Data survives between restarts\n- Best for personal use and long-term memory\n\n\n +### 3. Self-Hosted Client\n```json\n{\n "mcpServers": {\n "chroma": {\n "command": "uvx",\n "args": [\n "chroma-mcp",\n "--client-type",\n "http",\n "--host",\n "http://localhost:8000",\n "--port",\n "8000",\n "--custom-auth-credentials",\n "username:password",\n "--ssl",\n "true"\n ]\n }\n }\n}\n```\n- Connects to your own Chroma server\n- Full control over data and infrastructure\n- Suitable for team environments\n\n### 4. Cloud Client\n```json\n{\n "mcpServers": {\n "chroma": {\n "command": "uvx",\n "args": [\n "chroma-mcp",\n "--client-type",\n "cloud",\n "--tenant",\n "your-tenant-id",\n "--database",\n "your-database-name",\n "--api-key",\n "your-api-key"\n ]\n }\n }\n}\n```\n- Connects to Chroma Cloud or other hosted instances\n- Scalable and managed infrastructure\n- Best for production +deployments\n\n## Using Chroma with Claude\n\n### Team Knowledge Base Example\n\nLet's say your team maintains a knowledge base of customer support interactions. By storing these in Chroma Cloud, team members can use Claude to quickly access and learn from past support cases.\n\nFirst, set up your shared knowledge base:\n\n```python\nimport chromadb\nfrom datetime import datetime\n\n# Connect to Chroma Cloud\nclient = chromadb.HttpClient(\n ssl=True,\n host='api.trychroma.com',\n tenant='your-tenant-id',\n database='support-kb',\n headers={\n 'x-chroma-token': 'YOUR_API_KEY'\n }\n)\n\n# Create a collection for support cases\ncollection = client.create_collection("support_cases")\n\n# Add some example support cases\nsupport_cases = [\n {\n "case": "Customer reported issues connecting their IoT devices to the dashboard.",\n "resolution": "Guided customer through firewall configuration and port forwarding setup.",\n "category": "connectivity",\n "date": "2024-03-15"\n },\n {\n "case": "User couldn't access admin features after recent update.",\n "resolution": "Discovered role permissions weren't migrated correctly. Applied fix +and documented process.",\n "category": "permissions",\n "date": "2024-03-16"\n }\n]\n\n# Add documents to collection\ncollection.add(\n documents=[case["case"] + "\\n" + case["resolution"] for case in support_cases],\n metadatas=[{\n "category": case["category"],\n "date": case["date"]\n } for case in support_cases],\n ids=[f"case_{i}" for i in range(len(support_cases))]\n)\n```\n\nNow team members can use Claude to access this knowledge.\n\nIn your claude config, add the following:\n```json\n{\n "mcpServers": {\n "chroma": {\n "command": "uvx",\n "args": [\n "chroma-mcp",\n "--client-type",\n "cloud",\n "--tenant",\n "your-tenant-id",\n "--database",\n "support-kb",\n "--api-key",\n "YOUR_API_KEY"\n ]\n }\n }\n}\n```\n\nNow you can use the knowledge base in your chats:\n```\nClaude, I'm having trouble helping a customer with IoT device connectivity.\nCan you check our support knowledge +base for similar cases and suggest a solution?\n```\n\nClaude will:\n1. Search the shared knowledge base for relevant cases\n2. Consider the context and solutions from similar past issues\n3. Provide recommendations based on previous successful resolutions\n\nThis setup is particularly powerful because:\n- All support team members have access to the same knowledge base\n- Claude can learn from the entire team's experience\n- Solutions are standardized across the organization\n- New team members can quickly get up to speed on common issues\n\n### Project Memory Example\n\nClaude's context window has limits - long conversations eventually get truncated, and chats don't persist between sessions. Using Chroma as an external memory store solves these limitations, allowing Claude to reference past conversations and maintain context across multiple sessions.\n\nFirst, tell Claude to use Chroma for memory as part of the project setup:\n```\nRemember, you have access to Chroma tools.\nAt any point if the user references previous chats or memory, check chroma for similar conversations.\nTry to use retrieved information where possible.\n```\n\n![mcp-instructions](/mcp-instructions.png)\n\nThis prompt instructs Claude to:\n- Proactively check Chroma when memory-related topics come up\n- Search for semantically similar +past conversations\n- Incorporate relevant historical context into responses\n\nTo store the current conversation:\n```\nPlease chunk our conversation into small chunks and store it in Chroma for future reference.\n```\n\nClaude will:\n1. Break the conversation into smaller chunks (typically 512-1024 tokens)\n - Chunking is necessary because:\n - Large texts are harder to search semantically\n - Smaller chunks help retrieve more precise context\n - It prevents token limits in future retrievals\n2. Generate embeddings for each chunk\n3. Add metadata like timestamps and detected topics\n4. Store everything in your Chroma collection\n\n![mcp-store](/mcp-store.png)\n\nLater, you can access past conversations naturally:\n```\nWhat did we discuss previously about the authentication system?\n```\n\nClaude will:\n1. Search Chroma for chunks semantically related to authentication\n2. Filter by timestamp metadata for last week's discussions\n3. Incorporate the relevant historical context into its response\n\n![mcp-search](/mcp-search.png)\n\nThis setup is particularly useful for:\n- Long-running projects where context gets lost\n- Teams where multiple people interact with Claude\n- Complex discussions that reference past decisions\n- Maint +aining consistent context across multiple chat sessions\n\n### Advanced Features\n\nThe Chroma MCP server supports:\n\n- **Collection Management**: Create and organize separate collections for different projects\n- **Document Operations**: Add, update, or delete documents\n- **Search Capabilities**:\n - Vector similarity search\n - Keyword-based search\n - Metadata filtering\n- **Batch Processing**: Efficient handling of multiple operations\n\n## Troubleshooting\n\nIf you encounter issues:\n\n1. Verify your configuration file syntax\n2. Ensure all paths are absolute and valid\n3. Try using full paths for `uvx` with `which uvx` and using that path in the config\n4. Check the Claude logs (paths listed above)\n\n## Resources\n\n- [Model Context Protocol Documentation](https://modelcontextprotocol.io/introduction)\n- [Chroma MCP Server Documentation](https://github.com/chroma-core/chroma-mcp)\n- [Claude Desktop Guide](https://docs.anthropic.com/claude/docs/claude-desktop)\n\n\n---\nid: braintrust\nname: Braintrust\n---\n\n# Braintrust\n\n[Braintrust](https://www.braintrustdata.com) is an enterprise-grade stack for building AI products including: evaluations, prompt +playground, dataset management, tracing, etc.\n\nBraintrust provides a Typescript and Python library to run and log evaluations and integrates well with Chroma.\n\n- [Tutorial: Evaluate Chroma Retrieval app w/ Braintrust](https://www.braintrustdata.com/docs/examples/rag)\n\nExample evaluation script in Python:\n(refer to the tutorial above to get the full implementation)\n```python\nfrom autoevals.llm import *\nfrom braintrust import Eval\n\nPROJECT_NAME="Chroma_Eval"\n\nfrom openai import OpenAI\n\nclient = OpenAI()\nleven_evaluator = LevenshteinScorer()\n\nasync def pipeline_a(input, hooks=None):\n # Get a relevant fact from Chroma\n relevant = collection.query(\n query_texts=[input],\n n_results=1,\n )\n relevant_text = ','.join(relevant["documents"][0])\n prompt = """\n You are an assistant called BT. Help the user.\n Relevant information: {relevant}\n Question: {question}\n Answer:\n """.format(question=input, relevant=relevant_text)\n messages = [{"role": "system", "content": prompt}]\n response = client.chat.completions.create(\n model="gpt- +3.5-turbo",\n messages=messages,\n temperature=0,\n max_tokens=100,\n )\n\n result = response.choices[0].message.content\n return result\n\n# Run an evaluation and log to Braintrust\nawait Eval(\n PROJECT_NAME,\n # define your test cases\n data = lambda:[{"input": "What is my eye color?", "expected": "Brown"}],\n # define your retrieval pipeline w/ Chroma above\n task = pipeline_a,\n # use a prebuilt scoring function or define your own :)\n scores=[leven_evaluator],\n)\n```\n\nLearn more: [docs](https://www.braintrustdata.com/docs).\n\n---\nid: deepeval\nname: DeepEval\n---\n\n# DeepEval\n\n[DeepEval](https://docs.confident-ai.com/docs/integrations-chroma) is the open-source LLM evaluation framework. It provides 20+ research-backed metrics to help you evaluate and pick the best hyperparameters for your LLM system.\n\nWhen building a RAG system, you can use DeepEval to pick the best parameters for your **Choma retriever** for optimal retrieval performance and accuracy: `n_results`, ` +distance_function`, `embedding_model`, `chunk_size`, etc.\n\n{% Banner type="tip" %}\nFor more information on how to use DeepEval, see the [DeepEval docs](https://docs.confident-ai.com/docs/getting-started).\n{% /Banner %}\n\n## Getting Started\n\n### Step 1: Installation\n\n```CLI\npip install deepeval\n```\n\n### Step 2: Preparing a Test Case\n\nPrepare a query, generate a response using your RAG pipeline, and store the retrieval context from your Chroma retriever to create an `LLMTestCase` for evaluation.\n\n```python\n...\n\ndef chroma_retriever(query):\n query_embedding = model.encode(query).tolist() # Replace with your embedding model\n res = collection.query(\n query_embeddings=[query_embedding],\n n_results=3\n )\n return res["metadatas"][0][0]["text"]\n\nquery = "How does Chroma work?"\nretrieval_context = search(query)\nactual_output = generate(query, retrieval_context) # Replace with your LLM function\n\ntest_case = LLMTestCase(\n input=query,\n retrieval_context=retrieval_context,\n actual_output=actual_output\n)\n +```\n\n### Step 3: Evaluation\n\nDefine retriever metrics like `Contextual Precision`, `Contextual Recall`, and `Contextual Relevancy` to evaluate test cases. Recall ensures enough vectors are retrieved, while relevancy reduces noise by filtering out irrelevant ones.\n\n{% Banner type="tip" %}\nBalancing recall and relevancy is key. `distance_function` and `embedding_model` affects recall, while `n_results` and `chunk_size` impact relevancy. \n{% /Banner %}\n\n```python\nfrom deepeval.metrics import (\n ContextualPrecisionMetric,\n ContextualRecallMetric,\n ContextualRelevancyMetric\n)\nfrom deepeval import evaluate\n...\n\nevaluate(\n [test_case],\n [\n ContextualPrecisionMetric(),\n ContextualRecallMetric(),\n ContextualRelevancyMetric(),\n ],\n)\n```\n\n### 4. Visualize and Optimize\n\nTo visualize evaluation results, log in to the [Confident AI (DeepEval platform)](https://www.confident-ai.com/) by running:\n\n```\ndeepeval login\n```\n\nWhen logged in, running `evaluate` will automatically send evaluation results to Confident AI, where you can visualize +and analyze performance metrics, identify failing retriever hyperparameters, and optimize your Chroma retriever for better accuracy.\n\n![](https://github.com/confident-ai/deepeval/raw/main/assets/demo.gif)\n\n{% Banner type="tip" %}\nTo learn more about how to use the platform, please see [this Quickstart Guide](https://docs.confident-ai.com/confident-ai/confident-ai-introduction).\n{% /Banner %}\n\n## Support\n\nFor any question or issue with integration you can reach out to the DeepEval team on [Discord](https://discord.com/invite/a3K9c8GRGt).\n\n---\nid: haystack\nname: Haystack\n---\n\n# Haystack\n\n[Haystack](https://github.com/deepset-ai/haystack) is an open-source LLM framework in Python. It provides [embedders](https://docs.haystack.deepset.ai/v2.0/docs/embedders), [generators](https://docs.haystack.deepset.ai/v2.0/docs/generators) and [rankers](https://docs.haystack.deepset.ai/v2.0/docs/rankers) via a number of LLM providers, +tooling for [preprocessing](https://docs.haystack.deepset.ai/v2.0/docs/preprocessors) and data preparation, connectors to a number of vector databases including Chroma and more. Haystack allows you to build custom LLM applications using both components readily available in Haystack and [custom components](https://docs.haystack.deepset.ai/v2.0/docs/custom-components). Some of the most common applications you can build with Haystack are retrieval-augmented generation pipelines (RAG), question-answering and semantic search.\n\n![](https://img.shields.io/github/stars/deepset-ai/haystack.svg?style=social&label=Star&maxAge=2400)\n\n|[Docs](https://docs.haystack.deepset.ai/v2.0/docs) | [Github](https://github.com/deepset-ai/haystack) | [Haystack Integrations](https://haystack.deepset.ai/integrations) | [Tutorials](https://haystack.deepset.ai/tutorials) |\n\nYou can use Chroma together with Haystack by installing the integration and using the `ChromaDocumentStore`\n\n### Installation\n\n```terminal\npip install chroma-h +aystack\n```\n\n### Usage\n\n- The [Chroma Integration page](https://haystack.deepset.ai/integrations/chroma-documentstore)\n- [Chroma + Haystack Example](https://colab.research.google.com/drive/1YpDetI8BRbObPDEVdfqUcwhEX9UUXP-m?usp=sharing)\n\n#### Write documents into a ChromaDocumentStore\n\n```python\nimport os\nfrom pathlib import Path\n\nfrom haystack import Pipeline\nfrom haystack.components.converters import TextFileToDocument\nfrom haystack.components.writers import DocumentWriter\nfrom chroma_haystack import ChromaDocumentStore\n\nfile_paths = ["data" / Path(name) for name in os.listdir("data")]\n\ndocument_store = ChromaDocumentStore()\n\nindexing = Pipeline()\nindexing.add_component("converter", TextFileToDocument())\nindexing.add_component("writer", DocumentWriter(document_store))\n\nindexing.connect("converter", "writer")\nindexing.run({"converter": {"sources": file_paths}})\n```\n\n#### Build RAG on top of Chroma\n\n```python\nfrom chroma_haystack.retriever import ChromaQueryRetriever\nfrom haystack.components.generators import +HuggingFaceTGIGenerator\nfrom haystack.components.builders import PromptBuilder\n\nprompt = """\nAnswer the query based on the provided context.\nIf the context does not contain the answer, say 'Answer not found'.\nContext:\n{% for doc in documents %}\n {{ doc.content }}\n{% endfor %}\nquery: {{query}}\nAnswer:\n"""\nprompt_builder = PromptBuilder(template=prompt)\n\nllm = HuggingFaceTGIGenerator(model="mistralai/Mixtral-8x7B-Instruct-v0.1", token='YOUR_HF_TOKEN')\nllm.warm_up()\nretriever = ChromaQueryRetriever(document_store)\n\nquerying = Pipeline()\nquerying.add_component("retriever", retriever)\nquerying.add_component("prompt_builder", prompt_builder)\nquerying.add_component("llm", llm)\n\nquerying.connect("retriever.documents", "prompt_builder.documents")\nquerying.connect("prompt_builder", "llm")\n\nresults = querying.run({"retriever": {"queries": [query], "top_k": 3},\n "prompt_builder": {"query": query}})\n```\n\n---\nid: langchain\nname: Langchain\n---\n\n# Langchain\n\n## Langchain - +Python\n\n- [LangChain + Chroma](https://blog.langchain.dev/langchain-chroma/) on the LangChain blog\n- [Harrison's `chroma-langchain` demo repo](https://github.com/hwchase17/chroma-langchain)\n - [question answering over documents](https://github.com/hwchase17/chroma-langchain/blob/master/qa.ipynb) - ([Replit version](https://replit.com/@swyx/LangChainChromaStarter#main.py))\n - [to use Chroma as a persistent database](https://github.com/hwchase17/chroma-langchain/blob/master/persistent-qa.ipynb)\n- Tutorials\n - [Chroma and LangChain tutorial](https://github.com/grumpyp/chroma-langchain-tutorial) - The demo showcases how to pull data from the English Wikipedia using their API. The project also demonstrates how to vectorize data in chunks and get embeddings using OpenAI embeddings model.\n - [Create a Voice-based ChatGPT Clone That Can Search on the Internet and local files](https://betterprogramming.pub/how-to-create-a-voice-based-chatgpt-clone-that-can-search-on +-the-internet-24d7f570ea8)\n- [LangChain's Chroma Documentation](https://python.langchain.com/docs/integrations/vectorstores/chroma)\n\n\n## Langchain - JS\n\n- [LangChainJS Chroma Documentation](https://js.langchain.com/docs/modules/indexes/vector_stores/integrations/chroma)\n\n---\nid: llamaindex\nname: LlamaIndex\n---\n\n# LlamaIndex\n\n- `LlamaIndex` [Vector Store page](https://docs.llamaindex.ai/en/stable/examples/vector_stores/ChromaIndexDemo.html)\n- [Demo](https://github.com/jerryjliu/llama_index/blob/main/docs/examples/vector_stores/ChromaIndexDemo.ipynb)\n- [Chroma Loader on Llamahub](https://llamahub.ai/l/chroma)\n\n---\nid: openlit\nname: OpenLIT\n---\n\n# OpenLIT\n\n[OpenLIT](https://github.com/openlit/openlit) is an OpenTelemetry-native LLM Application Observability tool and includes OpenTelemetry auto-instrumention for Chroma with just a single line of code helping you ensure your applications are monitored seamlessly, providing +critical insights to improve performance, operations and reliability.\n\nFor more information on how to use OpenLIT, see the [OpenLIT docs](https://docs.openlit.io/).\n\n## Getting Started\n\n### Step 1: Install OpenLIT\n\nOpen your command line or terminal and run:\n\n```bash\npip install openlit\n```\n\n### Step 2: Initialize OpenLIT in your Application\nIntegrating OpenLIT into LLM applications is straightforward. Start monitoring for your LLM Application with just **two lines of code**:\n\n```python\nimport openlit\n\nopenlit.init()\n```\n\nTo forward telemetry data to an HTTP OTLP endpoint, such as the OpenTelemetry Collector, set the `otlp_endpoint` parameter with the desired endpoint. Alternatively, you can configure the endpoint by setting the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable as recommended in the OpenTelemetry documentation.\n\n> \U0001f4a1 Info: If you don't provide `otlp_endpoint` function argument or set the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable, OpenLIT directs the trace directly to your console, which can be useful during development.\nTo send telemetry to OpenTelemetry backends requiring authentication, set +the `otlp_headers` parameter with its desired value. Alternatively, you can configure the endpoint by setting the `OTEL_EXPORTER_OTLP_HEADERS` environment variable as recommended in the OpenTelemetry documentation.\n\n### Step 3: Visualize and Optimize!\n\n![](https://github.com/openlit/.github/blob/main/profile/assets/openlit-client-1.png?raw=true)\n\nWith the LLM Observability data now being collected by OpenLIT, the next step is to visualize and analyze this data to get insights into your LLM application\u2019s performance, behavior, and identify areas of improvement.\n\nTo begin exploring your LLM Application's performance data within the OpenLIT UI, please see the [Quickstart Guide](https://docs.openlit.io/latest/quickstart).\n\nIf you want to integrate and send metrics and traces to your existing observability tools like Promethues+Jaeger, Grafana or more, refer to the [Official Documentation for OpenLIT Connections](https://docs.openlit.io/latest/connections/intro) for detailed instructions.\n\n\n## Support\n\nFor any question or issue with integration you can reach out to the OpenLIT team on [Slack](https://join.slack.com/t/openlit/shared_invite +/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ) or via [email](mailto:contact@openlit.io).\n\n---\nid: openLLMetry\nname: OpenLLMetry\n---\n\n# OpenLLMetry\n\n[OpenLLMetry](https://www.traceloop.com/openllmetry) provides observability for systems using Chroma. It allows tracing calls to Chroma, OpenAI, and other services.\nIt gives visibility to query and index calls as well as LLM prompts and completions.\nFor more information on how to use OpenLLMetry, see the [OpenLLMetry docs](https://www.traceloop.com/docs/openllmetry).\n\n![](/openllmetry.png)\n\n### Example\n\nInstall OpenLLMetry SDK by running:\n\n```terminal\npip install traceloop-sdk\n```\n\nThen, initialize the SDK in your application:\n\n```python\nfrom traceloop.sdk import Traceloop\n\nTraceloop.init()\n```\n\n### Configuration\n\nOpenLLMetry can be configured to send traces to any observability platform that supports OpenTelemetry - Datadog, +Honeycomb, Dynatrace, New Relic, etc. See the [OpenLLMetry docs](https://www.traceloop.com/openllmetry/provider/chroma) for more information.\n\n---\nid: streamlit\nname: Streamlit\n---\n\n# Streamlit\n\nStreamlit is an open-source Python library that makes it easy to create and share beautiful, custom web apps for machine learning and data science. In just a few minutes you can build and deploy powerful data apps.\n\n![](https://img.shields.io/github/stars/streamlit/streamlit.svg?style=social&label=Star&maxAge=2400)\n\n[Apache 2.0 License](https://github.com/streamlit/streamlit/blob/develop/LICENSE)  • [Site](https://streamlit.io/)\n\n{% special_table %}\n{% /special_table %}\n\n| Languages | Docs | Github |\n|--|--|--|\n| Python | [Docs](https://docs.streamlit.io/) | [Code](https://github.com/streamlit/streamlit)\n\n### Install\n\nInstall Streamlit: {% br %}{% /br %}\n`pip install streamlit`\n\nInstall `streamlit-chromadb-connection`, which connects your Stream +lit app to Chroma through [`st.connection`](https://docs.streamlit.io/1.11.0/library/api-reference/connections/st.connection): {% br %}{% /br %}\n`pip install streamlit-chromadb-connection`\n\n### Main Benefits\n\n- Easy to get started with Streamlit's straightforward syntax\n- Built-in [chatbot functionality](https://docs.streamlit.io/library/api-reference/chat)\n- Pre-built integration with Chroma via `streamlit-chromadb-connection`\n- Deploy apps for free on [Streamlit Community Cloud](https://share.streamlit.io/)\n\n### Simple Example\n\n#### Python\n\n```python\nimport streamlit as st\nfrom streamlit_chromadb_connection.chromadb_connection import ChromadbConnection\n\nconfiguration = {\n "client": "PersistentClient",\n "path": "/tmp/.chroma"\n}\n\ncollection_name = "documents_collection"\n\nconn = st.connection("chromadb",\n type=ChromaDBConnection,\n **configuration)\ndocuments_collection_df = conn.get_collection_data(collection_name)\nst.dataframe(documents_collection_df)\n```\n\n### Resources\n\n- [Instructions for using `streamlit-chromadb-connection` to connect your Streamlit app to Chroma]( +https://github.com/Dev317/streamlit_chromadb_connection/blob/main/README.md)\n- [Demo app for `streamlit-chromadb-connection`](https://app-chromadbconnection-mfzxl3nzozmaxh3mrkd6zm.streamlit.app/)\n- [Streamlit's `st.connection` documentation](https://docs.streamlit.io/library/api-reference/connections/st.connection)\n- [Guide to using vector databases with Streamlit](https://pub.towardsai.net/vector-databases-for-your-streamlit-ai-apps-56cd0af7bbba)\n\n#### Tutorials\n\n- [Build an "Ask the Doc" app using Chroma, Streamlit, and LangChain](https://blog.streamlit.io/langchain-tutorial-4-build-an-ask-the-doc-app/)\n- [Summarize documents with Chroma, Streamlit, and LangChain](https://alphasec.io/summarize-documents-with-langchain-and-chroma/)\n- [Build a custom chatbot with Chroma, Streamlit, and LangChain](https://blog.streamlit.io/how-in-app-feedback-can-increase-your-chatbots-performance/)\n- [Build a RAG bot using Chroma, Streamlit +, and LangChain](https://levelup.gitconnected.com/building-a-generative-ai-app-with-streamlit-and-openai-95ec31fe8efd)\n- [Build a PDF QA chatbot with Chroma, Streamlit, and OpenAI](https://www.confident-ai.com/blog/how-to-build-a-pdf-qa-chatbot-using-openai-and-chromadb)\n\n +# Migration\n\nSchema and data format changes are a necessary evil of evolving software. We take changes seriously and make them infrequently and only when necessary.\n\nChroma's commitment is whenever schema or data format change, we will provide a seamless and easy-to-use migration tool to move to the new schema/format.\n\nSpecifically we will announce schema changes on:\n\n- Discord ([#migrations channel](https://discord.com/channels/1073293645303795742/1129286514845691975))\n- Github ([here](https://github.com/chroma-core/chroma/issues))\n- Email listserv [Sign up](https://airtable.com/shrHaErIs1j9F97BE)\n\nWe will aim to provide:\n\n- a description of the change and the rationale for the change.\n- a CLI migration tool you can run\n- a video walkthrough of using the tool\n\n## Migration Log\n\n### v1.0.0\n\nIn this release, we've rewritten much of Chroma in Rust. Performance has significantly improved across the board.\n\n**Breaking changes**\n\nChroma no longer provides built-in authentication implementations.\n\n**Chroma in-process changes**\n\nThis section is applicable to you if you use Chroma via\n\n```python\n +import chromadb\n\nclient = chromadb.Client()\n# or\nclient = chromadb.EphemeralClient()\n# or\nclient = chromadb.PersistentClient()\n```\n\nThe new Rust implementation ignores these settings:\n\n- `chroma_server_nofile`\n- `chroma_server_thread_pool_size`\n- `chroma_memory_limit_bytes`\n- `chroma_segment_cache_policy`\n\n**Chroma CLI changes**\n\nThis section is applicable to you if you run a Chroma server using the CLI (`chroma run`).\n\nSettings that you may have previously provided to the server using environment variables, like `CHROMA_SERVER_CORS_ALLOW_ORIGINS` or `CHROMA_OTEL_COLLECTION_ENDPOINT`, are now provided using a configuration file. For example:\n\n```terminal\nchroma run --config ./config.yaml\n```\n\nCheck out a full sample configuration file [here](https://github.com/chroma-core/chroma/blob/main/rust/frontend/sample_configs/single_node_full.yaml).\n\n\n**Chroma in Docker changes**\n\nThis section is applicable to you if you run Chroma using a Docker container.\n\nSettings that you previously provided to the container using environment variables, like `CHROMA_SERVER_CORS_ALLOW_ORIGINS` or `CHROMA_OT +EL_COLLECTION_ENDPOINT`, are now provided to the container using a configuration file. See the [Docker documentation](../production/containers/docker#configuration) for more information.\n\nThe default data location in the container has changed from `/chroma/chroma` to `/data`. For example, if you previously started the container with:\n\n```terminal\ndocker run -p 8000:8000 -v ./chroma:/chroma/chroma chroma-core/chroma\n```\n\nyou should now start it with:\n\n```terminal\ndocker run -p 8000:8000 -v ./chroma:/data chroma-core/chroma\n```\n\n\n### v0.6.0\n\nPreviously, `list_collections` returned a list of `Collection` objects. This could lead to some errors if any of your collections were created with a custom embedding function (i.e. not the default). So moving forward, `list_collections` will only return collections names.\n\nFor example, if you created all your collections with the `OpenAIEmbeddingFunction` , this is how you will use `list_collections` and `get_collection` correctly:\n\n```python\ncollection_names = client.list_collections()\nef = OpenAIEmbeddingFunction(...)\ncollections = +[\n\tclient.get_collection(name=name, embedding_function=ef)\n\tfor name in collection_names\n]\n```\n\nIn the future, we plan on supporting embedding function persistence, so `list_collections` can return properly configured `Collection` objects, and you won\u2019t need to supply the correct embedding function to `get_collection`.\n\nAdditionally, we have dropped support for Python 3.8\n\n### v0.5.17\n\nWe no longer support sending empty lists or dictionaries for metadata filtering, ID filtering, etc. For example,\n\n```python\ncollection.get(\n\tids=["id1", "id2", "id3", ...],\n\twhere={}\n)\n```\n\nis not supported. Instead, use:\n\n```python\ncollection.get(ids=["id1", "id2", "id3", ...])\n```\n\n### v0.5.12\n\nThe operators `$ne` (not equal) and `$nin` (not in) in `where` clauses have been updated:\n* Previously: They only matched records that had the specified key.\n* Now: They also match records that don't have the specified key at all.\n\nIn other words, `$ne` and `$nin` now match the complement set of records (the exact opposite) that +`$eq` (equals) and `$in` (in) would match, respectively.\n\nThe `$not_contains` operator in the `where_document` clause has also been updated:\n* Previously: It only matched records that had a document field.\n* Now: It also matches records that don't have a document field at all.\n\nIn other words, `$not_contains` now matches the exact opposite set of records that `$contains` would match.\n\n`RateLimitingProvider` is now deprecated and replaced by `RateLimitEnforcer`. This new interface allows you to wrap server calls with rate limiting logic. The default `SimpleRateLimitEnforcer` implementation allows all requests, but you can create custom implementations for more advanced rate limiting strategies.\n### v0.5.11\n\nThe results returned by `collection.get()` is now ordered by internal ids. Whereas previously, the results were ordered by user provided ids, although this behavior was not explicitly documented. We would like to make the change because using user provided ids may not be ideal for performance in hosted Chroma, and we hope to propagate the change to local Chroma for consistency of behavior. In general, newer documents in Chroma has larger internal ids.\n\nA subsequent change in behavior is ` +limit` and `offset`, which depends on the order of returned results. For example, if you have a collection named `coll` of documents with ids `["3", "2", "1", "0"]` inserted in this order, then previously `coll.get(limit=2, offset=2)["ids"]` gives you `["2", "3"]`, while currently this will give you `["1", "0"]`.\n\nWe have also modified the behavior of `client.get_or_create`. Previously, if a collection already existed and the `metadata` argument was provided, the existing collection's metadata would be overwritten with the new values. This has now changed. If the collection already exists, get_or_create will simply return the existing collection with the specified name, and any additional arguments\u2014including `metadata`\u2014will be ignored.\n\nFinally, the embeddings returned from `collection.get()`, `collection.query()`, and `collection.peek()` are now represented as 2-dimensional NumPy arrays instead of Python lists. When adding embeddings, you can still use either a Python list or a NumPy array. If your request returns multiple embeddings, the result will be a Python list containing 2-dimensional NumPy arrays. This change is part +of our effort to enhance performance in Local Chroma by using NumPy arrays for internal representation of embeddings.\n\n### v0.5.6\n\nChroma internally uses a write-ahead log. In all versions prior to v0.5.6, this log was never pruned. This resulted in the data directory being much larger than it needed to be, as well as the directory size not decreasing by the expected amount after deleting a collection.\n\nIn v0.5.6 the write-ahead log is pruned automatically. However, this is not enabled by default for existing databases. After upgrading, you should run `chroma utils vacuum` once to reduce your database size and enable continuous pruning. See the [CLI reference](/reference/cli#vacuuming) for more details.\n\nThis does not need to be run regularly and does not need to be run on new databases created with v0.5.6 or later.\n\n### v0.5.1\n\nOn the Python client, the `max_batch_size` property was removed. It wasn't previously documented, but if you were reading it, you should now use `get_max_batch_size()`.\n\nThe first time this is run, it makes a HTTP request. We made this +a method to make it more clear that it's potentially a blocking operation.\n\n### Auth overhaul - April 20, 2024\n\n**If you are not using Chroma's [built-in auth system](https://docs.trychroma.com/deployment/auth), you do not need to take any action.**\n\nThis release overhauls and simplifies our authentication and authorization systems.\nIf you are you using Chroma's built-in auth system, you will need to update your configuration and\nany code you wrote to implement your own authentication or authorization providers.\nThis change is mostly to pay down some of Chroma's technical debt and make future changes easier,\nbut it also changes and simplifies user configuration.\nIf you are not using Chroma's built-in auth system, you do not need to take any action.\n\nPreviously, Chroma's authentication and authorization relied on many objects with many configuration options, including:\n\n- `chroma_server_auth_provider`\n- `chroma_server_auth_configuration_provider`\n- `chroma_server_auth_credentials_provider`\n- `chroma_client_auth_credentials_provider`\n- `chroma_client_auth_protocol_adapter`\n\nand others.\n\nWe have consolidated these into three classes:\n\n- `ClientAuthProvider`\n- `ServerAuthenticationProvider`\n- +`ServerAuthorizationProvider`\n\n`ClientAuthProvider`s are now responsible for their own configuration and credential management. Credentials can be given to them with the `chroma_client_auth_credentials` setting. The value for `chroma_client_auth_credentials` depends on the `ServerAuthenticationProvider`; for `TokenAuthenticationServerProvider` it should just be the token, and for `BasicAuthenticationServerProvider` it should be `username:password`.\n\n`ServerAuthenticationProvider`s are responsible for turning a request's authorization information into a `UserIdentity` containing any information necessary to make an authorization decision. They are now responsible for their own configuration and credential management. Configured via the `chroma_server_authn_credentials` and `chroma_server_authn_credentials_file` settings.\n\n`ServerAuthorizationProvider`s are responsible for turning information about the request and the `UserIdentity` which issued the request into an authorization decision. Configured via the `chroma_server_authz_config` and `chroma_server_authz_config_file` settings.\n\n_Either `_authn_credentials` or `authn_credentials_file` can be set, never both. Same for `authz_config` and `authz_config_file`. The value of the config (or data in the config file +) will depend on your authn and authz providers. See [here](https://github.com/chroma-core/chroma/tree/main/examples/basic_functionality/authz) for more information._\n\nThe two auth systems Chroma ships with are `Basic` and `Token`. We have a small migration guide for each.\n\n#### Basic\n\nIf you're using `Token` auth, your server configuration might look like:\n\n```yaml\nCHROMA_SERVER_AUTH_CREDENTIALS="admin:admin"\nCHROMA_SERVER_AUTH_CREDENTIALS_FILE="./example_file"\nCHROMA_SERVER_AUTH_CREDENTIALS_PROVIDER="chromadb.auth.providers.HtpasswdConfigurationServerAuthCredentialsProvider"\nCHROMA_SERVER_AUTH_PROVIDER="chromadb.auth.basic.BasicAuthServerProvider"\n```\n\n_Note: Only one of `AUTH_CREDENTIALS` and `AUTH_CREDENTIALS_FILE` can be set, but this guide shows how to migrate both._\n\nAnd your corresponding client configation:\n\n```yaml\nCHROMA_CLIENT_AUTH_PROVIDER="chromadb.auth.token.TokenAuthClientProvider"\nCHROMA_CLIENT_AUTH_CREDENTIALS="admin:admin"\n```\n\nTo migrate to the new server configuration, simply change it to:\n\n```yaml\nCHROMA_SERVER_AUTHN_PROVIDER +="chromadb.auth.token_authn.TokenAuthenticationServerProvider"\nCHROMA_SERVER_AUTHN_CREDENTIALS="test-token"\nCHROMA_SERVER_AUTHN_CREDENTIALS_FILE="./example_file"\n```\n\nNew client configuration:\n\n```yaml\nCHROMA_CLIENT_AUTH_CREDENTIALS="test-token"\nCHROMA_CLIENT_AUTH_PROVIDER="chromadb.auth.basic_authn.BasicAuthClientProvider"\n```\n\n#### Token\n\nIf you're using `Token` auth, your server configuration might look like:\n\n```yaml\nCHROMA_SERVER_AUTH_CREDENTIALS="test-token"\nCHROMA_SERVER_AUTH_CREDENTIALS_FILE="./example_file"\nCHROMA_SERVER_AUTH_CREDENTIALS_PROVIDER="chromadb.auth.token.TokenConfigServerAuthCredentialsProvider"\nCHROMA_SERVER_AUTH_PROVIDER="chromadb.auth.token.TokenAuthServerProvider"\nCHROMA_SERVER_AUTH_TOKEN_TRANSPORT_HEADER="AUTHORIZATION"\n```\n\n_Note: Only one of `AUTH_CREDENTIALS` and `AUTH_CREDENTIALS_FILE` can be set, but this guide shows how to migrate both._\n\nAnd your corresponding client configation:\n\n```yaml\nCHROMA_CLIENT_AUTH_PROVIDER="chromadb.auth.token.TokenAuthClientProvider"\nCHROMA_CLIENT_AUTH_CREDENTIALS="test-token"\n +CHROMA_CLIENT_AUTH_TOKEN_TRANSPORT_HEADER="AUTHORIZATION"\n```\n\nTo migrate to the new server configuration, simply change it to:\n\n```yaml\nCHROMA_SERVER_AUTHN_PROVIDER="chromadb.auth.token_authn.TokenAuthenticationServerProvider"\nCHROMA_SERVER_AUTHN_CREDENTIALS="test-token"\nCHROMA_SERVER_AUTHN_CREDENTIALS_FILE="./example_file"\nCHROMA_AUTH_TOKEN_TRANSPORT_HEADER="AUTHORIZATION"\n```\n\nNew client configuration:\n\n```yaml\nCHROMA_CLIENT_AUTH_CREDENTIALS="test-token"\nCHROMA_CLIENT_AUTH_PROVIDER="chromadb.auth.token_authn.TokenAuthClientProvider"\nCHROMA_AUTH_TOKEN_TRANSPORT_HEADER="AUTHORIZATION"\n```\n\n#### Reference of changed configuration values\n\n- Overall config\n - `chroma_client_auth_token_transport_header`: renamed to `chroma_auth_token_transport_header`.\n - `chroma_server_auth_token_transport_header`: renamed to `chroma_auth_token_transport_header`.\n- Client config\n - `chroma_client_auth_credentials_provider`: deleted. Functionality is now in `chroma_client_auth_provider`.\n - `chroma_client_auth_protocol_adapter`: deleted. Functionality is now in `chroma_client_auth_provider`.\n - ` +chroma_client_auth_credentials_file`: deleted. Functionality is now in `chroma_client_auth_credentials`.\n - These changes also apply to the Typescript client.\n- Server authn\n - `chroma_server_auth_provider`: Renamed to `chroma_server_authn_provider`.\n - `chroma_server_auth_configuration_provider`: deleted. Functionality is now in `chroma_server_authn_provider`.\n - `chroma_server_auth_credentials_provider`: deleted. Functionality is now in `chroma_server_authn_provider`.\n - `chroma_server_auth_credentials_file`: renamed to `chroma_server_authn_credentials_file`.\n - `chroma_server_auth_credentials`: renamed to `chroma_server_authn_credentials`.\n - `chroma_server_auth_configuration_file`: renamed to `chroma_server_authn_configuration_file`.\n- Server authz\n - `chroma_server_authz_ignore_paths`: deleted. Functionality is now in `chroma_server_auth_ignore_paths`.\n\nTo see the full changes, you can read the [PR](https://github.com/chroma-core/chroma/pull/1970/files) or reach out to the Chroma team on [Discord](https://discord.gg/MMeYNT +mh3x).\n\n### Migration to 0.4.16 - November 7, 2023\n\nThis release adds support for multi-modal embeddings, with an accompanying change to the definitions of `EmbeddingFunction`.\nThis change mainly affects users who have implemented their own `EmbeddingFunction` classes. If you are using Chroma's built-in embedding functions, you do not need to take any action.\n\n**EmbeddingFunction**\n\nPreviously, `EmbeddingFunction`s were defined as:\n\n```python\nclass EmbeddingFunction(Protocol):\n def __call__(self, texts: Documents) -> Embeddings:\n ...\n```\n\nAfter this update, `EmbeddingFunction`s are defined as:\n\n```python\nEmbeddable = Union[Documents, Images]\nD = TypeVar("D", bound=Embeddable, contravariant=True)\n\nclass EmbeddingFunction(Protocol[D]):\n def __call__(self, input: D) -> Embeddings:\n ...\n```\n\nThe key differences are:\n\n- `EmbeddingFunction` is now generic, and takes a type parameter `D` which is a subtype of `Embeddable`. This allows us to define `EmbeddingFunction`s which can embed multiple modalities.\n- ` +__call__` now takes a single argument, `input`, to support data of any type `D`. The `texts` argument has been removed.\n\n### Migration from >0.4.0 to 0.4.0 - July 17, 2023\n\nWhat's new in this version?\n\n- New easy way to create clients\n- Changed storage method\n- `.persist()` removed, `.reset()` no longer on by default\n\n**New Clients**\n\n```python\n### in-memory ephemeral client\n\n# before\nimport chromadb\nclient = chromadb.Client()\n\n# after\nimport chromadb\nclient = chromadb.EphemeralClient()\n\n\n### persistent client\n\n# before\nimport chromadb\nfrom chromadb.config import Settings\nclient = chromadb.Client(Settings(\n chroma_db_impl="duckdb+parquet",\n persist_directory="/path/to/persist/directory" # Optional, defaults to .chromadb/ in the current directory\n))\n\n# after\nimport chromadb\nclient = chromadb.PersistentClient(path="/path/to/persist/directory")\n\n\n### http client (to talk to server backend)\n\n# before\nimport chromadb\nfrom chromadb.config import Settings\nclient = chromadb.Client(Settings(ch +roma_api_impl="rest",\n chroma_server_host="localhost",\n chroma_server_http_port="8000"\n ))\n\n# after\nimport chromadb\nclient = chromadb.HttpClient(host="localhost", port="8000")\n\n```\n\nYou can still also access the underlying `.Client()` method. If you want to turn off telemetry, all clients support custom settings:\n\n```python\nimport chromadb\nfrom chromadb.config import Settings\nclient = chromadb.PersistentClient(\n path="/path/to/persist/directory",\n settings=Settings(anonymized_telemetry=False))\n```\n\n**New data layout**\n\nThis version of Chroma drops `duckdb` and `clickhouse` in favor of `sqlite` for metadata storage. This means migrating data over. We have created a migration CLI utility to do this.\n\nIf you upgrade to `0.4.0` and try to access data stored in the old way, you will see this error message\n\n> You are using a deprecated configuration of Chroma. Please pip install chroma-migrate and run `chroma-migrate` to upgrade your configuration. See https://docs.trychroma.com/deployment/migration for more information or join our discord at https:// +discord.gg/MMeYNTmh3x for help!\n\nHere is how to install and use the CLI:\n\n```terminal\npip install chroma-migrate\nchroma-migrate\n```\n\n![](/chroma-migrate.png)\n\nIf you need any help with this migration, please reach out! We are on [Discord](https://discord.com/channels/1073293645303795742/1129286514845691975) ready to help.\n\n**Persist & Reset**\n\n`.persist()` was in the old version of Chroma because writes were only flushed when forced to. Chroma `0.4.0` saves all writes to disk instantly and so `persist` is no longer needed.\n\n`.reset()`, which resets the entire database, used to by enabled-by-default which felt wrong. `0.4.0` has it disabled-by-default. You can enable it again by passing `allow_reset=True` to a Settings object. For example:\n\n```python\nimport chromadb\nfrom chromadb.config import Settings\nclient = chromadb.PersistentClient(path="./path/to/chroma", settings=Settings(allow_reset=True))\n```\n\n# Troubleshooting\n\nThis page is a list of common gotchas or +issues and how to fix them.\n\nIf you don't see your problem listed here, please also search the [Github Issues](https://github.com/chroma-core/chroma/issues).\n\n## Chroma JS-Client failures on NextJS projects\n\nWhen using Chroma with Next.js, be sure to do any embedding in the server - client-side embedding is not supported.\n\nNext.js v15.2.1 includes a fix for embedding functions used by Chroma. If you're using an earlier version of Next.js, you may need to add this configuration to your `next.config.{js|ts}` file:\n\n```typescript\nconst nextConfig = {\n serverExternalPackages: ['chromadb', 'chromadb-default-embed'],\n};\nmodule.exports = nextConfig\n```\n\nIn addition, make sure you're using the latest of the `chromadb` package. Version v2.0.0 includes some important fixes for Next.js environments.\n\n\n## Cannot return the results in a contiguous 2D array. Probably ef or M is too small\n\nThis error happens when the HNSW index fails to retrieve the requested number of results for a query, given its structure and your data. he way to resolve this is to either decrease the number of +results you request from a query (n_result), or increase the HNSW parameters `M`, `ef_construction`, and `ef_search`. You can read more about HNSW configurations [here](/docs/collections/configure).\n\n## Using .get or .query, embeddings say `None`\n\nThis is actually not an error. Embeddings are quite large and heavy to send back. Most application don't use the underlying embeddings and so, by default, chroma does not send them back.\n\nTo send them back: add `include=["embeddings", "documents", "metadatas", "distances"]` to your query to return all information.\n\nFor example:\n\n```python\nresults = collection.query(\n query_texts="hello",\n n_results=1,\n include=["embeddings", "documents", "metadatas", "distances"],\n)\n```\n\n{% note type="tip" %}\nWe may change `None` to something else to more clearly communicate why they were not returned.\n{% /note %}\n\n\n## Build error when running `pip install chromadb`\n\nIf you encounter an error like this during setup\n\n```\nFailed to build hnswlib\nERROR: Could not build wheels for hnsw +lib, which is required to install pyproject.toml-based projects\n```\n\nTry these few tips from the [community](https://github.com/chroma-core/chroma/issues/221):\n\n1. If you get the error: `clang: error: the clang compiler does not support '-march=native'`, set this ENV variable, `export HNSWLIB_NO_NATIVE=1`\n2. If on Mac, install/update xcode dev tools, `xcode-select --install`\n3. If on Windows, try [these steps](https://github.com/chroma-core/chroma/issues/250#issuecomment-1540934224)\n\n## SQLite\n\nChroma requires SQLite > 3.35, if you encounter issues with having too low of a SQLite version please try the following.\n\n1. Install the latest version of Python 3.10, sometimes lower versions of python are bundled with older versions of SQLite.\n2. If you are on a Linux system, you can install pysqlite3-binary, `pip install pysqlite3-binary` and then override the default\n sqlite3 library before running Chroma with the steps [here](https://gist.github.com/defulmere/8b9695 +e415a44271061cc8e272f3c300).\n Alternatively you can compile SQLite from scratch and replace the library in your python installation with the latest version as documented [here](https://github.com/coleifer/pysqlite3#building-a-statically-linked-library).\n3. If you are on Windows, you can manually download the latest version of SQLite from https://www.sqlite.org/download.html and\n replace the DLL in your python installation's DLLs folder with the latest version. You can find your python installation path by running `os.path.dirname(sys.executable)` in python.\n4. If you are using a Debian based Docker container, older Debian versions do not have an up to date SQLite, please use `bookworm` or higher.\n\n## Illegal instruction (core dumped)\n\nIf you encounter an error like this during setup and are using Docker - you may have built the library on a machine with a different CPU architecture than the one you are running it on. Try rebuilding the Docker image on the machine you are running it on.\n\n## My data directory is too large\n\nIf you were using Chroma prior to v0.5.6, you may be able to significantly shrink your database by [vac +uuming it](/reference/cli#vacuuming). After vacuuming once, automatic pruning (a new feature in v0.5.6) is enabled and will keep your database size in check. +# Adding Data to Chroma Collections\n\nAdd data to Chroma with `.add`.\n\nRaw documents:\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\ncollection.add(\n documents=["lorem ipsum...", "doc2", "doc3", ...],\n metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],\n ids=["id1", "id2", "id3", ...]\n)\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nawait collection.add({\n ids: ["id1", "id2", "id3", ...],\n metadatas: [{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],\n documents: ["lorem ipsum...", "doc2", "doc3", ...],\n});\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nIf Chroma is passed a list of `documents`, it will automatically tokenize and embed them +with the collection's embedding function (the default will be used if none was supplied at collection creation). Chroma will also store the `documents` themselves. If the documents are too large to embed using the chosen embedding function, an exception will be raised.\n\nEach document must have a unique associated `id`. Trying to `.add` the same ID twice will result in only the initial value being stored. An optional list of `metadata` dictionaries can be supplied for each document, to store additional information and enable filtering.\n\nAlternatively, you can supply a list of document-associated `embeddings` directly, and Chroma will store the associated documents without embedding them itself.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\ncollection.add(\n documents=["doc1", "doc2", "doc3", ...],\n embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],\n metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": " +29", "verse": "11"}, ...],\n ids=["id1", "id2", "id3", ...]\n)\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nawait collection.add({\n ids: ["id1", "id2", "id3", ...],\n embeddings: [[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],\n metadatas: [{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],\n documents: ["lorem ipsum...", "doc2", "doc3", ...],\n})\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nIf the supplied `embeddings` are not the same dimension as the collection, an exception will be raised.\n\nYou can also store documents elsewhere, and just supply a list of `embeddings` and `metadata` to Chroma. You can use the `ids` to associate the embeddings +with your documents stored elsewhere.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\ncollection.add(\n embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],\n metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],\n ids=["id1", "id2", "id3", ...]\n)\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nawait collection.add({\n ids: ["id1", "id2", "id3", ...],\n embeddings: [[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],\n metadatas: [{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": " +5"}, {"chapter": "29", "verse": "11"}, ...],\n})\n```\n\n# Configuring Chroma Collections\n\nYou can configure the embedding space of a collection by setting special keys on a collection's metadata. These configurations will help you customize your Chroma collections for different data, accuracy and performance requirements.\n\n* `hnsw:space` defines the distance function of the embedding space. The default is `l2` (squared L2 norm), and other possible values are `cosine` (cosine similarity), and `ip` (inner product).\n\n| Distance | parameter | Equation |\n| ----------------- | :-------: |-----------------------------------------------------------------------------------------------------------------------------------------------------------:|\n| Squared L2 | `l2` | {% Latex %} d = \\\\sum\\\\left(A_i-B_i\\\\right)^2 {% /Latex %} |\n| Inner product | `ip` | {% Latex %} d = 1.0 - \\\\sum\\\\left(A_i \\\\times B_i\\\\right) {% /Latex %} |\n| Cosine similarity | `cosine` | {% Latex %} d = 1.0 - \\\\ +frac{\\\\sum\\\\left(A_i \\\\times B_i\\\\right)}{\\\\sqrt{\\\\sum\\\\left(A_i^2\\\\right)} \\\\cdot \\\\sqrt{\\\\sum\\\\left(B_i^2\\\\right)}} {% /Latex %} |\n\n* `hnsw:construction_ef` determines the size of the candidate list used to select neighbors during index creation. A higher value improves index quality at the cost of more memory and time, while a lower value speeds up construction with reduced accuracy. The default value is `100`.\n* `hnsw:search_ef` determines the size of the dynamic candidate list used while searching for the nearest neighbors. A higher value improves recall and accuracy by exploring more potential neighbors but increases query time and computational cost, while a lower value results in faster but less accurate searches. The default value is `100`.\n* `hnsw:M` is the maximum number of neighbors (connections) that each node in the graph can have during the construction of the index. A higher value results in a denser graph, leading to better recall and accuracy during searches but increases memory usage and construction time. A lower value creates a sparser graph, reducing memory usage and construction time but at the cost of lower search +accuracy and recall. The default value is `16`.\n* `hnsw:num_threads` specifies the number of threads to use during index construction or search operations. The default value is `multiprocessing.cpu_count()` (available CPU cores).\n\nHere is an example of how you can create a collection and configure it with custom HNSW settings:\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\ncollection = client.create_collection(\n name="my_collection", \n embedding_function=emb_fn,\n metadata={\n "hnsw:space": "cosine",\n "hnsw:search_ef": 100\n }\n)\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nlet collection = await client.createCollection({\n name: "my_collection",\n embeddingFunction: emb_fn,\n metadata: {\n "hnsw:space": "cosine",\n "hnsw:search_ef": 100\n }\n});\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nYou can learn more in our [Embeddings section](../embeddings/embedding-functions).\n\n## Fine-Tuning HNSW Parameters\n\nWe use an HNSW ( +Hierarchical Navigable Small World) index to perform approximate nearest neighbor (ANN) search for a given embedding. In this context, **Recall** refers to how many of the true nearest neighbors were retrieved.\n\nIncreasing `search_ef` normally improves recall, but slows down query time. Similarly, increasing `construction_ef` improves recall, but increases the memory usage and runtime when creating the index.\n\nChoosing the right values for your HNSW parameters depends on your data, embedding function, and requirements for recall, and performance. You may need to experiment with different construction and search values to find the values that meet your requirements.\n\nFor example, for a dataset with 50,000 embeddings of 2048 dimensions, generated by\n\n```python\nembeddings = np.random.randn(50000, 2048).astype(np.float32).tolist()\n```\n\nwe set up two Chroma collections:\n* The first is configured with `hnsw:ef_search: 10`. When querying using a specific embedding from the set (with `id = 1`), the query takes `0.00529` seconds, and we get back embeddings with distances:\n\n```\n[3629.019775390625, 3666.576 +904296875, 3684.57080078125]\n``` \n\n* The second collection is configured with `hnsw:ef_search: 100` and `hnsw:ef_construction:1000`. When issuing the same query, this time it takes `0.00753` seconds (about 42% slower), but with better results as measured by their distance:\n\n```\n[0.0, 3620.593994140625, 3623.275390625]\n```\n\nIn this example, when querying with the test embedding (`id=1`), the first collection failed to find the embedding itself, despite it being in the collection (where it should have appeared as a result with a distance of `0.0`). The second collection, while slightly slower, successfully found the query embedding itself (shown by the `0.0` distance) and returned closer neighbors overall, demonstrating better accuracy at the cost of performance.\n\n# Create, Get, and Delete Chroma Collections\n\nChroma lets you manage collections of embeddings, using the `collection` primitive.\n\nChroma uses collection names in the url, so there are a few restrictions on naming them:\n\n- The length of the name must be between +3 and 63 characters.\n- The name must start and end with a lowercase letter or a digit, and it can contain dots, dashes, and underscores in between.\n- The name must not contain two consecutive dots.\n- The name must not be a valid IP address.\n\nChroma collections are created with a name and an optional embedding function.\n\n{% Banner type="note" %}\nIf you supply an embedding function, you must supply it every time you get the collection.\n{% /Banner %}\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\ncollection = client.create_collection(name="my_collection", embedding_function=emb_fn)\ncollection = client.get_collection(name="my_collection", embedding_function=emb_fn)\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nlet collection = await client.createCollection({\n name: "my_collection",\n embeddingFunction: emb_fn,\n});\n\ncollection = await client.getCollection({\n name: "my_collection",\n embeddingFunction: emb_fn,\n});\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nThe embedding function takes text as input and embeds it. If no embedding function is supplied, Chroma will use [sentence +transformer](https://www.sbert.net/index.html) as a default. You can learn more about [embedding functions](../embeddings/embedding-functions), and how to create your own.\n\nWhen creating collections, you can pass the optional `metadata` argument to add a mapping of metadata key-value pairs to your collections. This can be useful for adding general about the collection like creation time, description of the data stored in the collection, and more.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\nfrom datetime import datetime\n\ncollection = client.create_collection(\n name="my_collection", \n embedding_function=emb_fn,\n metadata={\n "description": "my first Chroma collection",\n "created": str(datetime.now())\n } \n)\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nlet collection = await client.createCollection({\n name: "my_collection",\n embeddingFunction: emb_fn,\n metadata: {\n description: "my first Chroma collection",\n created: (new Date()).toString()\n }\n});\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nThe collection metadata is also used to configure the embedding space of +a collection. Learn more about it in [Configuring Chroma Collections](./configure).\n\nThe Chroma client allows you to get and delete existing collections by their name. It also offers a `get or create` method to get a collection if it exists, or create it otherwise.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\ncollection = client.get_collection(name="test") # Get a collection object from an existing collection, by name. Will raise an exception if it's not found.\ncollection = client.get_or_create_collection(name="test") # Get a collection object from an existing collection, by name. If it doesn't exist, create it.\nclient.delete_collection(name="my_collection") # Delete a collection and all associated embeddings, documents, and metadata. \u26a0\ufe0f This is destructive and not reversible\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nconst collection = await client.getCollection({ name: "test" }); // Get a collection object from an existing collection, by name. Will raise an exception of it's not found.\ncollection = await client.getOrCreateCollection({ name: "test" }); // Get a collection object from an existing collection, +by name. If it doesn't exist, create it.\nawait client.deleteCollection(collection); // Delete a collection and all associated embeddings, documents, and metadata. \u26a0\ufe0f This is destructive and not reversible\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\nCollections have a few useful convenience methods.\n\n* `peek()` - returns a list of the first 10 items in the collection.\n* `count()` - returns the number of items in the collection.\n* `modify()` - rename the collection\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\ncollection.peek() \ncollection.count() \ncollection.modify(name="new_name")\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nawait collection.peek();\nawait collection.count();\nawait collection.modify({ name: "new_name" })\n```\n\n# Deleting Data from Chroma Collections\n\nChroma supports deleting items from a collection by `id` using `.delete`. The embeddings, documents, and metadata associated with each item will be deleted.\n\n{% Banner type="warn" %}\nNaturally, this is a destructive operation, and cannot be undone.\n{% /Banner %}\n\n`.delete` also supports the `where +` filter. If no `ids` are supplied, it will delete all items in the collection that match the `where` filter.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\ncollection.delete(\n ids=["id1", "id2", "id3",...],\n\twhere={"chapter": "20"}\n)\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nawait collection.delete({\n ids: ["id1", "id2", "id3",...], //ids\n where: {"chapter": "20"} //where\n})\n``` +# Deployment\n\n{% Banner type="tip" %}\n\n**Hosted Chroma**\n\nChroma Cloud, our fully managed hosted service is here. [Sign up here](https://trychroma.com/signup) for early access.\n\n{% /Banner %}\n\n{% Banner type="tip" %}\n\nIf you are using Chroma in production, please fill out [this form](https://airtable.com/appqd02UuQXCK5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users.\nThis is the best place to\n\n1. Get support with building with Chroma in prod.\n2. Stay up-to-date with exciting new features.\n3. Get swag!\n\nWe would love to help you think through the design of your system, or if you would be a good fit for our upcoming distributed cloud service.\n\n{% /Banner %}\n\nYou can run Chroma single-node in [client/server mode](./chroma-server/client-server-mode), and easily deploy it. In this section, we also show you how to make sure your Chroma server is secure and reliable, and how to understand its performance at scale.\n\n\n### Containers\n* +[Docker](./containers/docker)\n* Kubernetes - Coming Soon!\n\n### Cloud Providers\n\n* [AWS](./cloud-providers/aws)\n* [GCP](./cloud-providers/gcp)\n* [Azure](./cloud-providers/azure)\n\n***\n\n### Administration\n\nRunning a server in production requires a few additional steps to ensure the server is secure and reliable.\n\n* [Performance](./administration/performance)\n* [Observability](./administration/observability)\n* [Migration](./administration/migration)\n\n# Observability\n\n\n## Backend Observability\n\nChroma is instrumented with [OpenTelemetry](https://opentelemetry.io/) hooks for observability.\n\n{% note type="default" title="Telemetry vs Observability" %}\n"[Telemetry](../../docs/overview/telemetry)" refers to anonymous product usage statistics we collect. "Observability" refers to metrics, logging, and tracing which can be used by anyone operating a Chroma deployment. Observability features listed on this page are **never** sent back to Chroma; they are for end-users to better understand how their Chroma deployment is behaving.\n{% /note %}\n\n### Available Observability\n\nChroma currently only exports OpenTelemetry [traces]( +https://opentelemetry.io/docs/concepts/signals/traces/). Traces allow a Chroma operator to understand how requests flow through the system and quickly identify bottlenecks.\n\n### Configuration\n\nTracing is configured with three environment variables:\n\n- `CHROMA_OPEN_TELEMETRY__ENDPOINT`: where to send observability data. Example: `api.honeycomb.com`.\n- `CHROMA_OPEN_TELEMETRY__SERVICE_NAME`: Service name for OTel traces. Default: `chromadb`.\n- `OTEL_EXPORTER_OTLP_HEADERS`: Headers to use when sending observability data. Often used to send API and app keys. For example `{"x-honeycomb-team": "abc"}`.\n\nWe also have dedicated observability guides for various deployments:\n* [Docker](../containers/docker#observability-with-docker)\n* [AWS](../cloud-providers/aws#observability-with-AWS)\n* [GCP](../cloud-providers/gcp#observability-with-GCP)\n* [Azure](../cloud-providers/azure#observability-with-Azure)\n\n## Client (SDK) Observability\n\nSeveral observability platforms offer built-in integrations for Chroma, allowing you to +monitor your application's interactions with the Chroma server:\n- [OpenLLMetry Integration](../../integrations/frameworks/openllmetry).\n- [OpenLIT Integration](../../integrations/frameworks/openlit).\n\n# Single-Node Chroma: Performance and Limitations\n\n\nThe single-node version of Chroma is designed to be easy to deploy and maintain, while still providing robust performance that satisfies a broad range of production applications.\n\nTo help you understand when single-node Chroma is a good fit for your use case, we have performed a series of stress tests and performance experiments to probe the system\u2019s capabilities and discover its limitations and edge cases. We analyzed these boundaries across a range of hardware configurations, to determine what sort of deployment is appropriate for different workloads.\n\nThis document describes these findings, as well as some general principles for getting the most out of your Chroma deployment.\n\n## Results Summary\n\nRoughly speaking, here is the sort of performance you can expect from Chroma on different EC2 instance types with a very typical workload:\n\n- 1024 dimensional embeddings\n- Small documents (100-200 words)\n- Three metadata fields per record.\n\n| Instance Type | System RAM | Approx. Max Collection Size | Mean Latency +(insert) | 99.9% Latency (insert) | Mean Latency (query) | 99.9% Latency (query) | Monthly Cost |\n|-----------------|------------|-----------------------------|-----------------------|------------------------|----------------------|-----------------------|--------------|\n| **t3.small** | 2 | 250,000 | 55ms | 250ms | 22ms | 72ms | $15.936 |\n| **t3.medium** | 4 | 700,000 | 37ms | 120ms | 14ms | 41ms | $31.072 |\n| **t3.large** | 8 | 1,700,000 | 30ms | 100ms | 13ms | 35ms | $61.344 |\n| **t3.xlarge** | 16 | 3,600,000 | 30ms | 100ms | 13ms | 30ms | $121.888 |\n| **t3.2xlarge** +| 32 | 7,500,000 | 30ms | 100ms | 13ms | 30ms | $242.976 |\n| **r7i.2xlarge** | 64 | 15,000,000 | 13ms | 50ms | 7ms | 13ms | $386.944 |\n\n{% br %}{% /br %}\n\nDeploying Chroma on a system with less than 2GB of RAM is **not** recommended.\n\nNote that the latency figures in this table are for small collections. Latency increases as collections grow: see [Latency and collection size](./performance#latency-and-collection-size) below for a full analysis.\n\n## Memory and collection size\n\nChroma uses a fork of [`hnswlib`](https://github.com/nmslib/hnswlib) to efficiently index and search over embedding vectors. The HNSW algorithm requires that the embedding index reside in system RAM to query or update.\n\nAs such, the amount of available system memory defines an upper bound on the size of a Chroma collection (or multiple collections, if they are being used concurrently +.) If a collection grows larger than available memory, insert and query latency spike rapidly as the operating system begins swapping memory to disk. The memory layout of the index is not amenable to swapping, and the system quickly becomes unusable.\n\nTherefore, users should always plan on having enough RAM provisioned to accommodate the anticipated total number of embeddings.\n\nTo analyze how much RAM is required, we launched an an instance of Chroma on variously sized EC2 instances, then inserted embeddings until each system became non-responsive. As expected, this failure point corresponded linearly to RAM and embedding count.\n\nFor 1024 dimensional embeddings, with three metadata records and a small document per embedding, this works out to `N = R * 0.245` where `N` is the max collection size in millions, and `R` is the amount of system RAM required in gigabytes. Remember, you wil also need reserve at least a gigabyte for the system\u2019s other needs, in addition to the memory required by Chroma.\n\nThis pattern holds true up through about 7 million embeddings, which is as far as we tested. At this point Chroma is still fast and stable, and we did not find a strict upper bound on the size of +a Chroma database.\n\n## Disk space and collection size\n\nChroma durably persists each collection to disk. The amount of space required is a combination of the space required to save the HNSW embedding index, and the space required by the sqlite database used to store documents and embedding metadata.\n\nThe calculations for persisting the HNSW index are similar to that for calculating RAM size. As a rule of thumb, just make sure a system\u2019s storage is at least as big as its RAM, plus several gigabytes to account for the overhead of the operating system and other applications.\n\nThe amount of space required by the sqlite database is highly variable, and depends entirely on whether documents and metadata are being saved in Chroma, and if so, how large they are. Fully exploring all permutations of this are beyond the scope of the experiments we were able to run.\n\nHowever, as a single data point, the sqlite database for a collection with ~40k documents of 1000 words each, and ~600k metadata entries was about 1.7gb.\n\nThere is no strict upper bound on the size of the metadata database: sqlite itself supports databases into the terabyte range, and can page to disk effectively.\n\nIn most realistic use cases, +it\u2019s likely that the size and performance of the HNSW index in RAM becomes the limiting factor on a Chroma collection\u2019s size long before the metadata database does.\n\n## Latency and collection size\n\nAs collections get larger and the size of the index grows, inserts and queries both take longer to complete. The rate of increase starts out fairly flat then grow roughly linearly, with the inflection point and slope depending on the quantity and speed of CPUs available.\n\n### Query Latency\n\n![query-latency](/query-latency.png)\n\n### Insert Latency\n\n![insert-latency](/insert-latency.png)\n\n{% note type="tip" title="" %}\nIf you\u2019re using multiple collections, performance looks quite similar, based on the total number of embeddings across collections. Splitting collections into multiple smaller collections doesn\u2019t help, but it doesn\u2019t hurt, either, as long as they all fit in memory at once.\n{% /note %}\n\n## Concurrency\n\nAlthough aspects of HNSW\u2019s algorithm are multithreaded internally, only one thread can read or write to a given index at a time. For the most part, single-node Chroma is fundamentally single threaded. If an operation is executed while another is still in progress +, it blocks until the first one is complete.\n\nThis means that under concurrent load, the average latency of each request will increase.\n\nWhen writing, the increased latency is more pronounced with larger batch sizes, as the system is more completely saturated. We have experimentally verified this: as the number of concurrent writers is increased, average latency increases linearly.\n\n![concurrent-writes](/concurrent-writes.png)\n\n![concurrent-queries](/concurrent-queries.png)\n\nDespite the effect on latency, Chroma does remain stable with high concurrent load. Too many concurrent users can eventually increase latency to the point where the system does not perform acceptably, but this typically only happens with larger batch sizes. As the above graphs shows, the system remains usable with dozens to hundreds of operations per second.\n\nSee the [Insert Throughput](./performance#insert-throughput) section below for a discussion of optimizing user count for maximum throughput when the concurrency is under your control, such as when inserting bulk data.\n\n# CPU speed, core count & type\n\nAs a CPU bound application, it\u2019s not surprising that CPU speed and type makes a difference for average latency.\n\nAs the data demonstrates, although it is not fully parallelized, Chroma can +still take some advantage of multiple CPU cores for better throughput.\n\n![cpu-mean-query-latency](/cpu-mean-query-latency.png)\n\n{% note type="tip" title="" %}\nNote the slightly increased latency for the t3.2xlarge instance. Logically, it should be faster than the other t3 series instances, since it has the same class of CPU, and more of them.\n\nThis data point is left in as an important reminder that the performance of EC2 instances is slightly variable, and it\u2019s entirely possible to end up with an instance that has performance differences for no discernible reason.\n{% /note %}\n\n# Insert Throughput\n\nA question that is often relevant is: given bulk data to insert, how fast is it possible to do so, and what\u2019s the best way to insert a lot of data quickly?\n\nThe first important factor to consider is the number of concurrent insert requests.\n\nAs mentioned in the [Concurrency](./performance#concurrency) section above, actual insertion throughput does not benefit from concurrency. However, there is some amount of network and HTTP overhead which can be parallelized. Therefore, to saturate Chroma while keeping latencies as low as possible, we recommend 2 concurrent client processes or threads +inserting as fast as possible.\n\nThe second factor to consider is the batch size of each request. Performance is mostly linear with respect to batch size, with a constant overhead to process the HTTP request itself.\n\nExperimentation confirms this: overall throughput (total number of embeddings inserted, across batch size and request count) remains fairly flat between batch sizes of 100-500:\n\n![concurrent-inserts](/concurrent-inserts.png)\n\nGiven that smaller batches have lower, more consistent latency and are less likely to lead to timeout errors, we recommend batches on the smaller side of this curve: anything between 50 and 250 is a reasonable choice.\n\n## Conclusion\n\nUsers should feel comfortable relying on Chroma for use cases approaching tens of millions of embeddings, when deployed on the right hardware. It\u2019s average and upper-bound latency for both reads and writes make it a good platform for all but the largest AI-based applications, supporting potentially thousands of simultaneous human users (depending on your application\u2019s backend access patterns.)\n\nAs a single-node solution, though, it won\u2019t scale forever. If you find your needs exceeding the parameters laid out in this analysis, we are extremely interested in hearing from you. Please fill out [this form](https://airtable.com/app +qd02UuQXCK5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users. We would love to help you think through the design of your system, whether Chroma has a place in it, or if you would be a good fit for our upcoming distributed cloud service.\n\n# Running Chroma in Client-Server Mode\n\nChroma can also be configured to run in client/server mode. In this mode, the Chroma client connects to a Chroma server running in a separate process.\n\nThis means that you can deploy single-node Chroma to a [Docker container](../containers/docker), or a machine hosted by a cloud provider like [AWS](../cloud-providers/aws), [GCP](../cloud-providers/gcp), [Azure](../cloud-providers/azure), and others. Then, you can access your Chroma server from your application using our `HttpClient` (or `ChromaClient` for JS/TS users).\n\nYou can quickly experiment locally with Chroma in client/server mode by using our CLI:\n\n```terminal\nchroma run --path /db_path\n```\n\n{% Tabs %}\n\n{% Tab +label="python" %}\n\nThen use the Chroma `HttpClient` to connect to the server:\n\n```python\nimport chromadb\nchroma_client = chromadb.HttpClient(host='localhost', port=8000)\n```\n\nChroma also provides an `AsyncHttpClient`. The behaviors and method signatures are identical to the synchronous client, but all methods that would block are now async:\n\n```python\nimport asyncio\nimport chromadb\n\nasync def main():\n client = await chromadb.AsyncHttpClient()\n collection = await client.create_collection(name="my_collection")\n await collection.add(\n documents=["hello world"],\n ids=["id1"]\n )\n\nasyncio.run(main())\n```\n\nIf you intend to deploy your Chroma server, you may want to consider our [thin-client package](./thin-client) for client-side interactions.\n\n{% /Tab %}\n\n{% Tab label="typescript" %}\n\nThen instantiate a new `ChromaClient`. The default is to connect to a Chroma server running on localhost.\n\n```typescript\n// CJS\nconst { ChromaClient } = require("chromadb");\n// ESM\nimport { ChromaClient } from "chromadb";\n\nconst client = new ChromaClient();\n```\n\n{% / +Tab %}\n\n{% /Tabs %}\n\n# Chroma's Thin-Client\n\n\nIf you are running Chroma in client-server mode in a Python or JavaScript application, you may not need the full Chroma library. Instead, you can use the lightweight client-only library.\n\nIn this case, you can install the `chromadb-client` package **instead** of our `chromadb` package.\n\nThe `chromadb-client` package is a lightweight HTTP client for the server with a minimal dependency footprint.\n\n\n```terminal\n# Python\npip install chromadb-client\n# JS\nnpm install chromadb-client\n```\n\n```python\n# Python\nimport chromadb\n# Example setup of the client to connect to your chroma server\nclient = chromadb.HttpClient(host='localhost', port=8000)\n\n# Or for async usage:\nasync def main():\n client = await chromadb.AsyncHttpClient(host='localhost', port=8000)\n```\n\n```javascript\n// JavaScript\nimport { ChromaClient } from "chromadb-client";\nconst client = new ChromaClient({ path: "http://localhost:8000" })\n```\n\nNote that the `chromadb-client` package is a subset of the full Chroma library and does +not include all the dependencies. If you want to use the full Chroma library, you can install the `chromadb` package instead.\n\nMost importantly, the thin-client package has no default embedding functions. If you `add()` documents without embeddings, you must have manually specified an embedding function and installed the dependencies for it.\n\n# AWS Deployment\n\n{% Banner type="tip" %}\n\n**Hosted Chroma**\n\nChroma Cloud, our fully managed hosted service is here. [Sign up here](https://trychroma.com/signup) for early access.\n\n{% /Banner %}\n\n{% Banner type="tip" %}\n\nIf you are using Chroma in production, please fill out [this form](https://airtable.com/appqd02UuQXCK5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users.\nThis is the best place to\n\n1. Get support with building with Chroma in prod.\n2. Stay up-to-date with exciting new features.\n3. Get swag!\n\nWe would love to help you think through the design of your system, or if you would be a good fit for our upcoming distributed cloud service +.\n\n{% /Banner %}\n\n## A Simple AWS Deployment\n\nYou can deploy Chroma on a long-running server, and connect to it\nremotely.\n\nThere are many possible configurations, but for convenience we have\nprovided a very simple AWS CloudFormation template to experiment with\ndeploying Chroma to EC2 on AWS.\n\n{% Banner type="warn" %}\n\nChroma and its underlying database [need at least 2GB of RAM](./performance#results-summary),\nwhich means it won't fit on the 1gb instances provided as part of the\nAWS Free Tier. This template uses a [`t3.small`](https://aws.amazon.com/ec2/instance-types/t3/#Product%20Details) EC2 instance, which\ncosts about two cents an hour, or $15 for a full month, and gives you 2GiB of memory. If you follow these\ninstructions, AWS will bill you accordingly.\n\n{% /Banner %}\n\n{% Banner type="warn" %}\n\nIn this guide we show you how to secure your endpoint using [Chroma's\nnative authentication support](./aws#authentication-with-aws). Alternatively, you can put it behind\n[AWS API Gateway](https://aws.amazon.com +/api-gateway/) or add your own\nauthenticating proxy. This basic stack doesn't support any kind of authentication;\nanyone who knows your server IP will be able to add and query for\nembeddings.\n\n{% /Banner %}\n\n{% Banner type="warn" %}\n\nBy default, this template saves all data on a single\nvolume. When you delete or replace it, the data will disappear. For\nserious production use (with high availability, backups, etc.) please\nread and understand the CloudFormation template and use it as a basis\nfor what you need, or reach out to the Chroma team for assistance.\n\n{% /Banner %}\n\n### Step 1: Get an AWS Account\n\nYou will need an AWS Account. You can use one you already have, or\n[create a new one](https://aws.amazon.com).\n\n### Step 2: Get credentials\n\nFor this example, we will be using the AWS command line\ninterface. There are\n[several ways](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-prereqs.html)\nto configure the AWS CLI, but for the purposes of these examples we\nwill presume that you have\n[obtained an +AWS access key](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html)\nand will be using environment variables to configure AWS.\n\nExport the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables in your shell:\n\n```terminal\nexport AWS_ACCESS_KEY_ID=**\\*\\***\\*\\*\\*\\***\\*\\***\nexport AWS_SECRET_ACCESS_KEY=****\\*\\*****\\*\\*****\\*\\*****\n```\n\nYou can also configure AWS to use a region of your choice using the\n`AWS_REGION` environment variable:\n\n```terminal\nexport AWS_REGION=us-east-1\n```\n\n### Step 3: Run CloudFormation\n\nChroma publishes a [CloudFormation template](https://s3.amazonaws.com/public.trychroma.com/cloudformation/latest/chroma.cf.json) to S3 for each release.\n\nTo launch the template using AWS CloudFormation, run the following command line invocation.\n\nReplace `--stack-name my-chroma-stack` with a different stack name, if you wish.\n\n```terminal\naws cloudformation create-stack --stack-name my-chroma-stack --template-url https://s3.amazonaws.com/public.trychroma.com/cloudformation/latest/chroma.cf.json\n```\n\nWait a few minutes +for the server to boot up, and Chroma will be\navailable! You can get the public IP address of your new Chroma server using the AWS console, or using the following command:\n\n```terminal\naws cloudformation describe-stacks --stack-name my-chroma-stack --query 'Stacks[0].Outputs'\n```\n\nNote that even after the IP address of your instance is available, it may still take a few minutes for Chroma to be up and running.\n\n#### Customize the Stack (optional)\n\nThe CloudFormation template allows you to pass particular key/value\npairs to override aspects of the stack. Available keys are:\n\n- `InstanceType` - the AWS instance type to run (default: `t3.small`)\n- `KeyName` - the AWS EC2 KeyPair to use, allowing to access the instance via SSH (default: none)\n\nTo set a CloudFormation stack's parameters using the AWS CLI, use the\n`--parameters` command line option. Parameters must be specified using\nthe format `ParameterName={parameter},ParameterValue={value}`.\n\nFor example, the following command launches a new stack similar to the\nabove, but on a `m5.4xlarge` EC2 instance, and adding a +KeyPair named\n`mykey` so anyone with the associated private key can SSH into the\nmachine:\n\n```terminal\naws cloudformation create-stack --stack-name my-chroma-stack --template-url https://s3.amazonaws.com/public.trychroma.com/cloudformation/latest/chroma.cf.json \\\n --parameters ParameterKey=KeyName,ParameterValue=mykey \\\n ParameterKey=InstanceType,ParameterValue=m5.4xlarge\n```\n\n### Step 4: Chroma Client Set-Up\n\nOnce your EC2 instance is up and running with Chroma, all\nyou need to do is configure your `HttpClient` to use the server's IP address and port\n`8000`. Since you are running a Chroma server on AWS, our [thin-client package](../chroma-server/python-thin-client) may be enough for your application.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n\n```python\nimport chromadb\n\nchroma_client = chromadb.HttpClient(\n host="",\n port=8000\n)\nchroma_client.heartbeat()\n```\n\n{% /Tab %}\n\n{% Tab label="typescript" %}\n\n```typescript\nimport { ChromaClient } from "chromadb +";\n\nconst chromaClient = new ChromaClient({\n path: "",\n port: 8000\n})\nchromaClient.heartbeat()\n```\n\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n### Step 5: Clean Up (optional).\n\nTo destroy the stack and remove all AWS resources, use the AWS CLI `delete-stack` command.\n\n{% note type="warning" title="Note" %}\nThis will destroy all the data in your Chroma database,\nunless you've taken a snapshot or otherwise backed it up.\n{% /note %}\n\n```terminal\naws cloudformation delete-stack --stack-name my-chroma-stack\n```\n\n## Observability with AWS\n\nChroma is instrumented with [OpenTelemetry](https://opentelemetry.io/) hooks for observability. We currently only exports OpenTelemetry [traces](https://opentelemetry.io/docs/concepts/signals/traces/). These should allow you to understand how requests flow through the system and quickly identify bottlenecks. Check out the [observability docs](../administration/observability) for a full explanation of the available parameters.\n\nTo enable tracing on your Chroma server, simply pass your desired values as +arguments when creating your Cloudformation stack:\n\n```terminal\naws cloudformation create-stack --stack-name my-chroma-stack --template-url https://s3.amazonaws.com/public.trychroma.com/cloudformation/latest/chroma.cf.json \\\n --parameters ParameterKey=ChromaOtelCollectionEndpoint,ParameterValue="api.honeycomb.com" \\\n ParameterKey=ChromaOtelServiceName,ParameterValue="chromadb" \\\n ParameterKey=ChromaOtelCollectionHeaders,ParameterValue="{'x-honeycomb-team': 'abc'}"\n```\n\n## Troubleshooting\n\n#### Error: No default VPC for this user\n\nIf you get an error saying `No default VPC for this user` when creating `ChromaInstanceSecurityGroup`, head to [AWS VPC section](https://us-east-1.console.aws.amazon.com/vpc/home?region=us-east-1#vpcs) and create a default VPC for your user.\n\n# Azure Deployment\n\n{% Banner type="tip" %}\n\n**Hosted Chroma**\n\nChroma Cloud, our fully managed hosted service is here. [Sign up here](https://trychroma.com/signup) for early access.\n\n{% /Banner %}\n\n{% Banner type="tip" %}\n\nIf +you are using Chroma in production, please fill out [this form](https://airtable.com/appqd02UuQXCK5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users.\nThis is the best place to\n\n1. Get support with building with Chroma in prod.\n2. Stay up-to-date with exciting new features.\n3. Get swag!\n\nWe would love to help you think through the design of your system, or if you would be a good fit for our upcoming distributed cloud service.\n\n{% /Banner %}\n\n## A Simple Azure Deployment\n\nYou can deploy Chroma on a long-running server, and connect to it\nremotely.\n\nFor convenience, we have\nprovided a very simple Terraform configuration to experiment with\ndeploying Chroma to Azure.\n\n{% Banner type="warn" %}\nChroma and its underlying database [need at least 2GB of RAM](./performance#results-summary). When defining your VM size for the template in this example, make sure it meets this requirement.\n{% /Banner %}\n\n{% Banner type="warn" %}\nIn this guide we show you how to secure your +endpoint using [Chroma's\nnative authentication support](./azure#authentication-with-azure). Alternatively, you can put it behind\nan API Gateway or add your own\nauthenticating proxy. This basic stack doesn't support any kind of authentication;\nanyone who knows your server IP will be able to add and query for\nembeddings.\n{% /Banner %}\n\n{% Banner type="warn" %}\nBy default, this template saves all data on a single\nvolume. When you delete or replace it, the data will disappear. For\nserious production use (with high availability, backups, etc.) please\nread and understand the Terraform template and use it as a basis\nfor what you need, or reach out to the Chroma team for assistance.\n{% /Banner %}\n\n### Step 1: Install Terraform\n\nDownload [Terraform](https://developer.hashicorp.com/terraform/install?product_intent=terraform) and follow the installation instructions for you OS.\n\n### Step 2: Authenticate with Azure\n\n```terminal\naz login\n```\n\n### Step 3: Configure your Azure Settings\n\nCreate a `chroma.tfvars` file. Use it to define the following variables for your Azure Resource Group name, +VM size, and location. Note that this template creates a new resource group for your Chroma deployment.\n\n```text\nresource_group_name = "your-azure-resource-group-name"\nlocation = "your-location"\nmachine_type = "Standard_B1s"\n```\n\n### Step 4: Initialize and deploy with Terraform\n\nDownload our [Azure Terraform configuration](https://github.com/chroma-core/chroma/blob/main/deployments/azure/main.tf) to the same directory as your `chroma.tfvars` file. Then run the following commands to deploy your Chroma stack.\n\nInitialize Terraform:\n```terminal\nterraform init\n```\n\nPlan the deployment, and review it to ensure it matches your expectations:\n```terminal\nterraform plan -var-file chroma.tfvars\n```\n\nFinally, apply the deployment:\n```terminal\nterraform apply -var-file chroma.tfvars\n```\n\nAfter a few minutes, you can get the IP address of your instance with\n```terminal\nterraform output -raw public_ip_address\n```\n\n### Step 5: Chroma Client Set-Up\n\nOnce your Azure VM instance is up and running with Chroma, all\nyou need to do is configure your `HttpClient` to use the +server's IP address and port\n`8000`. Since you are running a Chroma server on Azure, our [thin-client package](../chroma-server/python-thin-client) may be enough for your application.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n\n```python\nimport chromadb\n\nchroma_client = chromadb.HttpClient(\n host="",\n port=8000\n)\nchroma_client.heartbeat()\n```\n\n{% /Tab %}\n\n{% Tab label="typescript" %}\n\n```typescript\nimport { ChromaClient } from "chromadb";\n\nconst chromaClient = new ChromaClient({\n path: "",\n port: 8000\n})\nchromaClient.heartbeat()\n```\n\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n### Step 5: Clean Up (optional).\n\nTo destroy the stack and remove all Azure resources, use the `terraform destroy` command.\n\n```shell\nterraform destroy -var-file chroma.tfvars\n```\n\n{% Banner type="warn" %}\nThis will destroy all the data in your Chroma database,\nunless you've taken a snapshot or otherwise backed it up.\n{% +/Banner %}\n\n## Observability with Azure\n\nChroma is instrumented with [OpenTelemetry](https://opentelemetry.io/) hooks for observability. We currently only exports OpenTelemetry [traces](https://opentelemetry.io/docs/concepts/signals/traces/). These should allow you to understand how requests flow through the system and quickly identify bottlenecks. Check out the [observability docs](../administration/observability) for a full explanation of the available parameters.\n\nTo enable tracing on your Chroma server, simply define the following variables in your `chroma.tfvars`:\n\n```text\nchroma_otel_collection_endpoint = "api.honeycomb.com"\nchroma_otel_service_name = "chromadb"\nchroma_otel_collection_headers = "{'x-honeycomb-team': 'abc'}"\n```\n\n# GCP Deployment\n\n{% Banner type="tip" %}\n\n**Hosted Chroma**\n\nChroma Cloud, our fully managed hosted service is here. [Sign up here](https://trychroma.com/signup) for early access.\n\n{% /Banner %}\n\n{% Banner type="tip" %}\n\nIf you are using Chroma in production, please fill out [ +this form](https://airtable.com/appqd02UuQXCK5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users.\nThis is the best place to\n\n1. Get support with building with Chroma in prod.\n2. Stay up-to-date with exciting new features.\n3. Get swag!\n\nWe would love to help you think through the design of your system, or if you would be a good fit for our upcoming distributed cloud service.\n\n{% /Banner %}\n\n## A Simple GCP Deployment\n\nYou can deploy Chroma on a long-running server, and connect to it\nremotely.\n\nFor convenience, we have\nprovided a very simple Terraform configuration to experiment with\ndeploying Chroma to Google Compute Engine.\n\n{% Banner type="warn" %}\n\nChroma and its underlying database [need at least 2GB of RAM](./performance#results-summary),\nwhich means it won't fit on the instances provided as part of the\nGCP "always free" tier. This template uses an [`e2-small`](https://cloud.google.com/compute/docs/general-purpose-machines#e2_machine_types +) instance, which\ncosts about two cents an hour, or $15 for a full month, and gives you 2GiB of memory. If you follow these\ninstructions, GCP will bill you accordingly.\n\n{% /Banner %}\n\n{% Banner type="warn" %}\n\nIn this guide we show you how to secure your endpoint using [Chroma's\nnative authentication support](./gcp#authentication-with-gcp). Alternatively, you can put it behind\n[GCP API Gateway](https://cloud.google.com/api-gateway/docs) or add your own\nauthenticating proxy. This basic stack doesn't support any kind of authentication;\nanyone who knows your server IP will be able to add and query for\nembeddings.\n\n{% /Banner %}\n\n{% Banner type="warn" %}\n\nBy default, this template saves all data on a single\nvolume. When you delete or replace it, the data will disappear. For\nserious production use (with high availability, backups, etc.) please\nread and understand the Terraform template and use it as a basis\nfor what you need, or reach out to the Chroma team for assistance.\n\n{% /Banner %}\n\n### Step 1: Set up your G +CP credentials\n\nIn your GCP project, create a service account for deploying Chroma. It will need the following roles:\n* Service Account User\n* Compute Admin\n* Compute Network Admin\n* Storage Admin\n\nCreate a JSON key file for this service account, and download it. Set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable to the path of your JSON key file:\n\n```terminal\nexport GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/service-account-key.json"\n```\n\n### Step 2: Install Terraform\n\nDownload [Terraform](https://developer.hashicorp.com/terraform/install?product_intent=terraform) and follow the installation instructions for your OS.\n\n### Step 3: Configure your GCP Settings\n\nCreate a `chroma.tfvars` file. Use it to define the following variables for your GCP project ID, region, and zone:\n\n```text\nproject_id=""\nregion=""\nzone=""\n```\n\n### Step 4: Initialize and deploy with Terraform\n\nDownload our [GCP Terraform configuration](https://github.com/chroma-core/chroma/blob/main/deployments/gcp/main.tf) to the same directory as your `chroma +.tfvars` file. Then run the following commands to deploy your Chroma stack.\n\nInitialize Terraform:\n```terminal\nterraform init\n```\n\nPlan the deployment, and review it to ensure it matches your expectations:\n```terminal\nterraform plan -var-file chroma.tfvars\n```\nIf you did not customize our configuration, you should be deploying an `e2-small` instance.\n\nFinally, apply the deployment:\n```terminal\nterraform apply -var-file chroma.tfvars\n```\n\n#### Customize the Stack (optional)\n\nIf you want to use a machine type different from the default `e2-small`, in your `chroma.tfvars` add the `machine_type` variable and set it to your desired machine:\n\n```text\nmachine_type = "e2-medium"\n```\n\nAfter a few minutes, you can get the IP address of your instance with\n```terminal\nterraform output -raw chroma_instance_ip\n```\n\n### Step 5: Chroma Client Set-Up\n\nOnce your Compute Engine instance is up and running with Chroma, all\nyou need to do is configure your `HttpClient` to use the server's IP address and port\n`8000`. Since you are running a Chroma server on G +CP, our [thin-client package](../chroma-server/python-thin-client) may be enough for your application.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n\n```python\nimport chromadb\n\nchroma_client = chromadb.HttpClient(\n host="",\n port=8000\n)\nchroma_client.heartbeat()\n```\n\n{% /Tab %}\n\n{% Tab label="typescript" %}\n\n```typescript\nimport { ChromaClient } from "chromadb";\n\nconst chromaClient = new ChromaClient({\n path: "",\n port: 8000\n})\nchromaClient.heartbeat()\n```\n\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n### Step 5: Clean Up (optional).\n\nTo destroy the stack and remove all GCP resources, use the `terraform destroy` command.\n\n{% note type="warning" title="Note" %}\nThis will destroy all the data in your Chroma database,\nunless you've taken a snapshot or otherwise backed it up.\n{% /note %}\n\n```terminal\nterraform destroy -var-file chroma.tfvars\n```\n\n## Observability with GCP\n\nChroma is instrument +ed with [OpenTelemetry](https://opentelemetry.io/) hooks for observability. We currently only exports OpenTelemetry [traces](https://opentelemetry.io/docs/concepts/signals/traces/). These should allow you to understand how requests flow through the system and quickly identify bottlenecks. Check out the [observability docs](../administration/observability) for a full explanation of the available parameters.\n\nTo enable tracing on your Chroma server, simply define the following variables in your `chroma.tfvars`:\n\n```text\nchroma_otel_collection_endpoint = "api.honeycomb.com"\nchroma_otel_service_name = "chromadb"\nchroma_otel_collection_headers = "{'x-honeycomb-team': 'abc'}"\n```\n\n# Docker\n\n{% Banner type="tip" %}\n\n**Hosted Chroma**\n\nChroma Cloud, our fully managed hosted service is here. [Sign up here](https://trychroma.com/signup) for early access.\n\n{% /Banner %}\n\n{% Banner type="tip" %}\n\nIf you are using Chroma in production, please fill out [this form](https://airtable.com/appqd02UuQXCK +5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users.\nThis is the best place to\n\n1. Get support with building with Chroma in prod.\n2. Stay up-to-date with exciting new features.\n3. Get swag!\n\nWe would love to help you think through the design of your system, or if you would be a good fit for our upcoming distributed cloud service.\n\n{% /Banner %}\n\n## Run Chroma in a Docker Container\n\nYou can run a Chroma server in a Docker container, and access it using the `HttpClient`. We provide images on both [docker.com](https://hub.docker.com/r/chromadb/chroma) and [ghcr.io](https://github.com/chroma-core/chroma/pkgs/container/chroma).\n\nTo start the server, run:\n\n```terminal\ndocker run -v ./chroma-data:/data -p 8000:8000 chroma-core/chroma\n```\n\nThis starts the server with the default configuration and stores data in `./chroma-data` (in your current working directory).\n\nThe Chroma client can then be configured to connect to the server running in +the Docker container.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\nimport chromadb\nchroma_client = chromadb.HttpClient(host='localhost', port=8000)\nchroma_client.heartbeat()\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nimport { ChromaClient } from "chromadb";\n\nconst chromaClient = new ChromaClient({ path: "http://localhost:8000" })\nchromaClient.heartbeat()\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n{% Banner type="tip" %}\n\n**Client-only package**\n\nIf you're using Python, you may want to use the [client-only package](../chroma-server/python-thin-client) for a smaller install size.\n{% /Banner %}\n\n## Configuration\n\nChroma is configured using a YAML file. Check out [this config file](https://github.com/chroma-core/chroma/blob/main/rust/frontend/sample_configs/single_node_full.yaml) detailing all available options.\n\nTo use a custom config file, mount it into the container at `/config.yaml` like so:\n\n```terminal\necho "allow_reset: true" > config.yaml # the server will +now allow clients to reset its state\ndocker run -v ./chroma-data:/data -v ./config.yaml:/config.yaml -p 8000:8000 chroma-core/chroma\n```\n\n## Observability with Docker\n\nChroma is instrumented with [OpenTelemetry](https://opentelemetry.io/) hooks for observability. OpenTelemetry traces allow you to understand how requests flow through the system and quickly identify bottlenecks. Check out the [observability docs](../administration/observability) for a full explanation of the available parameters.\n\nHere's an example of how to create an observability stack with Docker Compose. The stack is composed of\n\n- a Chroma server\n- [OpenTelemetry Collector](https://github.com/open-telemetry/opentelemetry-collector)\n- [Zipkin](https://zipkin.io/)\n\nFirst, paste the following into a new file called `otel-collector-config.yaml`:\n\n```yaml\nreceivers:\n otlp:\n protocols:\n grpc:\n endpoint: 0.0.0.0:4317\n http:\n endpoint: 0.0.0.0:4318\n\nexporters:\n debug:\n +zipkin:\n endpoint: "http://zipkin:9411/api/v2/spans"\n\nservice:\n pipelines:\n traces:\n receivers: [otlp]\n exporters: [zipkin, debug]\n```\n\nThis is the configuration file for the OpenTelemetry Collector:\n* The `receivers` section specifies that the OpenTelemetry protocol (OTLP) will be used to receive data over GRPC and HTTP.\n* `exporters` defines that telemetry data is logged to the console (`debug`), and sent to a `zipkin` server (defined below in `docker-compose.yml`).\n* The `service` section ties everything together, defining a `traces` pipeline receiving data through our `otlp` receiver and exporting data to `zipkin` and via logging.\n\nNext, paste the following into a new file called `docker-compose.yml`:\n\n```yaml\nservices:\n zipkin:\n image: openzipkin/zipkin\n ports:\n - "9411:9411"\n depends_on: [otel-collector]\n networks:\n - internal\n otel-collector:\n image: otel/opentelemetry-collector-contrib:0.111.0 +\n command: ["--config=/etc/otel-collector-config.yaml"]\n volumes:\n - ${PWD}/otel-collector-config.yaml:/etc/otel-collector-config.yaml\n networks:\n - internal\n server:\n image: chroma-core/chroma\n volumes:\n - chroma_data:/data\n ports:\n - "8000:8000"\n networks:\n - internal\n environment:\n - CHROMA_OPEN_TELEMETRY__ENDPOINT=http://otel-collector:4317/\n - CHROMA_OPEN_TELEMETRY__SERVICE_NAME=chroma\n depends_on:\n - otel-collector\n - zipkin\n\nnetworks:\n internal:\n\nvolumes:\n chroma_data:\n```\n\nTo start the stack, run\n\n```terminal\ndocker compose up --build -d\n```\n\nOnce the stack is running, you can access Zipkin at [http://localhost:9411](http://localhost:9411) when running locally to see your traces.\n\nZipkin will show an empty view initially as no traces are created during startup. You can call the heartbeat endpoint to quickly create a sample trace:\n\n```terminal\ncurl http +://localhost:8000/api/v2/heartbeat\n```\n\nThen, click "Run Query" in Zipkin to see the trace. +# Chroma Cloud\n\nOur fully managed hosted service, **Chroma Cloud** is here. You can now [sign up](https://trychroma.com/signup) for early access.\n\nMore documentation for Chroma Cloud users coming soon! +# Ephemeral Client\n\nIn Python, you can run a Chroma server in-memory and connect to it with the ephemeral client:\n\n```python\nimport chromadb\n\nclient = chromadb.Client()\n```\n\nThe `Client()` method starts a Chroma server in-memory and also returns a client with which you can connect to it.\n\nThis is a great tool for experimenting with different embedding functions and retrieval techniques in a Python notebook, for example. If you don't need data persistence, the ephemeral client is a good choice for getting up and running with Chroma.\n\n# Persistent Client\n\n{% Tabs %}\n\n{% Tab label="python" %}\n\nYou can configure Chroma to save and load the database from your local machine, using the `PersistentClient`. \n\nData will be persisted automatically and loaded on start (if it exists).\n\n```python\nimport chromadb\n\nclient = chromadb.PersistentClient(path="/path/to/save/to")\n```\n\nThe `path` is where Chroma will store its database files on disk, and load them on start. If you don't provide a path, the default is `.chroma`\n\n{% /Tab %}\n\n{% Tab label="typescript" %}\n\nTo connect with the JS/TS client, you +must connect to a Chroma server. \n\nTo run a Chroma server locally that will persist your data, install Chroma via `pip`:\n\n```terminal\npip install chromadb\n```\n\nAnd run the server using our CLI:\n\n```terminal\nchroma run --path ./getting-started \n```\n\nThe `path` is where Chroma will store its database files on disk, and load them on start. The default is `.chroma`.\n\nAlternatively, you can also use our official Docker image:\n\n```terminal\ndocker pull chromadb/chroma\ndocker run -p 8000:8000 chromadb/chroma\n```\n\nWith a Chroma server running locally, you can connect to it by instantiating a new `ChromaClient`:\n\n```typescript\nimport { ChromaClient } from "chromadb";\n\nconst client = new ChromaClient();\n```\n\nSee [Running Chroma in client-server mode](../client-server-mode) for more.\n\n{% /Tab %}\n\n{% /Tabs %}\n\nThe client object has a few useful convenience methods.\n\n* `heartbeat()` - returns a nanosecond heartbeat. Useful for making sure the client remains connected.\n* `reset()` - empties and completely resets the database. +\u26a0\ufe0f This is destructive and not reversible.\n\n{% TabbedCodeBlock %}\n\n{% Tab label="python" %}\n```python\nclient.heartbeat()\nclient.reset()\n```\n{% /Tab %}\n\n{% Tab label="typescript" %}\n```typescript\nawait client.heartbeat();\nawait client.reset();\n```\n{% /Tab %}\n\n{% /TabbedCodeBlock %}\n\n# The Python HTTP-Only Client\n\nIf you are running Chroma in client-server mode, where you run a Chroma server and client on separate machines, you may not need the full Chroma package where you run your client. Instead, you can use the lightweight client-only library.\nIn this case, you can install the `chromadb-client` package. This package is a lightweight HTTP client for the server with a minimal dependency footprint.\n\nOn your server, install chroma with\n\n```terminal\npip install chromadb\n```\n\nAnd run a Chroma server:\n\n```terminal\nchroma run --path [path/to/persist/data]\n```\n\nThen, on your client side, install the HTTP-only client: \n\n```terminal\npip install chromadb-client\n```\n\n```python\nimport chromadb\n# Example setup of the client to connect to your +chroma server\nclient = chromadb.HttpClient(host='localhost', port=8000)\n\n# Or for async usage:\nasync def main():\n client = await chromadb.AsyncHttpClient(host='localhost', port=8000)\n```\n\nNote that the `chromadb-client` package is a subset of the full Chroma library and does not include all the dependencies. If you want to use the full Chroma library, you can install the `chromadb` package instead.\nMost importantly, there is no default embedding function. If you add() documents without embeddings, you must have manually specified an embedding function and installed the dependencies for it.\n\n +\n Chroma provides a convenient wrapper around OpenAI's embedding API. This embedding function runs remotely on OpenAI's servers, and requires an API key. You can get an API key by signing up for an account at OpenAI.\n\n The following OpenAI Embedding Models are supported:\n\n text-embedding-ada-002\n text-embedding-3-small\n text-embedding-3-large\n +\n import chromadb.utils.embedding_functions as embedding_functions\n\n # This embedding function relies on the openai python package, which you can install with pip install openai\n # You can pass in an optional model_name argument, which lets you choose which OpenAI embeddings model to use. By default, Chroma uses text-embedding-ada-002\n openai_ef = embedding_functions.OpenAIEmbeddingFunction(\n api_key="YOUR_API_KEY",\n model_name="text-embedding-3-small"\n )\n\n +\n import chromadb.utils.embedding_functions as embedding_functions\n\n # To use the OpenAI embedding models on other platforms such as Azure, you can use the api_base and api_type parameters\n openai_ef = embedding_functions.OpenAIEmbeddingFunction(\n api_key="YOUR_API_KEY",\n api_base="YOUR_API_BASE_PATH",\n api_type="azure",\n api_version="YOUR_API_VERSION",\n model_name="text-embedding-3-small"\n )\n +\n Integrations\n Embedding Integrations\n Embeddings are the A.I-native way to represent any kind of data, making them the perfect fit for working with all kinds of A.I-powered tools and algorithms. They can represent text, images, and soon audio and video. There are many options for creating embeddings, whether locally using an installed library, or by calling an API.\n\n Chroma provides lightweight wrappers around popular embedding providers, making it easy to use them in your apps. You can set an embedding function when you create a Chroma collection, which will be used automatically, or you can call them directly yourself.\n\n Python\tTypescript\n OpenAI\t\u2713\t\u2713\n Google Gemini\t\u2713\t\u2713\n Cohere\t\u2713\t\u2713\n Hugging Face\t\u2713\t-\n Instructor\t\u2713\t-\n Hugging Face Embedding Server\t\u2713\t\u2713\n Jina AI\t\u2713\t\u2713\n Roboflow\t\u2713\t-\n Ollama Embeddings\t\u2713\t\u2713\n +\n # typescript\n import { OpenAIEmbeddingFunction } from 'chromadb';\n\n const embeddingFunction = new OpenAIEmbeddingFunction({\n openai_api_key: "apiKey",\n openai_model: "text-embedding-3-small"\n })\n\n // use directly\n const embeddings = embeddingFunction.generate(["document1","document2"])\n\n // pass documents to query for .add and .query\n let collection = await client.createCollection({\n name: "name",\n embeddingFunction: embeddingFunction\n })\n collection = await client.getCollection({\n name: "name",\n embeddingFunction: embeddingFunction\n })\n +\n Chroma supports filtering queries by metadata and document contents. The where filter is used to filter by metadata.\n\n In order to filter on metadata, you must supply a where filter dictionary to the query. The dictionary must have the following structure:\n\n\n {\n "metadata_field": {\n : \n }\n }\n +\n Filtering metadata supports the following operators:\n\n $eq - equal to (string, int, float)\n $ne - not equal to (string, int, float)\n $gt - greater than (int, float)\n $gte - greater than or equal to (int, float)\n $lt - less than (int, float)\n $lte - less than or equal to (int, float)}\n }\n +\n # Using the $eq operator is equivalent to using the where filter\n {\n "metadata_field": "search_string"\n }\n\n # is equivalent to\n\n {\n "metadata_field": {\n "$eq": "search_string"\n }\n }\n +\n # An $and operator will return results that match all of the filters in the list.\n {\n "$and": [\n {\n "metadata_field": {\n : \n }\n },\n {\n "metadata_field": {\n : \n }\n }\n ]\n }\n\n +\n # An $or operator will return results that match any of the filters in the list.\n {\n "$or": [\n {\n "metadata_field": {\n : \n }\n },\n {\n "metadata_field": {\n : \n }\n }\n ]\n }\n +\n Using inclusion operators ($in and $nin)\n The following inclusion operators are supported:\n\n $in - a value is in predefined list (string, int, float, bool)\n $nin - a value is not in predefined list (string, int, float, bool)\n An $in operator will return results where the metadata attribute is part of a provided list:\n +\n Running Chroma in Client-Server Mode\n Chroma can also be configured to run in client/server mode. In this mode, the Chroma client connects to a Chroma server running in a separate process.\n\n To start the Chroma server, run the following command:\n\n\n chroma run --path /db_path\n +\n # Running Chroma in Client-Server Mode in Typescript\n import { ChromaClient } from "chromadb";\n\n const client = new ChromaClient();\n +\n import chromadb\n # use the Chroma HTTP client to connect to the server\n chroma_client = chromadb.HttpClient(host='localhost', port=8000)\n\n +\n import asyncio\n import chromadb\n\n # to use AsyncHttpClient instead\n async def main():\n client = await chromadb.AsyncHttpClient()\n\n collection = await client.create_collection(name="my_collection")\n await collection.add(\n documents=["hello world"],\n ids=["id1"]\n )\n\n asyncio.run(main())\n +\n collection.update(\n ids=["id1", "id2", "id3", ...],\n embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],\n metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],\n documents=["doc1", "doc2", "doc3", ...],\n )\n +\n Any property of records in a collection can be updated with .update\n\n If an id is not found in the collection, an error will be logged and the update will be ignored. If documents are supplied without corresponding embeddings, the embeddings will be recomputed with the collection's embedding function.\n\n If the supplied embeddings are not the same dimension as the collection, an exception will be raised.\n +\n # upsert operation updates existing items, or adds them if they don't yet exist (Python)\n collection.upsert(\n ids=["id1", "id2", "id3", ...],\n embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],\n metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],\n documents=["doc1", "doc2", "doc3", ...],\n )\n +\n await collection.update({\n ids: ["id1", "id2", "id3", ...], \n embeddings: [[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...], \n metadatas: [{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...], \n documents: ["doc1", "doc2", "doc3", ...]\n })\n\n +\n # upsert operation updates existing items, or adds them if they don't yet exist (Python)\n await collection.upsert({\n ids: ["id1", "id2", "id3"],\n embeddings: [\n [1.1, 2.3, 3.2],\n [4.5, 6.9, 4.4],\n [1.1, 2.3, 3.2],\n ],\n metadatas: [\n { chapter: "3", verse: "16" },\n { chapter: "3", verse: "5" },\n { chapter: "29", verse: "11" },\n ],\n documents: ["doc1", "doc2", "doc3"],\n });\n diff --git a/sample_apps/generative_benchmarking/functions/utils.py b/sample_apps/generative_benchmarking/functions/utils.py index e0f6831795a..d989d748b48 100644 --- a/sample_apps/generative_benchmarking/functions/utils.py +++ b/sample_apps/generative_benchmarking/functions/utils.py @@ -1,10 +1,9 @@ import pandas as pd from typing import List, Dict + def combined_datasets_dataframes( - queries: pd.DataFrame, - corpus: pd.DataFrame, - qrels: pd.DataFrame + queries: pd.DataFrame, corpus: pd.DataFrame, qrels: pd.DataFrame ) -> pd.DataFrame: qrels = qrels.merge(queries, left_on="query-id", right_on="_id", how="left") qrels.rename(columns={"text": "query-text"}, inplace=True) @@ -15,7 +14,10 @@ def combined_datasets_dataframes( return qrels -def create_metrics_dataframe(results_list: List[Dict[str, Dict[str, float]]]) -> pd.DataFrame: + +def create_metrics_dataframe( + results_list: List[Dict[str, Dict[str, float]]] +) -> pd.DataFrame: all_metrics = [] for result in results_list: @@ -23,28 +25,39 @@ def create_metrics_dataframe(results_list: List[Dict[str, Dict[str, float]]]) -> results = result["results"] all_metrics.append((model, results)) - + rows = [] for model, metrics in all_metrics: row = { - 'Model': model, - 'Recall@1': metrics['Recall']['Recall@1'], - 'Recall@3': metrics['Recall']['Recall@3'], - 'Recall@5': metrics['Recall']['Recall@5'], - 'Recall@10': metrics['Recall']['Recall@10'], - 'Precision@3': metrics['Precision']['P@3'], - 'Precision@5': metrics['Precision']['P@5'], - 'Precision@10': metrics['Precision']['P@10'], - 'NDCG@3': metrics['NDCG']['NDCG@3'], - 'NDCG@5': metrics['NDCG']['NDCG@5'], - 'NDCG@10': metrics['NDCG']['NDCG@10'], - 'MAP@3': metrics['MAP']['MAP@3'], - 'MAP@5': metrics['MAP']['MAP@5'], - 'MAP@10': metrics['MAP']['MAP@10'], + "Model": model, + "Recall@1": metrics["Recall"]["Recall@1"], + "Recall@3": metrics["Recall"]["Recall@3"], + "Recall@5": metrics["Recall"]["Recall@5"], + "Recall@10": metrics["Recall"]["Recall@10"], + "Precision@3": metrics["Precision"]["P@3"], + "Precision@5": metrics["Precision"]["P@5"], + "Precision@10": metrics["Precision"]["P@10"], + "NDCG@3": metrics["NDCG"]["NDCG@3"], + "NDCG@5": metrics["NDCG"]["NDCG@5"], + "NDCG@10": metrics["NDCG"]["NDCG@10"], + "MAP@3": metrics["MAP"]["MAP@3"], + "MAP@5": metrics["MAP"]["MAP@5"], + "MAP@10": metrics["MAP"]["MAP@10"], } rows.append(row) metrics_df = pd.DataFrame(rows) - return metrics_df \ No newline at end of file + return metrics_df + + +def normalize_collection_name(path: str) -> str: + file_name = ( + path.rsplit("/", 1)[-1].rsplit(".", 1)[0].replace("/", "-").replace("_", "-") + ) + return "".join(c for c in file_name if c.isalnum() or c in ["_", "-"]) + + +def env_var_provided(val: str | None) -> bool: + return val is not None and len(val) > 0 diff --git a/sample_apps/generative_benchmarking/generate_benchmark.ipynb b/sample_apps/generative_benchmarking/generate_benchmark.ipynb index 77129e8387c..5fd48640611 100644 --- a/sample_apps/generative_benchmarking/generate_benchmark.ipynb +++ b/sample_apps/generative_benchmarking/generate_benchmark.ipynb @@ -9,10 +9,10 @@ "This notebook walks through how to generate a custom benchmark based on your data.\n", "\n", "We will be using OpenAI for our embedding model and LLM, but this can easily be switched out:\n", - "- Various embedding functions are provided in `embedding_functions.py`\n", - "- LLM prompts are provided in `llm_functions.py`\n", "\n", - "NOTE: When switching out embedding models, you will need to make a new collection for your new embeddings. Then, embed the same documents and queries with the embedding model of your choice. \n", + "Various embedding functions are provided in `functions/embed.py`\n", + "- LLM prompts are provided in `functions/llm.py`\n", + "- NOTE: When switching out embedding models, you will need to make a new collection for your new embeddings. Then, embed the same documents and queries with the embedding model of your choice.\n", "\n", "Use the same golden dataset of queries when comparing embedding models on the same data.\n", "\n", @@ -20,143 +20,147 @@ ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ - "## 1. Setup" + "%pip install -r requirements.txt -q" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### 1.1 Install & Import\n", + "## 0. (Optional) Use your own data!\n", "\n", - "Install the necessary packages." + "This demo is already preloaded with sample data from Chroma docs, but you can also use your own data.\n", + "\n", + "If you want to use your own data, change `COLLECTION_NAME` to the name of the collection where you want your data.\n", + "\n", + "If you want to create a new collection with your own local data, use `load_data.py`" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ - "%pip install -r requirements.txt" + "# Sample data collection name: generative-benchmarking-chroma-docs\n", + "COLLECTION_NAME = \"generative-benchmarking-chroma-docs\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Import modules." + "For the sample dataset, we will be creating a dataset for creating a technical support bot.\n", + "\n", + "You can change the subject of the generated dataset by changing the following variables:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ - "%load_ext autoreload\n", - "%autoreload 2\n", - "\n", - "import chromadb\n", - "import pandas as pd\n", - "import numpy as np\n", - "import json\n", - "import os\n", - "import dotenv\n", - "from pathlib import Path\n", - "from datetime import datetime\n", - "from openai import OpenAI as OpenAIClient\n", - "from anthropic import Anthropic as AnthropicClient\n", - "from functions.llm import *\n", - "from functions.embed import *\n", - "from functions.chroma import *\n", - "from functions.evaluate import *\n", - "from functions.visualize import *\n", - "from functions.types import *\n", - "\n", - "dotenv.load_dotenv()" + "context = \"This is a technical support bot for Chroma, a vector database company often used by developers for building AI applications.\"\n", + "example_queries = \"\"\"\n", + " how to add to a collection\n", + " filter by metadata\n", + " retrieve embeddings when querying\n", + " how to use openai embedding function when adding to collection\n", + " \"\"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### 1.2 Set Variables" + "## 1. Setup" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "We use pre-chunked [Chroma Docs](https://docs.trychroma.com/docs/overview/introduction) as an example. To run this notebook with your own data, uncomment the commented out lines and fill in.\n", + "### 1.1 Install & Import\n", "\n", - "**[Modify]** `COLLECTION_NAME` when you change your embedding model" + "Install the necessary packages." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Import modules." ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "with open('data/chroma_docs.json', 'r') as f:\n", - " corpus = json.load(f)\n", - "\n", - "context = \"This is a technical support bot for Chroma, a vector database company often used by developers for building AI applications.\"\n", - "example_queries = \"\"\"\n", - " how to add to a collection\n", - " filter by metadata\n", - " retrieve embeddings when querying\n", - " how to use openai embedding function when adding to collection\n", - " \"\"\"\n", - "\n", - "COLLECTION_NAME = \"chroma-docs-openai-large\" # change this collection name whenever you switch embedding models\n", - "\n", - "# Generate a Benchmark with your own data:\n", - "\n", - "# with open('filepath/to/your/data.json', 'r') as f:\n", - "# corpus = json.load(f)\n", - "\n", - "# context = \"FILL IN WITH CONTEXT RELEVANT TO YOUR USE CASE\"\n", - "# example_queries = \"FILL IN WITH EXAMPLE QUERIES\"\n", + "%load_ext autoreload\n", + "%autoreload 2\n", "\n", - "# COLLECTION_NAME = \"YOUR COLLECTION NAME\"" + "import chromadb\n", + "import pandas as pd\n", + "import json\n", + "import os\n", + "import dotenv\n", + "from pathlib import Path\n", + "from datetime import datetime\n", + "from openai import OpenAI as OpenAIClient\n", + "from functions.utils import *\n", + "from functions.llm import *\n", + "from functions.embed import *\n", + "from functions.chroma import *\n", + "from functions.evaluate import *\n", + "from functions.visualize import *\n", + "from functions.types import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### 1.2 Load API Keys\n", - "\n", - "To use Chroma Cloud, you can sign up for a Chroma Cloud account [here](https://www.trychroma.com/) and create a new database." + "### 1.2 Set Variables" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ + "dotenv.load_dotenv();\n", + "\n", "# Embedding Model & LLM\n", "OPENAI_API_KEY = os.getenv(\"OPENAI_API_KEY\")\n", + "assert OPENAI_API_KEY != None and len(OPENAI_API_KEY) > 0, 'Please provide an OpenAI API key'\n", + "\n", + "CHROMA_CLOUD_API_KEY = os.getenv(\"CHROMA_CLOUD_API_KEY\")\n", + "CHROMA_HOST=os.getenv(\"CHROMA_HOST\")\n", + "CHROMA_TENANT=os.getenv(\"CHROMA_TENANT\")\n", + "CHROMA_DB_NAME=os.getenv(\"CHROMA_DB_NAME\")\n", + "\n", + "using_chroma_cloud = env_var_provided(CHROMA_CLOUD_API_KEY)\n", "\n", - "# If you want to use Chroma Cloud, uncomment and fill in the following:\n", - "# CHROMA_TENANT = \"YOUR CHROMA TENANT ID\"\n", - "# X_CHROMA_TOKEN = \"YOUR CHROMA API KEY\"\n", - "# DATABASE_NAME = \"YOUR CHROMA DATABASE NAME\"" + "if using_chroma_cloud:\n", + " assert env_var_provided(CHROMA_HOST)\n", + " assert env_var_provided(CHROMA_TENANT)\n", + " assert env_var_provided(CHROMA_DB_NAME)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### 1.3 Set Clients\n", - "\n", - "Initialize the clients." + "### 1.3 Connect to Chroma" ] }, { @@ -165,92 +169,58 @@ "metadata": {}, "outputs": [], "source": [ - "chroma_client = chromadb.Client()\n", - "\n", - "# If you want to use Chroma Cloud, uncomment the following line:\n", - "# chroma_client = chromadb.HttpClient(\n", - "# ssl=True,\n", - "# host='api.trychroma.com',\n", - "# tenant=CHROMA_TENANT,\n", - "# database=DATABASE_NAME,\n", - "# headers={\n", - "# 'x-chroma-token': X_CHROMA_TOKEN\n", - "# }\n", - "# )\n", + "chroma_client = chromadb.HttpClient(\n", + " ssl=using_chroma_cloud,\n", + " host=CHROMA_HOST,\n", + " tenant=CHROMA_TENANT,\n", + " database=CHROMA_DB_NAME,\n", + " headers={\n", + " 'x-chroma-token': CHROMA_CLOUD_API_KEY\n", + " }\n", + ")\n", "\n", - "openai_client = OpenAIClient(api_key=OPENAI_API_KEY)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 2. Create Chroma Collection\n", + "corpus_collection = chroma_client.get_or_create_collection(\n", + " name=COLLECTION_NAME,\n", + " metadata={\"hnsw:space\": \"cosine\"}\n", + ")\n", "\n", - "If you already have a Chroma Collection for your data, skip to **2.3**." + "assert corpus_collection.count() > 0, \\\n", + " ('Your collection is empty. If you want to create a new collection with '\n", + " 'your own data, use the `load_data.py` script.')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### 2.1 Load in Your Data" + "### 1.4 Connect to Embedding Provider" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ - "corpus_ids = list(corpus.keys())\n", - "corpus_documents = [corpus[key] for key in corpus_ids]" + "openai_client = OpenAIClient(api_key=OPENAI_API_KEY)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### 2.2 Embed Data & Add to Chroma Collection\n", - "\n", - "Embed your documents using an embedding model of your choice. We use Openai's text-embedding-3-large here, but have other functions available in `embed.py`. You may also define your own embedding function.\n", - "\n", - "We use batching and multi-threading for efficiency.\n", - "\n", - "**[Modify]** embedding function (`openai_embed_in_batches`) to the embedding model you wish to use" + "## 2. Get Data" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "corpus_embeddings = openai_embed_in_batches(\n", - " openai_client=openai_client,\n", - " texts=corpus_documents,\n", - " model=\"text-embedding-3-large\",\n", - ")\n", + "### 2.1 Load in Your Data\n", "\n", - "corpus_collection = chroma_client.get_or_create_collection(\n", - " name=COLLECTION_NAME,\n", - " metadata={\"hnsw:space\": \"cosine\"}\n", - ")\n", + "If you using your own data, this will embed your data. We use OpenAI's text-embedding-3-large here, but have other functions available in `embed.py`. You may also define your own embedding function.\n", "\n", - "collection_add_in_batches(\n", - " collection=corpus_collection,\n", - " ids=corpus_ids,\n", - " texts=corpus_documents,\n", - " embeddings=corpus_embeddings,\n", - ")\n", - "\n", - "corpus = {\n", - " id: {\n", - " 'document': document,\n", - " 'embedding': embedding\n", - " }\n", - " for id, document, embedding in zip(corpus_ids, corpus_documents, corpus_embeddings)\n", - "}" + "We use batching and multi-threading for efficiency." ] }, { @@ -259,16 +229,13 @@ "metadata": {}, "outputs": [], "source": [ - "corpus_collection = chroma_client.get_collection(\n", - " name=COLLECTION_NAME\n", - ")\n", - "\n", "corpus = get_collection_items(\n", " collection=corpus_collection\n", ")\n", - "\n", "corpus_ids = [key for key in corpus.keys()]\n", - "corpus_documents = [corpus[key]['document'] for key in corpus_ids]" + "corpus_documents = [corpus[key]['document'] for key in corpus_ids]\n", + "corpus_embeddings = [corpus[key]['embedding'] for key in corpus_ids]\n", + "assert len(corpus) > 0" ] }, { @@ -295,7 +262,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -317,9 +284,17 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Filtering documents: 100%|██████████| 648/648 [20:07<00:00, 1.86s/it]\n" + ] + } + ], "source": [ "filtered_document_ids = filter_documents(\n", " client=openai_client,\n", @@ -333,7 +308,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -408,6 +383,26 @@ " example_queries=example_queries\n", ")\n", "\n", + "golden_collection = chroma_client.get_or_create_collection(\n", + " name=f'{COLLECTION_NAME}-golden',\n", + " metadata={\"hnsw:space\": \"cosine\"}\n", + ")\n", + "\n", + "golden_ids = golden_dataset['id'].tolist()\n", + "golden_queries = golden_dataset['query'].tolist()\n", + "golden_embeddings = openai_embed_in_batches(\n", + " openai_client=openai_client,\n", + " texts=golden_queries,\n", + " model=\"text-embedding-3-large\",\n", + ")\n", + "\n", + "collection_add_in_batches(\n", + " collection=golden_collection,\n", + " ids=golden_ids,\n", + " texts=golden_queries,\n", + " embeddings=golden_embeddings,\n", + ")\n", + "\n", "golden_dataset.head()" ] }, @@ -427,16 +422,6 @@ "### 5.1 Prepare Inputs" ] }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [], - "source": [ - "queries = golden_dataset['query'].tolist()\n", - "ids = golden_dataset['id'].tolist()" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -454,7 +439,7 @@ "source": [ "query_embeddings = openai_embed_in_batches(\n", " openai_client=openai_client,\n", - " texts=queries,\n", + " texts=golden_queries,\n", " model=\"text-embedding-3-large\"\n", ")\n", "\n", @@ -463,7 +448,7 @@ " text=query,\n", " embedding=embedding\n", " )\n", - " for id, query, embedding in zip(ids, queries, query_embeddings)\n", + " for id, query, embedding in zip(golden_ids, golden_queries, query_embeddings)\n", "}\n", "\n", "query_embeddings_lookup = QueryLookup(lookup=query_embeddings_lookup_dict)" @@ -478,14 +463,14 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "qrels = pd.DataFrame(\n", " {\n", - " \"query-id\": ids,\n", - " \"corpus-id\": ids,\n", + " \"query-id\": golden_ids,\n", + " \"corpus-id\": golden_ids,\n", " \"score\": 1\n", " }\n", ")" @@ -500,46 +485,9 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Processing batches: 100%|██████████| 1/1 [00:00<00:00, 18.79it/s]" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "NDCG@1: 0.61364\n", - "NDCG@3: 0.7224\n", - "NDCG@5: 0.75956\n", - "NDCG@10: 0.76766\n", - "MAP@1: 0.61364\n", - "MAP@3: 0.69697\n", - "MAP@5: 0.71742\n", - "MAP@10: 0.72121\n", - "Recall@1: 0.61364\n", - "Recall@3: 0.79545\n", - "Recall@5: 0.88636\n", - "Recall@10: 0.90909\n", - "P@1: 0.61364\n", - "P@3: 0.26515\n", - "P@5: 0.17727\n", - "P@10: 0.09091\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], + "outputs": [], "source": [ "results = run_benchmark(\n", " query_embeddings_lookup=query_embeddings_lookup,\n", @@ -574,7 +522,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -583,11 +531,34 @@ "with open(os.path.join(results_dir, f'{timestamp}.json'), 'w') as f:\n", " json.dump(results_to_save, f)" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Finished\n", + "\n", + "Your dataset is ready!\n", + "\n", + "Next steps:\n", + "1. Rerun this notebook using different embedding models\n", + "2. Use `compare.ipynb` to compare the retrieval performance of different models" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(f'View your dataset: `chroma browse {COLLECTION_NAME}{' --local' if not using_chroma_cloud else ''}`')\n", + "print(f'View the generated golden dataset: `chroma browse {COLLECTION_NAME}-golden{(' --local' if not using_chroma_cloud else '')}`')" + ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "generative-benchmarking-16hOiizI-py3.13", "language": "python", "name": "python3" }, @@ -601,7 +572,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.6" + "version": "3.13.3" } }, "nbformat": 4, diff --git a/sample_apps/generative_benchmarking/load_data.py b/sample_apps/generative_benchmarking/load_data.py new file mode 100644 index 00000000000..a5fd2597fe4 --- /dev/null +++ b/sample_apps/generative_benchmarking/load_data.py @@ -0,0 +1,77 @@ +""" +Use this script to upload your local data to a Chroma collection +Each line in this file is an entry in the dataset +Look at data/chroma_docs.txt for an example of the format + +Run using: + python load_data.py + poetry run python load_data.py + conda run python load_data.py +""" + +import os +import uuid +import dotenv + +from openai import OpenAI as OpenAIClient +from functions.chroma import collection_add_in_batches +from functions.embed import openai_embed_in_batches +import chromadb + +dotenv.load_dotenv() + +OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") +openai_client = OpenAIClient(api_key=OPENAI_API_KEY) + +# CHANGE ME ################################################################### +DATASET_FILE = "data/chroma_docs.txt" +CHROMA_COLLECTION_NAME = "generative-benchmarking-custom-data" + + +def embed(documents: list[str]) -> list[list[float]]: + # We provide helper functions to use OpenAI, Voyage, and Jina, and + # more! Check out functions/embed.py and replace this function with your own! + return openai_embed_in_batches( + openai_client=openai_client, + texts=documents, + model="text-embedding-3-large", + ) + + +# CHANGE ME ################################################################### + +assert os.path.exists(DATASET_FILE), "Check the value of DATASET_FILE" + +CHROMA_CLOUD_API_KEY = os.getenv("CHROMA_CLOUD_API_KEY") or "" +CHROMA_HOST = os.getenv("CHROMA_HOST") +CHROMA_TENANT = os.getenv("CHROMA_TENANT") +CHROMA_DB_NAME = os.getenv("CHROMA_DB_NAME") + +assert CHROMA_HOST, "Check the value of CHROMA_HOST in .env" +assert CHROMA_TENANT, "Check the value of CHROMA_TENANT in .env" +assert CHROMA_DB_NAME, "Check the value of CHROMA_DB_NAME in .env" + +using_local_chroma = CHROMA_HOST == "localhost" + +chroma_client = chromadb.HttpClient( + ssl=not using_local_chroma, + host=CHROMA_HOST, + tenant=CHROMA_TENANT, + database=CHROMA_DB_NAME, + headers={"x-chroma-token": CHROMA_CLOUD_API_KEY}, +) + +corpus_collection = chroma_client.get_or_create_collection( + name=CHROMA_COLLECTION_NAME, metadata={"hnsw:space": "cosine"} +) + +with open(DATASET_FILE) as f: + corpus_documents = f.readlines() + corpus_ids = [str(uuid.uuid4()) for _ in range(len(corpus_documents))] + corpus_embeddings = embed(corpus_documents) + collection_add_in_batches( + collection=corpus_collection, + ids=corpus_ids, + texts=corpus_documents, + embeddings=corpus_embeddings, + )