هذا هو عميل Scala الكامل غير المتزامن لبرنامج Pinecone API يدعم جميع الفهرس المتاح والمتجه والتجميع والاستدلال وعمليات/نقاط النهاية ، المقدمة في خدمتين مناسبتين تسمى pineconeVectorService و PineconeIndexservice. المكالمات المدعومة هي:
PineconeAssistantService و PineconeAssistantFileService لاحظ أنه من أجل أن تكون متسقة مع تسمية Pinecone API ، تتطابق أسماء وظائف الخدمة مع عناوين/أوصاف نهاية API تمامًا مع Camelcase. أيضًا ، كنا نهدف إلى أن تكون LIB قائمة بذاتها مع عدد أقل من التبعيات الممكنة ، لذلك انتهى بنا المطاف باستخدام اثنين فقط من libs play-ahc-ws-standalone -ws play-ws-standalone-json (في المستوى الأعلى).
✔ مهم : هذه مكتبة "تم صيانتها" ، وعلى هذا النحو ، لا علاقة لها بشركة Pinecone.
تحقق من مقال عن lib/العميل على المتوسط. أيضًا ، إذا كنت ترغب في رؤية أمثلة عملية على الفور ، فانتقل إلى أمثلة Pinecone أو وحدات Openai + Pinecone.
إصدارات سكالا المدعومة حاليًا هي 2.12 و 2.13 و 3 .
لسحب المكتبة ، يجب عليك إضافة التبعية التالية إلى build.sbt
"io.cequence" %% "pinecone-scala-client" % "1.2.2"
أو إلى pom.xml (إذا كنت تستخدم Maven)
<dependency>
<groupId>io.cequence</groupId>
<artifactId>pinecone-scala-client_2.12</artifactId>
<version>1.2.2</version>
</dependency>
PINECONE_SCALA_CLIENT_API_KEY ، و PINECONE_SCALA_CLIENT_ENV إذا تم استخدام الخدمة المستندة إلى POD ia. الحصول على PineconeIndexService
تحتاج أولاً إلى توفير سياق تنفيذ ضمني وكذلك Akka Materializer ، على سبيل المثال ، على سبيل المثال
implicit val ec = ExecutionContext .global
implicit val materializer = Materializer ( ActorSystem ())بعد ذلك ، يمكنك الحصول على خدمة (POD أو قائمة على الخادم) بإحدى الطرق التالية.
Config ) import io . cequence . pineconescala . service . PineconeIndexServiceFactory . FactoryImplicits
val service = PineconeIndexServiceFactory ().asOne val config = ConfigFactory .load( " path_to_my_custom_config " )
val service = PineconeIndexServiceFactory (config).asOnePineconePodBasedIndexService val service = PineconeIndexServiceFactory (
apiKey = " your_api_key " ,
environment = " your_env " // e.g. "northamerica-northeast1-gcp
)PineconeServerlessIndexService val service = PineconeIndexServiceFactory (
apiKey = " your_api_key "
) IB. الحصول على PineconeVectorService
كما هو الحال مع PineconeIndexService ، تحتاج أولاً إلى توفير سياق تنفيذ ضمني ومواد Akka. ثم يمكنك الحصول على خدمة في واحدة من الطرق التالية.
Config ). لاحظ أنه إذا لم يكن الفهرس باسم معين غير متوفر ، فلن يعيد المصنع None . PineconeVectorServiceFactory ( " index_name " ).map { serviceOption =>
val service = serviceOption.getOrElse(
throw new Exception ( s " Index with a given name does not exist. " )
)
// do something with the service
} IC. الحصول على PineconeInferenceService
كما هو الحال مع PineconeIndexService ، تحتاج أولاً إلى توفير سياق تنفيذ ضمني ومواد Akka. ثم يمكنك الحصول على خدمة في واحدة من الطرق التالية.
val service = PineconeInferenceServiceFactory () val config = ConfigFactory .load( " path_to_my_custom_config " )
val service = PineconeInferenceServiceFactory (config) val service = PineconeInferenceServiceFactory (
apiKey = " your_api_key "
) بطاقة تعريف. الحصول على PineconeAssistantService
val service = PineconeAssistantServiceFactory () val config = ConfigFactory .load( " path_to_my_custom_config " )
val service = PineconeAssistantServiceFactory (config) val service = PineconeAssistantServiceFactory (
apiKey = " your_api "
) أي. الحصول على PineconeAssistantFileService
val service = PineconeAssistantFileServiceFactory () val config = ConfigFactory .load( " path_to_my_custom_config " )
val service = PineconeAssistantFileServiceFactory (config) val service = PineconeAssistantFileServiceFactory (
apiKey = " your_api "
)الثاني. وظائف الاتصال
يتم توفير وثائق كاملة لكل مكالمة مع مدخلاتها وإعداداتها في pineconeVectorService و pineconeIndexservice. نظرًا لأن جميع المكالمات غير متزامنة ، فإنها تعيد الردود ملفوفة في Future .
أمثلة:
عمليات الفهرس
pineconeIndexService.listIndexes.map(indexes =>
indexes.foreach(println)
) import io . cequence . pineconescala . domain . response . CreateResponse
pineconeIndexService.createIndex(
name = " auto-gpt-test " ,
dimension = 1536
).map {
case CreateResponse . Created => println( " Index successfully created. " )
case CreateResponse . BadRequest => println( " Index creation failed. Request exceeds quota or an invalid index name. " )
case CreateResponse . AlreadyExists => println( " Index with a given name already exists. " )
} pineconeIndexService.describeIndex( " index_name " ).map(indexInfo =>
// if not found, indexInfo will be None
println(indexInfo)
) import io . cequence . pineconescala . domain . response . DeleteResponse
pineconeIndexService.deleteIndex( " index_name " ).map {
case DeleteResponse . Deleted => println( " Index successfully deleted. " )
case DeleteResponse . NotFound => println( " Index with a given name not found. " )
} import io . cequence . pineconescala . domain . response . ConfigureIndexResponse
pineconeIndexService.configureIndex(
name = " index_name " ,
replicas = Some ( 2 ),
pod_type = Some ( PodType .p1_x2)
).map {
case ConfigureIndexResponse . Updated => println( " Index successfully updated. " )
case ConfigureIndexResponse . BadRequestNotEnoughQuota => println( " Index update failed. Not enough quota. " )
case ConfigureIndexResponse . NotFound => println( " Index with a given name not found. " )
}عمليات التجميع
pineconeIndexService.listCollections.map(collectionNames =>
println(collectionNames.mkString( " , " ))
) import io . cequence . pineconescala . domain . response . CreateResponse
pineconeIndexService.createCollection(
name = " collection_name " ,
source = " index_name "
).map {
case CreateResponse . Created => println( " Collection successfully created. " )
case CreateResponse . BadRequest => println( " Collection creation failed. Request exceeds quota or an invalid collection name. " )
case CreateResponse . AlreadyExists => println( " Collection with a given name already exists. " )
} pineconeIndexService.describeCollection( " collection_name " ).map(collectionInfo =>
// if not found, collectionInfo will be None
println(collectionInfo)
) import io . cequence . pineconescala . domain . response . DeleteResponse
pineconeIndexService.deleteCollection( " collection_name " ).map {
case DeleteResponse . Deleted => println( " Collection successfully deleted. " )
case DeleteResponse . NotFound => println( " Collection with a given name not found. " )
}عمليات المتجهات
val dimension = 1536
pineconeVectorService.upsert(
vectors = Seq (
PVector (
id = " 666 " ,
values = Seq .fill(dimension)( Random .nextDouble),
metadata = Map (
" is_relevant " -> " not really but for testing it's ok, you know " ,
" food_quality " -> " brunches are perfect but don't go there before closing time "
)
),
PVector (
id = " 777 " ,
values = Seq .fill(dimension)( Random .nextDouble),
metadata = Map (
" is_relevant " -> " very much so " ,
" food_quality " -> " burritos are the best! "
)
)
),
namespace = " my_namespace " ,
).map(vectorUpsertedCount =>
println( s " Upserted $vectorUpsertedCount vectors. " )
) val fetchedValues = ... // vectors fetched from somewhere
pineconeVectorService.update(
id = " 777 " ,
namespace = " my_namespace " ,
values = fetchedValues.map(_ / 100 ), // divide fetched values by 100
sparseValues = Some ( SparseVector (
indices = Seq ( 1 , 2 , 3 ),
values = Seq ( 8.8 , 7.7 , 2.2 )
)),
setMetaData = Map (
" solid_info " -> " this is the source of the truth "
)
).map(_ =>
println( s " Vectors updated. " )
) pineconeVectorService.query(
vector = Seq .fill( 1536 )( Random .nextDouble), // some values/embeddings
namespace = " my_namespace "
).map { queryResponse =>
queryResponse.matches.foreach { matchInfo =>
println( s " Matched vector id: ${matchInfo.id} " )
println( s " Matched vector values: ${matchInfo.values.take( 20 ).mkString( " , " )} .. " )
println( s " Matched vector score: ${matchInfo.score} " )
println( s " Matched vector metadata: ${matchInfo.metadata} " )
}
} pineconeVectorService.query(
vector = Seq .fill( 1536 )( Random .nextDouble), // some values/embeddings
namespace = " my_namespace " ,
settings = QuerySettings (
topK = 5 ,
includeValues = true ,
includeMetadata = true
)
).map { queryResponse =>
queryResponse.matches.foreach { matchInfo =>
println( s " Matched vector id: ${matchInfo.id} " )
println( s " Matched vector values: ${matchInfo.values.take( 20 ).mkString( " , " )} .. " )
println( s " Matched vector score: ${matchInfo.score} " )
println( s " Matched vector metadata: ${matchInfo.metadata} " )
}
} pineconeVectorService.fetch(
ids = Seq ( " 666 " , " 777 " ),
namespace = " my_namespace "
).map { fetchResponse =>
fetchResponse.vectors.values.map { pVector =>
println( s " Fetched vector id: ${pVector.id} " )
println( s " Fetched vector values: ${pVector.values.take( 20 ).mkString( " , " )} .. " )
println( s " Fetched vector metadata: ${pVector.metadata} " )
}
} pineconeVectorService.delete(
ids = Seq ( " 666 " , " 777 " ),
namespace = " my_namespace "
).map(_ =>
println( " Vectors deleted " )
) pineconeVectorService.deleteAll(
namespace = " my_namespace "
).map(_ =>
println( " All vectors deleted " )
) pineconeVectorService.describeIndexStats.map(stats =>
println(stats)
)عمليات الاستدلال
pineconeInferenceService.createEmbeddings(
Seq ( " The quick brown fox jumped over the lazy dog " )
).map { embeddings =>
println(embeddings.data.mkString( " n " ))
} pineconeInferenceService.rerank(
query = " The tech company Apple is known for its innovative products like the iPhone. " ,
documents = Seq (...)
).map(
_.data.foreach(println)
) pineconeInferenceService.evaluate(
question = " What are the capital cities of France, England and Spain? " ,
answer = " Paris is a city of France and Barcelona of Spain " ,
groundTruthAnswer = " Paris is the capital city of France, London of England and Madrid of Spain "
).map { response =>
println(response)
}** العمليات المساعدة **
pineconeAssistantService.listAssistants.map(assistants =>
println(assistants.mkString( " , " ))
) import io . cequence . pineconescala . domain . response . CreateResponse
pineconeAssistantService.createAssistant(
name = " assistant_name " ,
description = " assistant_description " ,
assistantType = " assistant_type "
).map {
case CreateResponse . Created => println( " Assistant successfully created. " )
case CreateResponse . BadRequest => println( " Assistant creation failed. Request exceeds quota or an invalid assistant name. " )
case CreateResponse . AlreadyExists => println( " Assistant with a given name already exists. " )
} pineconeAssistantService.describeAssistant( " assistant_name " ).map(assistant =>
// if not found, assistant will be None
println(assistant)
) import io . cequence . pineconescala . domain . response . DeleteResponse
pineconeAssistantService.deleteAssistant( " assistant_name " ).map {
case DeleteResponse . Deleted => println( " Assistant successfully deleted. " )
case DeleteResponse . NotFound => println( " Assistant with a given name not found. " )
} pineconeAssistantService.listFiles( " assistant_name " ).map(files =>
println(files.mkString( " , " ))
) import io . cequence . pineconescala . domain . response . CreateResponse
pineconeAssistantService.uploadFile(
assistantName = " assistant_name " ,
filePath = " path_to_file "
).map {
case CreateResponse . Created => println( " File successfully uploaded. " )
case CreateResponse . BadRequest => println( " File upload failed. Request exceeds quota or an invalid file path. " )
case CreateResponse . AlreadyExists => println( " File with a given name already exists. " )
} pineconeAssistantService.describeFile( " assistant_name " , " file_name " ).map(file =>
// if not found, file will be None
println(file)
) pineconeAssistantService.chatWithAssistant(
" assistant_name " ,
" What is the maximum height of a red pine? "
).map(response =>
println(response)
)للعروض التجريبية الجاهزة للتشغيل. الرجوع إلى وحدات منفصلة:
حصلت على استثناء مهلة. كيف يمكنني تغيير إعداد المهلة؟
يمكنك القيام بذلك إما عن طريق اجتياز timeouts param إلى Pinecone{Vector,Index}ServiceFactory أو ، إذا كنت تستخدم ملف التكوين الخاص بك ، فيمكنك ببساطة إضافته هناك على النحو التالي:
pinecone-scala-client {
timeouts {
requestTimeoutSec = 200
readTimeoutSec = 200
connectTimeoutSec = 5
pooledConnectionIdleTimeoutSec = 60
}
}
حصلت على استثناء مثل com.typesafe.config.ConfigException$UnresolvedSubstitution: pinecone-scala-client.conf @ jar:file:.../io/cequence/pinecone-scala-client_2.13/1.2.2/pinecone-scala-client_2.13-1.2.2.jar!/pinecone-scala-client.conf: 4: Could not resolve substitution to a value: ${PINECONE_SCALA_CLIENT_API_KEY} . ماذا علي أن أفعل؟
اضبط Env. متغير PINECONE_SCALA_CLIENT_API_KEY . إذا لم يكن لديك سجل واحد هنا.
كل شيء يبدو رائعا. أريد الدردشة معك حول بحثك وتطويرك؟
ما عليك سوى إطلاق النار علينا بريدًا إلكترونيًا في [email protected].
تتوفر هذه المكتبة ونشرها كمصدر مفتوح بموجب شروط ترخيص معهد ماساتشوستس للتكنولوجيا.
هذا المشروع مفتوح المصدر ويرحب بأي مساهمة أو ردود فعل (هنا).
تم دعم تطوير هذه المكتبة من قبل - cavenence.io - The future of contracting
تم إنشاؤها وصيانتها من قبل بيتر باندا.