Skip to content
This repository was archived by the owner on Jul 16, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ OPENAI_API_KEY=
# For using Claude on Anthropic
ANTHROPIC_API_KEY=

# For using Voyage
VOYAGE_API_KEY=

# For using GPT on Azure
AZURE_OPENAI_BASEURL=
AZURE_OPENAI_DEPLOYMENT=
Expand Down
34 changes: 25 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,17 @@ Currently supported models and platforms:
| Vendor | Model | Platform |
|----------------|------------------------|----------------------|
| **OpenAI** | - GPT<br/>- Embeddings | - OpenAI<br/>- Azure |
| **Anthropic** | - Claude | - Anthropic |
| **Anthropic** | - Claude | - Anthropic |
| **Voyage** | - Voyage | - Voyage |

Planned Models & Platforms (not implemented yet):

| Vendor | Model | Platform |
|----------------|------------------------|----------------------------------|
| **Anthropic** | - Voyage | - GPC<br/>- AWS |
| **Google** | - Gemini<br/>- Gemma | - GPC |
| **Meta** | - Llama | - Meta AI<br/>- GPC<br/>- Ollama |
| Vendor | Model | Platform |
|----------------|---------------------------|----------------------------------|
| **Anthropic** | - Claude | - GPC<br/>- AWS |
| **Voyage** | - Voyage | - AWS |
| **Google** | - Gemini<br/>- Gemma | - GPC |
| **Meta** | - Llama | - Meta AI<br/>- GPC<br/>- Ollama |
| **Mistral AI** | - Mistral<br/>- Codestral | - Mistral<br/>- GPT<br/>- Ollama |

Supported Stores
Expand Down Expand Up @@ -72,13 +74,13 @@ To run all examples, just use `make run-all-examples`.

### Chat Examples

1. Chat Example: OpenAI's GPT
1. OpenAI's GPT
```bash
export OPENAI_API_KEY=sk-...
php examples/chat-gpt-openai.php
```

1. Chat Example: OpenAI's GPT With Azure
1. OpenAI's GPT with Azure
```bash
export AZURE_OPENAI_BASEURL=... // e.g. your-resource.openai.azure.com
export AZURE_OPENAI_DEPLOYMENT=...
Expand All @@ -87,12 +89,26 @@ To run all examples, just use `make run-all-examples`.
php examples/chat-gpt-azure.php
```

1. Chat Example: Anthropic's Claude
1. Anthropic's Claude
```bash
export ANTHROPIC_API_KEY=sk-...
php examples/chat-claude-anthropic.php
```

### Embeddings Examples

1. OpenAI's Emebddings
```bash
export OPENAI_API_KEY=sk-...
php examples/embeddings-openai.php
```

1. Voyage's Embeddings
```bash
export VOYAGE_API_KEY=sk-...
php examples/embeddings-voyage.php
```

### Tool Examples

1. Simple Clock Tool
Expand Down
21 changes: 21 additions & 0 deletions examples/embeddings-openai.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

use PhpLlm\LlmChain\OpenAI\Model\Embeddings;
use PhpLlm\LlmChain\OpenAI\Model\Embeddings\Version;
use PhpLlm\LlmChain\OpenAI\Platform\OpenAI;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\HttpClient\HttpClient;

require_once dirname(__DIR__).'/vendor/autoload.php';
(new Dotenv())->loadEnv(dirname(__DIR__).'/.env');

$platform = new OpenAI(HttpClient::create(), $_ENV['OPENAI_API_KEY']);
$embeddings = new Embeddings($platform, Version::textEmbedding3Small());

$vector = $embeddings->create(<<<TEXT
Once upon a time, there was a country called Japan. It was a beautiful country with a lot of mountains and rivers.
The people of Japan were very kind and hardworking. They loved their country very much and took care of it. The
country was very peaceful and prosperous. The people lived happily ever after.
TEXT);

echo $vector->getDimensions().PHP_EOL;
20 changes: 20 additions & 0 deletions examples/embeddings-voyage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

use PhpLlm\LlmChain\Voyage\Model\Voyage;
use PhpLlm\LlmChain\Voyage\Platform\Voyage as VoyagePlatform;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\HttpClient\HttpClient;

require_once dirname(__DIR__).'/vendor/autoload.php';
(new Dotenv())->loadEnv(dirname(__DIR__).'/.env');

$platform = new VoyagePlatform(HttpClient::create(), $_ENV['VOYAGE_API_KEY']);
$embeddings = new Voyage($platform);

$vector = $embeddings->create(<<<TEXT
Once upon a time, there was a country called Japan. It was a beautiful country with a lot of mountains and rivers.
The people of Japan were very kind and hardworking. They loved their country very much and took care of it. The
country was very peaceful and prosperous. The people lived happily ever after.
TEXT);

echo $vector->getDimensions().PHP_EOL;
10 changes: 5 additions & 5 deletions src/Anthropic/Model/Claude.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

namespace PhpLlm\LlmChain\Anthropic\Model;

use PhpLlm\LlmChain\Anthropic\ClaudePlatform;
use PhpLlm\LlmChain\Anthropic\Model\Claude\Version;
use PhpLlm\LlmChain\Anthropic\Platform;
use PhpLlm\LlmChain\LanguageModel;
use PhpLlm\LlmChain\Message\MessageBag;
use PhpLlm\LlmChain\Response\Choice;
Expand All @@ -14,19 +14,19 @@
final class Claude implements LanguageModel
{
/**
* @param array<mixed> $options The default options for the model usage
* @param array<string, mixed> $options The default options for the model usage
*/
public function __construct(
private readonly ClaudePlatform $platform,
private readonly Platform $platform,
private ?Version $version = null,
private readonly array $options = ['temperature' => 1.0, 'max_tokens' => 1000],
) {
$this->version ??= Version::sonnet35();
}

/**
* @param array<mixed> $options The options to be used for this specific call.
* Can overwrite default options.
* @param array<string, mixed> $options The options to be used for this specific call.
* Can overwrite default options.
*/
public function call(MessageBag $messages, array $options = []): Response
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace PhpLlm\LlmChain\Anthropic;

interface ClaudePlatform
interface Platform
{
/**
* @param array<string, mixed> $body
Expand Down
4 changes: 2 additions & 2 deletions src/Anthropic/Platform/Anthropic.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

namespace PhpLlm\LlmChain\Anthropic\Platform;

use PhpLlm\LlmChain\Anthropic\ClaudePlatform;
use PhpLlm\LlmChain\Anthropic\Platform;
use Symfony\Contracts\HttpClient\HttpClientInterface;

final readonly class Anthropic implements ClaudePlatform
final readonly class Anthropic implements Platform
{
public function __construct(
private HttpClientInterface $httpClient,
Expand Down
2 changes: 1 addition & 1 deletion src/DocumentEmbedder.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
final readonly class DocumentEmbedder
{
public function __construct(
private EmbeddingModel $embeddings,
private EmbeddingsModel $embeddings,
private StoreInterface $store,
) {
}
Expand Down
19 changes: 0 additions & 19 deletions src/EmbeddingModel.php

This file was deleted.

23 changes: 23 additions & 0 deletions src/EmbeddingsModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace PhpLlm\LlmChain;

use PhpLlm\LlmChain\Document\Vector;

interface EmbeddingsModel
{
/**
* @param array<string, mixed> $options
*/
public function create(string $text, array $options = []): Vector;

/**
* @param list<string> $texts
* @param array<string, mixed> $options
*
* @return Vector[]
*/
public function multiCreate(array $texts, array $options = []): array;
}
8 changes: 4 additions & 4 deletions src/OpenAI/Model/Embeddings.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
namespace PhpLlm\LlmChain\OpenAI\Model;

use PhpLlm\LlmChain\Document\Vector;
use PhpLlm\LlmChain\EmbeddingModel;
use PhpLlm\LlmChain\EmbeddingsModel;
use PhpLlm\LlmChain\OpenAI\Model\Embeddings\Version;
use PhpLlm\LlmChain\OpenAI\Platform;

final class Embeddings implements EmbeddingModel
final class Embeddings implements EmbeddingsModel
{
public function __construct(
private readonly Platform $platform,
Expand All @@ -18,14 +18,14 @@ public function __construct(
$this->version ??= Version::textEmbedding3Small();
}

public function create(string $text): Vector
public function create(string $text, array $options = []): Vector
{
$response = $this->platform->request('embeddings', $this->createBody($text));

return $this->extractVector($response);
}

public function multiCreate(array $texts): array
public function multiCreate(array $texts, array $options = []): array
{
$bodies = array_map([$this, 'createBody'], $texts);

Expand Down
4 changes: 2 additions & 2 deletions src/ToolBox/Tool/SimilaritySearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace PhpLlm\LlmChain\ToolBox\Tool;

use PhpLlm\LlmChain\Document\Document;
use PhpLlm\LlmChain\EmbeddingModel;
use PhpLlm\LlmChain\EmbeddingsModel;
use PhpLlm\LlmChain\Store\VectorStoreInterface;
use PhpLlm\LlmChain\ToolBox\AsTool;

Expand All @@ -18,7 +18,7 @@ final class SimilaritySearch
public array $usedDocuments = [];

public function __construct(
private readonly EmbeddingModel $embeddings,
private readonly EmbeddingsModel $embeddings,
private readonly VectorStoreInterface $vectorStore,
) {
}
Expand Down
37 changes: 37 additions & 0 deletions src/Voyage/Model/Voyage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace PhpLlm\LlmChain\Voyage\Model;

use PhpLlm\LlmChain\Document\Vector;
use PhpLlm\LlmChain\EmbeddingsModel;
use PhpLlm\LlmChain\Voyage\Model\Voyage\Version;
use PhpLlm\LlmChain\Voyage\Platform;

final class Voyage implements EmbeddingsModel
{
public function __construct(
private readonly Platform $platform,
private ?Version $version = null,
) {
$this->version ??= Version::v3();
}

public function create(string $text, array $options = []): Vector
{
$vectors = $this->multiCreate([$text], $options);

return $vectors[0];
}

public function multiCreate(array $texts, array $options = []): array
{
$response = $this->platform->request(array_merge($options, [
'model' => $this->version->name,
'input' => $texts,
]));

return array_map(fn (array $data) => new Vector($data['embedding']), $response['data']);
}
}
46 changes: 46 additions & 0 deletions src/Voyage/Model/Voyage/Version.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace PhpLlm\LlmChain\Voyage\Model\Voyage;

use Webmozart\Assert\Assert;

final readonly class Version
{
public function __construct(
public string $name,
) {
Assert::stringNotEmpty($name);
}

public static function v3(): self
{
return new self('voyage-3');
}

public static function v3lite(): self
{
return new self('voyage-3-lite');
}

public static function finance2(): self
{
return new self('voyage-finance-2');
}

public static function multilingual2(): self
{
return new self('voyage-multilingual-2');
}

public static function law2(): self
{
return new self('voyage-law-2');
}

public static function code2(): self
{
return new self('voyage-code-2');
}
}
15 changes: 15 additions & 0 deletions src/Voyage/Platform.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace PhpLlm\LlmChain\Voyage;

interface Platform
{
/**
* @param array<string, mixed> $body
*
* @return array<string, mixed>
*/
public function request(array $body): array;
}
Loading