파이썬 Chromadb 상세 개발 가이드
설치
pip install chromadb
Chromadb 데이터 영속화
import chromadb
Chroma 데이터베이스 파일의 저장 경로를 지정할 수 있습니다. 데이터가 있으면 프로그램이 시작될 때 데이터베이스 파일이 자동으로 로드됩니다.
client = chromadb.PersistentClient(path="/data/tizi365.db")
path
매개변수는 Chroma 데이터베이스 파일의 경로입니다.
참고: Chroma 데이터베이스의 경우 클라이언트 개체를 한 번 만들면 충분합니다. 동일한 경로에 여러 클라이언트를 로드하고 저장하면 예기치 않은 동작(데이터 삭제 등)이 발생할 수 있습니다. 일반적으로 응용 프로그램에서는 하나의 Chroma 클라이언트만을 만들어야 합니다.
클라이언트 개체의 일반적으로 사용되는 함수 몇 가지:
client.reset() # 데이터베이스를 지우고 완전히 재설정합니다
컬렉션 작업
Chromadb는 벡터 데이터의 컬렉션을 관리하기 위해 collection
원시를 사용하며, 이는 MySQL의 테이블과 유사합니다.
컬렉션 생성, 보기 및 삭제
Chroma는 URL에서 컬렉션 이름을 사용하므로 몇 가지 네이밍 제약이 있습니다:
- 이름 길이는 3자에서 63자 사이여야 합니다.
- 이름은 소문자나 숫자로 시작하고 끝나야 하며, 그 사이에는 점, 하이픈, 밑줄을 포함할 수 있습니다.
- 이름은 두 개의 연속된 점을 포함할 수 없습니다.
- 이름은 유효한 IP 주소일 수 없습니다.
컬렉션을 생성하려면 컬렉션 이름과 옵션으로 벡터 계산 함수(임베딩 함수)를 지정해야 합니다. 임베딩 함수가 제공된 경우에는 컬렉션에 액세스할 때마다 제공해야 합니다.
참고: 벡터 계산 함수(임베딩 함수)의 목적은 텍스트 벡터를 계산하는 것입니다.
collection = client.create_collection(name="my_collection", embedding_function=emb_fn)
collection = client.get_collection(name="my_collection", embedding_function=emb_fn)
임베딩 함수는 텍스트를 입력으로 받아 계산된 벡터를 반환합니다.
참고: 초보자는 텍스트 임베딩 모델 튜토리얼을 참조할 수 있습니다.
.get_collection
함수로 기존 컬렉션을 참조하고, .delete_collection
을 사용하여 컬렉션을 삭제할 수 있습니다. 또한, .get_or_create_collection
을 사용하여 컬렉션을 참조(존재하는 경우)하거나 존재하지 않는 경우 생성할 수 있습니다.
collection = client.get_collection(name="tizi365")
collection = client.get_or_create_collection(name="tizi365")
client.delete_collection(name="tizi365")
다른 일반적으로 사용되는 컬렉션 작업:
collection.peek() # 컬렉션 내 처음 10개의 데이터 목록을 반환합니다
collection.count() # 컬렉션 내 전체 데이터 수를 반환합니다
collection.modify(name="new_name") # 컬렉션의 이름을 변경합니다
벡터 거리 계산 방법 지정
create_collection
함수는 옵션으로 metadata 매개변수를 포함합니다. hnsw:space
값을 설정하여 벡터 공간 거리 계산 방법을 사용자 정의할 수 있습니다.
참고: 벡터 데이터는 벡터 간의 공간 거리를 계산하여 벡터 간 유사성을 나타냅니다. 거리가 가까울수록 유사성이 높고, 그 반대도 마찬가지입니다.
collection = client.create_collection(
name="collection_name",
metadata={"hnsw:space": "cosine"} # l2가 기본 계산 방법입니다
)
hnsw:space
의 유효한 옵션은 "l2", "ip", 또는 "cosine"입니다. 기본값은 "l2"입니다.
컬렉션에 데이터 추가하기
.add
메서드를 사용하여 크로마에 데이터를 추가합니다.
문서 벡터를 지정하지 않고 데이터를 직접 추가합니다:
collection.add(
documents=["lorem ipsum...", "doc2", "doc3", ...],
metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],
ids=["id1", "id2", "id3", ...]
)
만약 크로마가 문서 목록을 받으면, 자동으로 컬렉션의 임베딩 함수를 사용하여 문서들의 벡터를 계산합니다 (컬렉션 생성 시 임베딩 함수를 지정하지 않은 경우 기본 값이 사용됩니다). 크로마는 또한 문서 자체를 저장합니다. 선택한 임베딩 함수로 계산하는 데 문서가 너무 커서 처리할 수 없는 경우 예외가 발생합니다.
각 문서는 고유한 ID (ids)를 가져야 합니다. 동일한 ID를 두 번 추가하면 초기 값을 하나만 저장합니다. 선택적으로, 각 문서에 대한 추가 정보를 저장할 수 있는 메타데이터 사전 목록 (metadatas)을 제공하여 쿼리 중에 데이터를 필터링하는 데 사용할 수 있습니다.
또는 문서와 관련된 벡터 데이터 목록을 직접 제공할 수 있으며, 크로마는 자동으로 벡터를 계산하지 않고 제공한 벡터 데이터를 사용합니다.
collection.add(
documents=["doc1", "doc2", "doc3", ...],
embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],
metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],
ids=["id1", "id2", "id3", ...]
)
제공된 벡터 데이터의 차원(길이)이 컬렉션의 차원과 일치하지 않는 경우 예외가 발생합니다.
또한 문서를 다른 곳에 저장하고 크로마에 벡터 데이터와 메타데이터 목록을 제공할 수 있습니다. 다른 곳에 저장된 문서와 벡터를 ids를 사용하여 연결할 수 있습니다.
collection.add(
embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],
metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],
ids=["id1", "id2", "id3", ...]
)
참고: 벡터 데이터베이스의 핵심 기능은 벡터 데이터를 기반으로 하는 의미론적 유사성 검색입니다. 벡터 데이터베이스의 크기를 줄이고 효율성을 높이기 위해 벡터 데이터 및 필요한 필터링 속성을 벡터 데이터베이스에 저장할지 선택할 수 있습니다. 글 내용과 같은 다른 데이터는 MYSQL과 같은 데이터베이스에 저장하여 ID를 통해 연관시킬 수 있습니다.
컬렉션 데이터 쿼리
.query
메서드를 사용하여 Chroma 데이터 세트를 다양한 방식으로 쿼리할 수 있습니다.
쿼리는 query_embeddings(벡터 데이터)를 사용하여 할 수 있습니다.
팁: 실제 개발 시나리오에서 query_embeddings는 일반적으로 텍스트 임베딩 모델을 통해 사용자 쿼리의 벡터를 먼저 계산한 다음 이 벡터를 사용하여 유사한 콘텐츠를 쿼리합니다.
collection.query(
query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],
n_results=10,
where={"metadata_field": "이_것과_동일한"},
where_document={"$contains":"검색_문자열"}
)
쿼리는 각 쿼리 벡터 (query_embedding)와 가장 일치하는 n_results 결과를 순서대로 반환합니다. 선택적으로 where 필터 사전을 제공하여 각 문서와 관련된 메타데이터를 기반으로 결과를 필터링할 수 있습니다. 또한 선택적으로 where_document 필터 사전을 제공하여 문서 콘텐츠를 기반으로 결과를 필터링할 수 있습니다.
제공된 query_embeddings가 컬렉션의 차원과 일치하지 않으면 예외가 발생합니다. 일관된 벡터 차원을 보장하려면 동일한 텍스트 임베딩 모델을 사용하여 벡터를 계산하세요.
또한 쿼리 텍스트 세트를 사용하여 쿼리할 수 있습니다. Chroma는 먼저 각 쿼리 텍스트에 대해 컬렉션의 임베딩 함수를 사용하여 벡터를 계산한 다음 생성된 텍스트 벡터를 사용하여 쿼리를 수행합니다.
collection.query(
query_texts=["문서10", "thus spake zarathustra", ...],
n_results=10,
where={"metadata_field": "이_것과_동일한"},
where_document={"$contains":"검색_문자열"}
)
또한 .get을 사용하여 컬렉션에서 id로 데이터를 쿼리할 수 있습니다.
collection.get(
ids=["id1", "id2", "id3", ...],
where={"style": "스타일1"}
)
.get은 또한 where와 where_document 필터를 지원합니다. id가 제공되지 않으면 where와 where_document 필터와 일치하는 컬렉션의 모든 항목을 반환합니다.
반환 필드 지정
get이나 query를 사용할 때 include 매개변수를 사용하여 반환할 데이터를 지정할 수 있습니다--embeddings
, documents
, 또는 metadatas
, 그리고 쿼리의 경우 거리 데이터가 반환되어야 합니다. 기본적으로 Chroma는 쿼리에 대해 문서와 메타데이터를 반환하고 쿼리의 경우 거리 데이터를 반환하며 "ids"를 항상 반환합니다. 쿼리나 get 메서드의 includes 매개변수에 필드 이름의 배열을 전달하여 반환할 필드를 지정할 수 있습니다.
collection.get(
include=["documents"]
)
collection.query(
query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],
include=["documents"]
)
Where 필터 사용
Chroma는 메타데이터 및 문서 콘텐츠를 기반으로 쿼리를 필터링하는 기능을 지원합니다. where 필터는 메타데이터를 필터링하는 데 사용되고, where_document 필터는 문서 콘텐츠를 필터링하는 데 사용되며, 다음은 필터 조건 표현 방법을 설명합니다.
메타데이터로 필터링
메타데이터를 필터링하려면 쿼리에 대해 where
필터 사전을 제공해야 합니다. 사전은 다음 구조를 가져야 합니다.
{
"metadata_필드": {
<연산자>: <값>
}
}
메타데이터 필터링은 다음 연산자를 지원합니다:
- $eq - 동일함 (문자열, 정수, 부동 소수점)
- $ne - 동일하지 않음 (문자열, 정수, 부동 소수점)
- $gt - 초과 (정수, 부동 소수점)
- $gte - 이상 (정수, 부동 소수점)
- $lt - 미만 (정수, 부동 소수점)
- $lte - 이하 (정수, 부동 소수점)
$eq 연산자를 사용하는 것은 where
필터를 사용하는 것과 동일합니다.
{
"metadata_필드": "검색_문자열"
}
{
"metadata_필드": {
"$eq": "검색_문자열"
}
}
문서 콘텐츠로 필터링
문서 콘텐츠를 필터링하려면 쿼리에 대해 where_document
필터 사전을 제공해야 합니다. 사전은 다음 구조를 가져야 합니다.
{
"$contains": "검색_문자열"
}
논리 연산자 사용하기
여러 필터를 결합하려면 $and
및 $or
논리 연산자를 사용할 수 있습니다.
$and
연산자는 리스트 내 모든 필터와 일치하는 결과를 반환합니다.
{
"$and": [
{
"metadata_field": {
<연산자>: <값>
}
},
{
"metadata_field": {
<연산자>: <값>
}
}
]
}
$or
연산자는 리스트 내 어떤 필터 조건이든 일치하는 결과를 반환합니다.
{
"$or": [
{
"metadata_field": {
<연산자>: <값>
}
},
{
"metadata_field": {
<연산자>: <값>
}
}
]
}
컬렉션 데이터 업데이트하기
.update
를 사용하면 컬렉션 내 데이터의 모든 속성을 업데이트할 수 있습니다.
collection.update(
ids=["id1", "id2", "id3", ...],
embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],
metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],
documents=["doc1", "doc2", "doc3", ...],
)
컬렉션에서 id를 찾을 수 없는 경우 오류가 기록되고 업데이트는 무시됩니다. 제공된 문서에 해당하는 벡터가 없는 경우 컬렉션의 임베딩 함수가 벡터를 계산하는 데 사용됩니다.
제공된 벡터 데이터의 차원이 컬렉션의 차원과 다른 경우 예외가 발생합니다.
Chroma는 또한 기존 데이터를 업데이트하고 없는 경우 새 데이터를 삽입하는 upsert
작업을 지원합니다.
collection.upsert(
ids=["id1", "id2", "id3", ...],
embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],
metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],
documents=["doc1", "doc2", "doc3", ...],
)
컬렉션 데이터 삭제하기
Chroma는 id
별로 컬렉션에서 데이터를 제거하는 데 .delete
를 지원합니다. 각 데이터와 관련된 벡터, 문서 및 메타데이터도 삭제됩니다.
collection.delete(
ids=["id1", "id2", "id3",...],
where={"chapter": "20"}
)
.delete
는 where
필터도 지원합니다. id가 제공되지 않으면 where
필터와 일치하는 컬렉션 내 모든 항목을 삭제합니다.