Using custom LLM driver
Overview¶
You can register and use your own LLM driver, either using a new driver name or overriding an existing driver bundled with Polyglot.
Example¶
<?php
require 'examples/boot.php';
use Cognesy\Config\Env;
use Cognesy\Http\Data\HttpRequest;
use Cognesy\Http\Data\HttpResponse;
use Cognesy\Messages\Messages;
use Cognesy\Polyglot\Inference\Config\LLMConfig;
use Cognesy\Polyglot\Inference\Creation\BundledInferenceDrivers;
use Cognesy\Polyglot\Inference\Drivers\InferenceDriverSpec;
use Cognesy\Polyglot\Inference\Drivers\OpenAI\OpenAIBodyFormat;
use Cognesy\Polyglot\Inference\Drivers\SpecifiedInferenceDriver;
use Cognesy\Polyglot\Inference\Inference;
use Cognesy\Polyglot\Inference\InferenceRuntime;
use Cognesy\Utils\Str;
// A provider that speaks the OpenAI wire protocol needs no driver class of its own -- an
// InferenceDriverSpec names the pieces and the runtime assembles them. To change *behaviour*
// rather than composition, subclass SpecifiedInferenceDriver and name it in the spec.
final class EchoingDriver extends SpecifiedInferenceDriver
{
#[\Override]
protected function makeHttpResponse(HttpRequest $request): HttpResponse
{
// some extra functionality to demonstrate our driver is being used
echo ">>> Handling request...\n";
return parent::makeHttpResponse($request);
}
}
$drivers = BundledInferenceDrivers::registry()->withDriver(
name: 'custom-driver',
driver: new InferenceDriverSpec(
bodyFormat: OpenAIBodyFormat::class,
driverClass: EchoingDriver::class,
),
);
// withDriver() still accepts a class-string or a closure, exactly as before -- a spec is a
// third option, not a replacement:
//
// driver: fn($config, $httpClient, $events) => new MyDriver($config, $httpClient, $events),
// driver: MyDriver::class,
// Create instance of LLM client initialized with custom parameters
$config = new LLMConfig(
apiUrl : 'https://api.openai.com/v1',
apiKey : (string) Env::get('OPENAI_API_KEY', ''),
endpoint : '/chat/completions', model: 'gpt-4o-mini', maxTokens: 128,
driver : 'custom-driver',
);
$answer = Inference::fromRuntime(InferenceRuntime::fromConfig($config, drivers: $drivers))
->withMessages(Messages::fromString('What is the capital of France'))
->withOptions(['max_tokens' => 64])
->get();
echo "USER: What is capital of France\n";
echo "ASSISTANT: $answer\n";
assert(Str::contains($answer, 'Paris'));
?>