diff --git a/.env b/.env index 2f47495e..417bed73 100644 --- a/.env +++ b/.env @@ -20,3 +20,7 @@ SERP_API_KEY= # For using MongoDB Atlas (store) MONGODB_URI= + +# For using Pinecone (store) +PINECONE_API_KEY= +PINECONE_HOST= diff --git a/examples/store-pinecone-similarity-search.php b/examples/store-pinecone-similarity-search.php new file mode 100755 index 00000000..54c22973 --- /dev/null +++ b/examples/store-pinecone-similarity-search.php @@ -0,0 +1,68 @@ +loadEnv(dirname(__DIR__).'/.env'); + +if (empty($_ENV['OPENAI_API_KEY']) || empty($_ENV['PINECONE_API_KEY']) || empty($_ENV['PINECONE_HOST'])) { + echo 'Please set OPENAI_API_KEY, PINECONE_API_KEY and PINECONE_HOST environment variables.'.PHP_EOL; + exit(1); +} + +// initialize the store +$store = new Store(Pinecone::client($_ENV['PINECONE_API_KEY'], $_ENV['PINECONE_HOST'])); + +// our data +$movies = [ + ['title' => 'Inception', 'description' => 'A skilled thief is given a chance at redemption if he can successfully perform inception, the act of planting an idea in someone\'s subconscious.', 'director' => 'Christopher Nolan'], + ['title' => 'The Matrix', 'description' => 'A hacker discovers the world he lives in is a simulated reality and joins a rebellion to overthrow its controllers.', 'director' => 'The Wachowskis'], + ['title' => 'The Godfather', 'description' => 'The aging patriarch of an organized crime dynasty transfers control of his empire to his reluctant son.', 'director' => 'Francis Ford Coppola'], +]; + +// create embeddings and documents +foreach ($movies as $movie) { + $documents[] = Document::fromText( + id: Uuid::v4(), + text: 'Title: '.$movie['title'].PHP_EOL.'Director: '.$movie['director'].PHP_EOL.$movie['description'], + metadata: new Metadata($movie), + ); +} + +// create embeddings for documents +$platform = new OpenAI(HttpClient::create(), $_ENV['OPENAI_API_KEY']); +$embedder = new DocumentEmbedder($embeddings = new Embeddings($platform), $store); +$embedder->embed($documents); + +$llm = new Gpt($platform, Version::gpt4oMini()); + +$similaritySearch = new SimilaritySearch($embeddings, $store); +$toolBox = new ToolBox(new ToolAnalyzer(), [$similaritySearch]); +$processor = new ChainProcessor($toolBox); +$chain = new Chain($llm, [$processor], [$processor]); + +$messages = new MessageBag( + Message::forSystem('Please answer all user questions only using SimilaritySearch function.'), + Message::ofUser('Which movie fits the theme of the mafia?') +); +$response = $chain->call($messages); + +echo $response.PHP_EOL; diff --git a/src/Store/Pinecone/Store.php b/src/Store/Pinecone/Store.php index df59d8ba..47329035 100644 --- a/src/Store/Pinecone/Store.php +++ b/src/Store/Pinecone/Store.php @@ -11,6 +11,7 @@ use Probots\Pinecone\Client; use Probots\Pinecone\Resources\Data\VectorResource; use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; use Symfony\Component\Uid\Uuid; final readonly class Store implements VectorStoreInterface @@ -20,7 +21,7 @@ */ public function __construct( private Client $pinecone, - private LoggerInterface $logger, + private LoggerInterface $logger = new NullLogger(), private ?string $namespace = null, private array $filter = [], private int $topK = 3,