diff --git a/api/core/rag/datasource/vdb/pinecone/pinecone_vector.py b/api/core/rag/datasource/vdb/pinecone/pinecone_vector.py index 5deafe6245..b3865cc250 100644 --- a/api/core/rag/datasource/vdb/pinecone/pinecone_vector.py +++ b/api/core/rag/datasource/vdb/pinecone/pinecone_vector.py @@ -8,6 +8,7 @@ from pydantic import BaseModel from configs import dify_config from core.rag.datasource.vdb.field import Field from core.rag.datasource.vdb.vector_base import BaseVector +from core.rag.datasource.vdb.vector_type import VectorType from core.rag.datasource.vdb.vector_factory import AbstractVectorFactory from core.rag.embedding.embedding_base import Embeddings from core.rag.models.document import Document @@ -62,11 +63,12 @@ class PineconeVector(BaseVector): # Guard empty name if not self._index_name: self._index_name = f"index-{hashlib.sha256(collection_name.encode()).hexdigest()[:suffix_len]}" - self._index = None + # Pinecone index handle, lazily initialized + self._index: Optional[Any] = None def get_type(self) -> str: - """Return vector database type identifier""" - return "pinecone" + """Return vector database type identifier.""" + return VectorType.PINECONE def _ensure_index_initialized(self) -> None: """Ensure that self._index is attached to an existing Pinecone index.""" @@ -211,7 +213,9 @@ class PineconeVector(BaseVector): # Execute search try: - response = self._index.query( + index = self._index + assert index is not None + response = index.query( vector=query_vector, top_k=top_k, include_metadata=True, @@ -257,7 +261,9 @@ class PineconeVector(BaseVector): } # Pinecone delete operation - self._index.delete(filter=filter_dict) + index = self._index + assert index is not None + index.delete(filter=filter_dict) except Exception as e: # Ignore delete errors pass @@ -268,7 +274,9 @@ class PineconeVector(BaseVector): try: # Pinecone delete by ID - self._index.delete(ids=ids) + index = self._index + assert index is not None + index.delete(ids=ids) except Exception as e: raise @@ -279,7 +287,9 @@ class PineconeVector(BaseVector): try: # Delete all vectors by group_id filter_dict = {Field.GROUP_KEY.value: {"$eq": self._group_id}} - self._index.delete(filter=filter_dict) + index = self._index + assert index is not None + index.delete(filter=filter_dict) except Exception as e: raise @@ -292,7 +302,9 @@ class PineconeVector(BaseVector): try: # Check if vector exists through query - response = self._index.fetch(ids=[id]) + index = self._index + assert index is not None + response = index.fetch(ids=[id]) exists = id in response.vectors return exists except Exception as e: @@ -327,7 +339,7 @@ class PineconeVectorFactory(AbstractVectorFactory): # Set index structure if not dataset.index_struct_dict: dataset.index_struct = json.dumps( - self.gen_index_struct_dict("pinecone", collection_name) + self.gen_index_struct_dict(VectorType.PINECONE, collection_name) ) # Create PineconeVector instance diff --git a/docker/.env.example b/docker/.env.example index 07b4088470..4847f3a4cf 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -708,6 +708,16 @@ CLICKZETTA_ANALYZER_TYPE=chinese CLICKZETTA_ANALYZER_MODE=smart CLICKZETTA_VECTOR_DISTANCE_FUNCTION=cosine_distance +# Pinecone configuration, only available when VECTOR_STORE is `pinecone` +PINECONE_API_KEY=your-pinecone-api-key +PINECONE_ENVIRONMENT=your-pinecone-environment +PINECONE_INDEX_NAME=dify-index +PINECONE_CLIENT_TIMEOUT=30 +PINECONE_BATCH_SIZE=100 +PINECONE_METRIC=cosine +PINECONE_PODS=1 +PINECONE_POD_TYPE=s1 + # ------------------------------ # Knowledge Configuration # ------------------------------ diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index dc94883b75..6334b2daf4 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -322,6 +322,14 @@ x-shared-env: &shared-api-worker-env HUAWEI_CLOUD_PASSWORD: ${HUAWEI_CLOUD_PASSWORD:-admin} UPSTASH_VECTOR_URL: ${UPSTASH_VECTOR_URL:-https://xxx-vector.upstash.io} UPSTASH_VECTOR_TOKEN: ${UPSTASH_VECTOR_TOKEN:-dify} + PINECONE_API_KEY: ${PINECONE_API_KEY:-} + PINECONE_ENVIRONMENT: ${PINECONE_ENVIRONMENT:-} + PINECONE_INDEX_NAME: ${PINECONE_INDEX_NAME:-} + PINECONE_CLIENT_TIMEOUT: ${PINECONE_CLIENT_TIMEOUT:-30} + PINECONE_BATCH_SIZE: ${PINECONE_BATCH_SIZE:-100} + PINECONE_METRIC: ${PINECONE_METRIC:-cosine} + PINECONE_PODS: ${PINECONE_PODS:-1} + PINECONE_POD_TYPE: ${PINECONE_POD_TYPE:-s1} TABLESTORE_ENDPOINT: ${TABLESTORE_ENDPOINT:-https://instance-name.cn-hangzhou.ots.aliyuncs.com} TABLESTORE_INSTANCE_NAME: ${TABLESTORE_INSTANCE_NAME:-instance-name} TABLESTORE_ACCESS_KEY_ID: ${TABLESTORE_ACCESS_KEY_ID:-xxx}