codewithkyrian / chromadb-php
Chroma开源嵌入数据库的PHP客户端
Requires
- php: ^8.1
- guzzlehttp/guzzle: ^7.0
Requires (Dev)
- mockery/mockery: ^1.6
- pestphp/pest: ^2.19
- symfony/var-dumper: ^6.3
README
一个用于无缝与Chroma矢量数据库交互的PHP库。
注意:此包与框架无关,可以在任何PHP项目中使用。如果您使用Laravel,您可能想查看此处的特定于Laravel的包,它提供更接近Laravel的体验,并包含一些额外功能。
描述
Chroma是一个开源的矢量数据库,允许您按比例存储、搜索和分析高维数据。它旨在快速、可扩展和可靠。它使构建需要高维矢量搜索的LLM(大型语言模型)应用程序和服务变得容易。
ChromaDB PHP为从PHP与Chroma交互提供了一个简单直观的接口。它使您能够
- 创建、读取、更新和删除文档。
- 执行查询和聚合。
- 管理集合和索引。
- 处理身份验证和授权。
- 无缝利用其他ChromaDB功能。
- 等等...
小示例
use Codewithkyrian\ChromaDB\ChromaDB; $chromaDB = ChromaDB::client(); // Check current ChromaDB version echo $chromaDB->version(); // Create a collection $collection = $chromaDB->createCollection('test-collection'); echo $collection->name; // test-collection echo $collection->id; // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx // Insert some documents into the collection $ids = ['test1', 'test2', 'test3']; $embeddings = [ [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0], [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0], [10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0], ]; $metadatas = [ ['url' => 'https://example.com/test1'], ['url' => 'https://example.com/test2'], ['url' => 'https://example.com/test3'], ]; $collection->add($ids, $embeddings, $metadatas); // Search for similar embeddings $queryResponse = $collection->query( queryEmbeddings: [ [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0] ], nResults: 2 ); // Print results echo $queryResponse->ids[0][0]; // test1 echo $queryResponse->ids[0][1]; // test2
要求
- PHP 8.1或更高版本
- 运行在客户端/服务器模式下的ChromaDB 0.4.0或更高版本
运行ChromaDB
为了使用此库,您需要在某处运行ChromaDB。您可以本地运行它或在云端运行。(Chroma目前不支持云端,但很快就会支持。)
目前,ChromaDB只能在Python中以内存中运行。但是,您可以通过运行python项目或使用docker镜像(推荐)以客户端/服务器模式运行它。
要运行docker镜像,您可以使用以下命令
docker run -p 8000:8000 chromadb/chroma
您还可以使用.env
文件传递一些环境变量
docker run -p 8000:8000 --env-file .env chromadb/chroma
或者如果您更喜欢使用docker-compose文件,可以使用以下
version: '3.9' services: chroma: image: 'chromadb/chroma' ports: - '8000:8000' volumes: - chroma-data:/chroma/chroma volumes: chroma-data: driver: local
然后使用以下命令运行它
docker-compose up -d
(有关如何运行ChromaDB的更多信息,请参阅Chroma文档。)
无论如何,您现在可以在http://localhost:8000
访问ChromaDB。
安装
composer require codewithkyrian/chromadb-php
使用
连接到ChromaDB
use Codewithkyrian\ChromaDB\ChromaDB; $chroma = ChromaDB::client();
默认情况下,ChromaDB将尝试使用默认数据库名称default_database
和默认租户名称default_tenant
连接到http://localhost:8000
。但是,您可以通过使用工厂方法构造客户端来更改这些值。
use Codewithkyrian\ChromaDB\ChromaDB; $chroma = ChromaDB::factory() ->withHost('http://localhost') ->withPort(8000) ->withDatabase('new_database') ->withTenant('new_tenant') ->connect();
如果租户或数据库不存在,该包将自动为您创建它们。
身份验证
ChromaDB支持基于静态令牌的身份验证。要使用它,您需要按照文档中的说明启动Chroma服务器,传递所需的环境变量。如果您使用的是docker镜像,您可以使用--env
标志或使用.env
文件传递环境变量,对于docker-compose文件,您可以使用env_file
选项或直接传递环境变量,如下所示
version: '3.9' services: chroma: image: 'chromadb/chroma' ports: - '8000:8000' environment: - CHROMA_SERVER_AUTHN_CREDENTIALS=test-token - CHROMA_SERVER_AUTHN_PROVIDER=chromadb.auth.token_authn.TokenAuthenticationServerProvider ...
然后您可以使用工厂方法连接到ChromaDB
use Codewithkyrian\ChromaDB\ChromaDB; $chroma = ChromaDB::factory() ->withAuthToken('test-token') ->connect();
获取版本
echo $chroma->version(); // 0.4.0
创建集合
创建集合就像在客户端上调用createCollection
方法并将集合名称传递给它一样简单。
$collection = $chroma->createCollection('test-collection');
如果集合已存在于数据库中,包将抛出异常。
插入文档
$ids = ['test1', 'test2', 'test3']; $embeddings = [ [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0], [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0], [10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0], ]; $metadatas = [ ['url' => 'https://example.com/test1'], ['url' => 'https://example.com/test2'], ['url' => 'https://example.com/test3'], ]; $collection->add($ids, $embeddings, $metadatas);
要将文档插入到集合中,您需要提供以下内容
ids
:文档ID数组。ID必须是唯一的,并且必须是字符串。embeddings
:文档嵌入数组。嵌入必须是长度一致的浮点数一维数组。您可以使用任何选择的嵌入模型来计算嵌入(只需确保在查询时也使用它即可)。metadatas
:文档元数据数组。元数据必须是键值对数组。
如果没有嵌入,可以传入文档并提供一个嵌入函数,该函数将用于为您计算嵌入。
传递嵌入函数
要使用嵌入函数,需要在创建集合时将其作为参数传入
use CodeWithKyrian\ChromaDB\EmbeddingFunction\EmbeddingFunctionInterface; $embeddingFunction = new OpenAIEmbeddingFunction('api-key', 'org-id', 'model-name'); $collection = $chroma->createCollection('test-collection', embeddingFunction: $embeddingFunction);
嵌入函数必须是EmbeddingFunctionInterface
的实例。有几个内置的嵌入函数可以用于
-
OpenAIEmbeddingFunction
:此嵌入函数使用OpenAI API来计算嵌入。您可以使用它如下use CodeWithKyrian\Chroma\EmbeddingFunction\OpenAIEmbeddingFunction; $embeddingFunction = new OpenAIEmbeddingFunction('api-key', 'org-id', 'model-name'); $collection = $chromaDB->createCollection('test-collection', embeddingFunction: $embeddingFunction);
您可以从OpenAI仪表板获取您的OpenAI API密钥和组织ID,如果您的API密钥不属于组织,则可以省略组织ID。模型名称是可选的,默认为
text-embedding-ada-002
-
JinaEmbeddingFunction
:这是Jina嵌入模型的包装器。您可以通过传递您的Jina API密钥和所需的模型来使用它。默认为jina-embeddings-v2-base-en
use Codewithkyrian\ChromaDB\Embeddings\JinaEmbeddingFunction; $embeddingFunction = new JinaEmbeddingFunction('api-key'); $collection = $chromaDB->createCollection('test-collection', embeddingFunction: $embeddingFunction);
-
HuggingFaceEmbeddingServerFunction
:此嵌入函数是HuggingFace Text Embedding Server的包装器。在使用之前,您需要在本地某处运行HuggingFace嵌入服务器。以下是使用方法use CodeWithKyrian\Chroma\EmbeddingFunction\HuggingFaceEmbeddingFunction; $embeddingFunction = new HuggingFaceEmbeddingFunction('api-key', 'model-name'); $collection = $chromaDB->createCollection('test-collection', embeddingFunction: $embeddingFunction);
除了内置的嵌入函数外,您还可以通过实现EmbeddingFunction
接口(包括匿名类)来创建自己的嵌入函数
use CodeWithKyrian\ChromaDB\EmbeddingFunction\EmbeddingFunctionInterface; $embeddingFunction = new class implements EmbeddingFunctionInterface { public function generate(array $texts): array { // Compute the embeddings here and return them as an array of arrays } }; $collection = $chroma->createCollection('test-collection', embeddingFunction: $embeddingFunction);
嵌入函数将为每个插入到集合中的文档批次调用,必须在创建集合或查询集合时提供。如果您不提供嵌入函数,并且不提供嵌入,则包将抛出异常。
使用嵌入函数将文档插入到集合中
$ids = ['test1', 'test2', 'test3']; $documents = [ 'This is a test document', 'This is another test document', 'This is yet another test document', ]; $metadatas = [ ['url' => 'https://example.com/test1'], ['url' => 'https://example.com/test2'], ['url' => 'https://example.com/test3'], ]; $collection->add( ids: $ids, documents: $documents, metadatas: $metadatas );
获取集合
$collection = $chromaDB->getCollection('test-collection');
或使用嵌入函数
$collection = $chromaDB->getCollection('test-collection', embeddingFunction: $embeddingFunction);
请确保您提供的嵌入函数与创建集合时使用的嵌入函数相同。
统计集合中的项目数
$collection->count() // 2
更新集合
$collection->update( ids: ['test1', 'test2', 'test3'], embeddings: [ [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0], [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0], [10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0], ], metadatas: [ ['url' => 'https://example.com/test1'], ['url' => 'https://example.com/test2'], ['url' => 'https://example.com/test3'], ] );
删除文档
$collection->delete(['test1', 'test2', 'test3']);
查询集合
$queryResponse = $collection->query( queryEmbeddings: [ [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0] ], nResults: 2 ); echo $queryResponse->ids[0][0]; // test1 echo $queryResponse->ids[0][1]; // test2
要查询集合,您需要提供以下内容
-
queryEmbeddings
(可选):查询嵌入数组。嵌入必须是浮点数一维数组。您可以使用任何选择的嵌入模型来计算嵌入(只需确保在插入时也使用它即可)。 -
nResults
:要返回的结果数量。默认为10。 -
queryTexts
(可选):查询文本数组。文本必须是字符串。如果您提供嵌入,则可以省略此内容。以下是一个示例$queryResponse = $collection->query( queryTexts: [ 'This is a test document' ], nResults: 2 ); echo $queryResponse->ids[0][0]; // test1 echo $queryResponse->ids[0][1]; // test2
-
where
(可选):用于根据其元数据过滤项目的where子句。以下是一个示例$queryResponse = $collection->query( queryEmbeddings: [ [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0] ], nResults: 2, where: [ 'url' => 'https://example.com/test1' ] ); echo $queryResponse->ids[0][0]; // test1
where子句必须是一个键值对数组。键必须是字符串,值可以是字符串或有效过滤器值数组。以下是有效过滤器(
$eq
、$ne
、$in
、$nin
、$gt
、$gte
、$lt
、$lte
)。$eq
:等于$ne
:不等于$gt
:大于$gte
:大于等于$lt
:小于$lte
:小于等于
以下是一个示例
$queryResponse = $collection->query( queryEmbeddings: [ [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0] ], nResults: 2, where: [ 'url' => [ '$eq' => 'https://example.com/test1' ] ] );
您还可以使用多个过滤器
$queryResponse = $collection->query( queryEmbeddings: [ [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0] ], nResults: 2, where: [ 'url' => [ '$eq' => 'https://example.com/test1' ], 'title' => [ '$ne' => 'Test 1' ] ] );
-
whereDocument
(可选):用于根据文档过滤项的where子句。以下是一个示例$queryResponse = $collection->query( queryEmbeddings: [ [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0] ], nResults: 2, whereDocument: [ 'text' => 'This is a test document' ] ); echo $queryResponse->ids[0][0]; // test1
where子句必须是一个键值对数组。键必须是字符串,值可以是字符串或有效过滤器值数组。在这种情况下,只支持两个过滤键
$contains
和$not_contains
。以下是一个示例
$queryResponse = $collection->query( queryEmbeddings: [ [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0] ], nResults: 2, whereDocument: [ 'text' => [ '$contains' => 'test document' ] ] );
-
include
(可选):要包含在响应中的字段数组。可能的值是embeddings
、documents
、metadatas
和distances
。默认为embeddings
和metadatas
(默认不包含documents
,因为它们可能很大)。$queryResponse = $collection->query( queryEmbeddings: [ [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0] ], nResults: 2, include: ['embeddings'] );
distances
仅适用于查询,不适用于获取。它返回查询嵌入与结果嵌入之间的距离。
有关查询和检索集合的其他相关信息,请参阅ChromaDB 文档。
删除集合中的项
要删除集合中的文档,传递一个包含项ID的数组
$collection->delete(['test1', 'test2']); $collection->count() // 1
传递ID是可选的。您可以使用where过滤器从集合中删除项
$collection->add( ['test1', 'test2', 'test3'], [ [1.0, 2.0, 3.0, 4.0, 5.0], [6.0, 7.0, 8.0, 9.0, 10.0], [11.0, 12.0, 13.0, 14.0, 15.0], ], [ ['some' => 'metadata1'], ['some' => 'metadata2'], ['some' => 'metadata3'], ] ); $collection->delete( where: [ 'some' => 'metadata1' ] ); $collection->count() // 2
删除集合
删除集合就像传递要删除的集合名称一样简单。
$chroma->deleteCollection('test_collection');
测试
// Run chroma by running the docker compose file in the repo
docker compose up -d
composer test
贡献者
- Kyrian Obikwelu
- 欢迎其他贡献者。
许可证
本项目采用MIT许可证。有关更多信息,请参阅LICENSE文件。