LLPhant is a PHP library for building generative AI applications and working with vector databases. It supports Symfony and Laravel, but the package is not tied to either framework. You can use the same library with hosted models such as OpenAI and Anthropic, or local models through Ollama and LM Studio.

Here's what the package gives you:

  • Multiple model providers: OpenAI, Anthropic, Mistral, Ollama, LM Studio, Gemini, and OpenAI-compatible services such as LocalAI
  • Streaming responses: return generated text incrementally for chat interfaces
  • Tool calls: describe PHP methods to a model and let it request those methods with typed parameters
  • Embeddings: turn files and text into vectors with OpenAI, Mistral, Ollama, or VoyageAI
  • Vector stores: keep embeddings in memory, the filesystem, PostgreSQL, Redis, Elasticsearch, Qdrant, Chroma, MongoDB, and other stores
  • RAG helpers: split documents, retrieve relevant context, rerank results, and answer questions over private data
  • Guardrails and prompt-injection checks: retry invalid JSON, block responses, or reject malicious questions before retrieval
  • Typed classification: use JevClassifier for yes/no, choice, and rubric-based score results

One API for Different Models

LLPhant gives each provider its own chat and configuration classes, while keeping the calling code close to the same shape. OpenAI is the default path in the documentation:

use LLPhant\Chat\OpenAIChat;

$chat = new OpenAIChat();
$response = $chat->generateText('What is one plus one?');

Set OPENAI_API_KEY in the environment, or pass an OpenAIConfig object when the application needs to provide the key and model itself. The package also has MistralAIChat, OllamaChat, and AnthropicChat classes. Ollama can point at a local model such as Llama 2, while OpenAI-compatible endpoints can use a custom base URL.

The chat classes can stream generated text, accept a conversation as an array of messages, and track token usage. That last part matters when an application needs to show or record the tokens consumed by a request.

Turn Documents into Searchable Context

LLPhant's embedding pipeline reads text from files, PDFs, and Word documents, splits it into chunks, generates vectors, and stores them for similarity search. The built-in FileDataReader can read a file or directory, while DocumentSplitter keeps chunks within the model's input limit:

use LLPhant\Embeddings\DocumentSplitter\DocumentSplitter;
use LLPhant\Embeddings\EmbeddingGenerator\OpenAI\OpenAI3SmallEmbeddingGenerator;
use LLPhant\Embeddings\VectorStores\Memory\MemoryVectorStore;
use LLPhant\Embeddings\DataReader\FileDataReader;

$reader = new FileDataReader(__DIR__.'/private-data.txt');
$documents = $reader->getDocuments();
$chunks = DocumentSplitter::splitDocuments($documents, 500);

$generator = new OpenAI3SmallEmbeddingGenerator();
$embedded = $generator->embedDocuments($chunks);

$store = new MemoryVectorStore();
$store->addDocuments($embedded);

The memory store is useful for a small application or a test. Production applications can use a database or service-backed store instead. The package lists adapters for Doctrine with PostgreSQL or MariaDB, Redis, Elasticsearch, Qdrant, Milvus, ChromaDB, AstraDB, OpenSearch, Typesense, and MongoDB. Most of those are optional Composer dependencies rather than requirements for every installation. For a focused in-process alternative, ext-turbovec keeps quantized vectors in a PHP extension without a separate vector database.

Ask Questions Over Private Data

Once the store contains embeddings, QuestionAnswering retrieves relevant documents and sends them to a chat model as context:

use LLPhant\Chat\OpenAIChat;
use LLPhant\Query\SemanticSearch\QuestionAnswering;

$qa = new QuestionAnswering(
    $store,
    $generator,
    new OpenAIChat(),
);

$answer = $qa->answerQuestion('What is the secret of Alice?');

The question-answering layer supports multi-query transformations, reranking, and small-to-big retrieval. A ChatSession can preserve context between questions, and the package can pass tool results into the conversation when an answer needs to call an external service.

LLPhant also includes a prompt-injection query transformer backed by its Jev classifier integration. It can reject a question with a SecurityException when the malicious score reaches a configured threshold. Lakera is available as another prompt-injection transformer.

Check and Classify Model Output

Guardrails run evaluators after a model response. An evaluator can check JSON syntax or look for a fallback answer, then retry the request, block it, or call application code:

use LLPhant\Chat\OpenAIChat;
use LLPhant\Evaluation\Guardrails\GuardrailStrategy;
use LLPhant\Evaluation\Guardrails\Guardrails;
use LLPhant\Evaluation\Output\JSONFormatEvaluator;

$guardrails = new Guardrails(llm: new OpenAIChat());
$guardrails->addStrategy(
    new JSONFormatEvaluator(),
    GuardrailStrategy::STRATEGY_RETRY,
);

$response = $guardrails->generateText(
    'Return a JSON object with correctKey and correctVal.',
);

For structured classification, JevClassifier defines typed questions rather than asking the application to parse free-form text. It supports binary NoulType questions, ChoiceType labels, and ScoreType rubrics with probabilities, confidence, and token usage in the returned answer objects.

Install It With Composer

LLPhant requires PHP 8.1 or newer:

composer require theodo-group/llphant

The package requires the GD extension by default through its Composer platform configuration. If that extension is not part of the PHP installation, the project documents --ignore-platform-req=ext-gd as an alternative. Provider-specific vector stores add their own optional dependencies, such as predis/predis for Redis or doctrine/orm for Doctrine.

Read the LLPhant documentation for the provider matrix and the source on GitHub. The package is available on Packagist.