Fix outdated code references across documentation

- Fix class names: CachedPlatform→CachePlatform, OllamaApiCatalog→ModelCatalog,
  Indexer→DocumentIndexer/SourceIndexer, Store\Vector→Platform\Vector\Vector
- Fix namespaces: TokenUsage, MemoryInputProcessor, ConfiguredSourceIndexer,
  SourceIndexer, DocumentIndexer, StructuredOutputSerializer
- Fix method calls: asText()→getContent(), private property access→getters
- Fix API signatures: StoreInterface::query() now requires QueryInterface,
  ChromaDb\Store constructor updated, Ollama PlatformFactory simplified
- Remove unused imports: Gpt, Embeddings, VertexAi Model
- Fix incorrect file reference: _model-listing.php→_model.php
- Fix incorrect link target: Crawler Tool→firecrawl-crawl.php
- Fix MessageBagInterface→MessageBag (interface doesn't exist)
This commit is contained in:
Christopher Hertel
2026-03-20 13:58:41 +01:00
parent 9dab2aeafb
commit 17eaefb768
12 changed files with 60 additions and 72 deletions

View File

@@ -104,7 +104,7 @@ AI Bundle
+$container->get('ai.toolbox.my_agent.subagent.research_agent');
```
* An indexer configured with a `source`, now wraps the indexer with a `Symfony\AI\Store\ConfiguredSourceIndexer` decorator. This is
* An indexer configured with a `source`, now wraps the indexer with a `Symfony\AI\Store\Indexer\ConfiguredSourceIndexer` decorator. This is
transparent - the configured source is still used by default, but can be overridden by passing a source to `index()`.
* The `host_url` parameter for `Ollama` platform has been renamed `endpoint`.
@@ -120,12 +120,12 @@ Store
-----
* The `Symfony\AI\Store\Indexer` class has been replaced with two specialized implementations:
- `Symfony\AI\Store\SourceIndexer`: For indexing from sources (file paths, URLs, etc.) using a `LoaderInterface`
- `Symfony\AI\Store\DocumentIndexer`: For indexing documents directly without a loader
- `Symfony\AI\Store\Indexer\SourceIndexer`: For indexing from sources (file paths, URLs, etc.) using a `LoaderInterface`
- `Symfony\AI\Store\Indexer\DocumentIndexer`: For indexing documents directly without a loader
```diff
-use Symfony\AI\Store\Indexer;
+use Symfony\AI\Store\SourceIndexer;
+use Symfony\AI\Store\Indexer\SourceIndexer;
-$indexer = new Indexer($loader, $vectorizer, $store, '/path/to/source');
-$indexer->index();
@@ -143,11 +143,11 @@ Store
$indexer->index([$document1, $document2]);
```
* The `Symfony\AI\Store\ConfiguredIndexer` class has been renamed to `Symfony\AI\Store\ConfiguredSourceIndexer`:
* The `Symfony\AI\Store\ConfiguredIndexer` class has been renamed to `Symfony\AI\Store\Indexer\ConfiguredSourceIndexer`:
```diff
-use Symfony\AI\Store\ConfiguredIndexer;
+use Symfony\AI\Store\ConfiguredSourceIndexer;
+use Symfony\AI\Store\Indexer\ConfiguredSourceIndexer;
-$indexer = new ConfiguredIndexer($innerIndexer, 'default-source');
+$indexer = new ConfiguredSourceIndexer($sourceIndexer, 'default-source');
@@ -260,7 +260,7 @@ Platform
* Run `composer require symfony/ai-cache-platform`
* Change `Symfony\AI\Platform\CachedPlatform` namespace usages to `Symfony\AI\Platform\Bridge\Cache\CachePlatform`
* The `ttl` option can be used in the configuration
* Adopt usage of class `Symfony\AI\Platform\Serializer\StructuredOuputSerializer` to `Symfony\AI\Platform\StructuredOutput\Serializer`
* Adopt usage of class `Symfony\AI\Platform\Serializer\StructuredOutputSerializer` to `Symfony\AI\Platform\StructuredOutput\Serializer`
UPGRADE FROM 0.1 to 0.2
=======================
@@ -285,7 +285,7 @@ Agent
* Constructor of `MemoryInputProcessor` now accepts an iterable of inputs instead of variadic arguments.
```php
use Symfony\AI\Agent\InputProcessor\MemoryInputProcessor;
use Symfony\AI\Agent\Memory\MemoryInputProcessor;
// Before
$processor = new MemoryInputProcessor($input1, $input2);

View File

@@ -798,7 +798,7 @@ Use the :class:`Symfony\\AI\\Agent\\Agent` service to leverage models and tools:
Message::ofUser($message),
);
return $this->agent->call($messages)->asText();
return $this->agent->call($messages)->getContent();
}
}
@@ -943,7 +943,7 @@ The token usage information can be accessed from the result metadata::
use Symfony\AI\Agent\AgentInterface;
use Symfony\AI\Platform\Message\Message;
use Symfony\AI\Platform\Message\MessageBag;
use Symfony\AI\Platform\Result\Metadata\TokenUsage\TokenUsage;
use Symfony\AI\Platform\TokenUsage\TokenUsage;
final readonly class MyService
{

View File

@@ -16,10 +16,9 @@ Basic Usage
-----------
To instantiate an agent, you need to pass a :class:`Symfony\\AI\\Platform\\PlatformInterface` and a
:class:`Symfony\\AI\\Platform\\Model` instance to the :class:`Symfony\\AI\\Agent\\Agent` class::
model name to the :class:`Symfony\\AI\\Agent\\Agent` class::
use Symfony\AI\Agent\Agent;
use Symfony\AI\Platform\Bridge\OpenAi\Gpt;
use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory;
$platform = PlatformFactory::create($apiKey);
@@ -27,7 +26,7 @@ To instantiate an agent, you need to pass a :class:`Symfony\\AI\\Platform\\Platf
$agent = new Agent($platform, $model);
You can then run the agent with a :class:`Symfony\\AI\\Platform\\Message\\MessageBagInterface` instance as input and an optional
You can then run the agent with a :class:`Symfony\\AI\\Platform\\Message\\MessageBag` instance as input and an optional
array of options::
use Symfony\AI\Agent\Agent;
@@ -780,7 +779,7 @@ Code Examples
.. _`Anthropic Toolbox Example`: https://github.com/symfony/ai/blob/main/examples/anthropic/toolcall.php
.. _`Brave Tool`: https://github.com/symfony/ai/blob/main/examples/toolbox/brave.php
.. _`Clock Tool`: https://github.com/symfony/ai/blob/main/examples/toolbox/clock.php
.. _`Crawler Tool`: https://github.com/symfony/ai/blob/main/examples/toolbox/brave.php
.. _`Crawler Tool`: https://github.com/symfony/ai/blob/main/examples/toolbox/firecrawl-crawl.php
.. _`Mapbox Geocode Tool`: https://github.com/symfony/ai/blob/main/examples/toolbox/mapbox-geocode.php
.. _`Mapbox Reverse Geocode Tool`: https://github.com/symfony/ai/blob/main/examples/toolbox/mapbox-reverse-geocode.php
.. _`SerpAPI Tool`: https://github.com/symfony/ai/blob/main/examples/toolbox/serpapi.php

View File

@@ -20,7 +20,6 @@ with a ``Symfony\AI\Agent\AgentInterface`` and a ``Symfony\AI\Chat\MessageStoreI
use Symfony\AI\Agent\Agent;
use Symfony\AI\Chat\Chat;
use Symfony\AI\Chat\InMemory\Store as InMemoryStore;
use Symfony\AI\Platform\Bridge\OpenAi\Gpt;
use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory;
use Symfony\AI\Platform\Message\Message;

View File

@@ -28,8 +28,6 @@ OpenAI, Anthropic, Google, Replicate, and others.
For example, to use the OpenAI provider, you would typically do something like this::
use Symfony\AI\Platform\Bridge\OpenAi\Embeddings;
use Symfony\AI\Platform\Bridge\OpenAi\Gpt;
use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory;
$platform = PlatformFactory::create(env('OPENAI_API_KEY'));
@@ -37,7 +35,7 @@ For example, to use the OpenAI provider, you would typically do something like t
With this :class:`Symfony\\AI\\Platform\\PlatformInterface` instance you can now interact with the LLM::
// Generate a vector embedding for a text, returns a Symfony\AI\Platform\Result\VectorResult
$vectorResult = $platform->invoke($embeddings, 'What is the capital of France?');
$vectorResult = $platform->invoke('text-embedding-3-small', 'What is the capital of France?');
// Generate a text completion with GPT, returns a Symfony\AI\Platform\Result\TextResult
$result = $platform->invoke('gpt-4o-mini', new MessageBag(Message::ofUser('What is the capital of France?')));
@@ -81,30 +79,18 @@ Custom models
~~~~~~~~~~~~~
For providers like Ollama, you can use custom models (built on top of ``Modelfile``), as those models are not listed in
the default catalog, you can use the built-in ``OllamaApiCatalog`` to query the model information from the API rather
than the default catalog::
the default catalog. The ``ModelCatalog`` automatically queries the model information from the Ollama API::
use Symfony\AI\Platform\Bridge\Ollama\OllamaApiCatalog;
use Symfony\AI\Platform\Bridge\Ollama\PlatformFactory;
use Symfony\AI\Platform\Message\Message;
use Symfony\AI\Platform\Message\MessageBag;
$platform = PlatformFactory::create('http://127.0.0.1:11434', HttpClient::create(), new OllamaApiCatalog(
'http://127.0.0.1:11434',
HttpClient::create(),
));
$platform = PlatformFactory::create('http://127.0.0.1:11434');
$platform->invoke('your_custom_model_name', new MessageBag(
Message::ofUser(...)
));
When using the bundle, the usage of ``OllamaApiCatalog`` is available via the ``api_catalog`` option::
ai:
platform:
ollama:
api_catalog: true
Supported Models & Platforms
----------------------------
@@ -131,7 +117,7 @@ Supported Models & Platforms
* `OpenAI's Whisper`_ with `OpenAI`_ and `Azure`_ as Platform
* `LM Studio Catalog`_ and `HuggingFace`_ Models with `LM Studio`_ as Platform.
* All models provided by `HuggingFace`_ can be listed with a command in the examples folder,
and also filtered, e.g. ``php examples/huggingface/_model-listing.php --provider=hf-inference --task=object-detection``
and also filtered, e.g. ``php examples/huggingface/_model.php --provider=hf-inference --task=object-detection``
* **Voice Models**
* `ElevenLabs TTS`_ with `ElevenLabs`_ as Platform
* `ElevenLabs STT`_ with `ElevenLabs`_ as Platform
@@ -556,7 +542,7 @@ Embeddings
Creating embeddings of word, sentences, or paragraphs is a typical use case around the interaction with LLMs.
The standalone usage results in a :class:`Symfony\\AI\\Store\\Vector` instance::
The standalone usage results in a :class:`Symfony\\AI\\Platform\\Vector\\Vector` instance::
use Symfony\AI\Platform\Bridge\OpenAi\Embeddings;
@@ -677,7 +663,7 @@ Cached Platform Calls
Thanks to Symfony's Cache component, platform calls can be cached to reduce calls and resources consumption::
use Symfony\AI\Agent\Agent;
use Symfony\AI\Platform\Bridge\Cache\CachedPlatform;
use Symfony\AI\Platform\Bridge\Cache\CachePlatform;
use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory;
use Symfony\AI\Platform\Message\Message;
use Symfony\AI\Platform\Message\MessageBag;
@@ -686,13 +672,13 @@ Thanks to Symfony's Cache component, platform calls can be cached to reduce call
use Symfony\Component\HttpClient\HttpClient;
$platform = PlatformFactory::create($apiKey, HttpClient::create());
$cachedPlatform = new CachedPlatform($platform, cache: new TagAwareAdapter(new ArrayAdapter()));
$cachePlatform = new CachePlatform($platform, cache: new TagAwareAdapter(new ArrayAdapter()));
$firstResult = $cachedPlatform->invoke('gpt-4o-mini', new MessageBag(Message::ofUser('What is the capital of France?')));
$firstResult = $cachePlatform->invoke('gpt-4o-mini', new MessageBag(Message::ofUser('What is the capital of France?')));
echo $firstResult->getContent().\PHP_EOL;
$secondResult = $cachedPlatform->invoke('gpt-4o-mini', new MessageBag(Message::ofUser('What is the capital of France?')));
$secondResult = $cachePlatform->invoke('gpt-4o-mini', new MessageBag(Message::ofUser('What is the capital of France?')));
echo $secondResult->getContent().\PHP_EOL;

View File

@@ -46,7 +46,6 @@ Configure your Google Cloud project and location:
Basic usage example::
use Symfony\AI\Platform\Bridge\VertexAi\Gemini\Model;
use Symfony\AI\Platform\Bridge\VertexAi\PlatformFactory;
use Symfony\AI\Platform\Message\Message;
use Symfony\AI\Platform\Message\MessageBag;

View File

@@ -22,15 +22,18 @@ for documents.
Indexing
--------
One higher level feature is the :class:`Symfony\\AI\\Store\\Indexer`. The purpose of this service is to populate a store with documents.
One higher level feature is the :class:`Symfony\\AI\\Store\\Indexer\\DocumentIndexer`. The purpose of this service is to populate a store with documents.
Therefore it accepts one or multiple :class:`Symfony\\AI\\Store\\Document\\TextDocument` objects, converts them into embeddings and stores them in the
used vector store::
use Symfony\AI\Store\Document\TextDocument;
use Symfony\AI\Store\Indexer;
use Symfony\AI\Store\Document\Vectorizer;
use Symfony\AI\Store\Indexer\DocumentIndexer;
use Symfony\AI\Store\Indexer\DocumentProcessor;
$indexer = new Indexer($platform, $model, $store);
$document = new TextDocument('This is a sample document.');
$vectorizer = new Vectorizer($platform, $model);
$indexer = new DocumentIndexer(new DocumentProcessor($vectorizer, $store));
$document = new TextDocument('id-1', 'This is a sample document.');
$indexer->index($document);
You can find more advanced usage in combination with an Agent using the store for RAG in the examples folder.

View File

@@ -14,10 +14,11 @@ InMemoryStore
Stores vectors in a PHP array. Data is not persisted and is lost when the PHP process ends::
use Symfony\AI\Store\InMemory\Store;
use Symfony\AI\Store\Query\VectorQuery;
$store = new Store();
$store->add([$document1, $document2]);
$results = $store->query($vector);
$results = $store->query(new VectorQuery($vector));
CacheStore
----------
@@ -30,7 +31,7 @@ Stores vectors using a PSR-6 cache implementation. Persistence depends on the ca
$cache = new FilesystemAdapter();
$store = new Store($cache);
$store->add([$document1, $document2]);
$results = $store->query($vector);
$results = $store->query(new VectorQuery($vector));
Distance Strategies
-------------------
@@ -70,7 +71,7 @@ candidates are kept, reducing peak memory from O(N) to O(maxItems + batchSize)::
$store = new Store($calculator);
// Batch processing is activated when both batchSize and maxItems are set
$results = $store->query($vector, [
$results = $store->query($vectorQuery, [
'maxItems' => 10,
]);
@@ -87,34 +88,34 @@ Both stores support filtering search results based on document metadata using a
use Symfony\AI\Store\Document\VectorDocument;
$results = $store->query($vector, [
'filter' => fn(VectorDocument $doc) => $doc->metadata['category'] === 'products',
$results = $store->query($vectorQuery, [
'filter' => fn(VectorDocument $doc) => $doc->getMetadata()['category'] === 'products',
]);
You can combine multiple conditions::
$results = $store->query($vector, [
$results = $store->query($vectorQuery, [
'filter' => fn(VectorDocument $doc) =>
$doc->metadata['price'] <= 100
&& $doc->metadata['stock'] > 0
&& $doc->metadata['enabled'] === true,
$doc->getMetadata()['price'] <= 100
&& $doc->getMetadata()['stock'] > 0
&& $doc->getMetadata()['enabled'] === true,
'maxItems' => 10,
]);
Filter nested metadata::
$results = $store->query($vector, [
$results = $store->query($vectorQuery, [
'filter' => fn(VectorDocument $doc) =>
$doc->metadata['options']['size'] === 'S'
&& $doc->metadata['options']['color'] === 'blue',
$doc->getMetadata()['options']['size'] === 'S'
&& $doc->getMetadata()['options']['color'] === 'blue',
]);
Use array functions for complex filtering::
$allowedBrands = ['Nike', 'Adidas', 'Puma'];
$results = $store->query($vector, [
$results = $store->query($vectorQuery, [
'filter' => fn(VectorDocument $doc) =>
\in_array($doc->metadata['brand'] ?? '', $allowedBrands, true),
\in_array($doc->getMetadata()['brand'] ?? '', $allowedBrands, true),
]);
.. note::
@@ -131,7 +132,7 @@ Both stores support the following query options:
Example combining both options::
$results = $store->query($vector, [
$results = $store->query($vectorQuery, [
'maxItems' => 5,
'filter' => fn(VectorDocument $doc) => $doc->metadata['active'] === true,
'filter' => fn(VectorDocument $doc) => $doc->getMetadata()['active'] === true,
]);

View File

@@ -81,9 +81,10 @@ Query Similar Vectors
::
use Symfony\AI\Platform\Vector\Vector;
use Symfony\AI\Store\Query\VectorQuery;
$results = $store->query(
vector: new Vector([0.1, 0.2, 0.3, ...]),
query: new VectorQuery(new Vector([0.1, 0.2, 0.3, ...])),
options: [
'topK' => 5,
'filter' => ['category' => 'documentation'],
@@ -91,7 +92,7 @@ Query Similar Vectors
);
foreach ($results as $result) {
echo $result->metadata['title'] . ' (score: ' . $result->score . ')' . PHP_EOL;
echo $result->getMetadata()['title'] . ' (score: ' . $result->getScore() . ')' . PHP_EOL;
}
Remove Documents

View File

@@ -94,7 +94,7 @@ The SQLite store supports filtering search results based on document metadata us
use Symfony\AI\Store\Document\VectorDocument;
$results = $store->query($vectorQuery, [
'filter' => fn(VectorDocument $doc) => $doc->metadata['category'] === 'products',
'filter' => fn(VectorDocument $doc) => $doc->getMetadata()['category'] === 'products',
]);
Query Options
@@ -109,5 +109,5 @@ Example combining both options::
$results = $store->query($vectorQuery, [
'maxItems' => 5,
'filter' => fn(VectorDocument $doc) => $doc->metadata['active'] === true,
'filter' => fn(VectorDocument $doc) => $doc->getMetadata()['active'] === true,
]);

View File

@@ -152,15 +152,17 @@ Querying Documents
$queryVector = new Vector([0.1, 0.2, 0.3, /* ... 768 dimensions */]);
$results = $store->query($queryVector, [
use Symfony\AI\Store\Query\VectorQuery;
$results = $store->query(new VectorQuery($queryVector), [
'max_items' => 10,
'min_score' => 0.7
]);
foreach ($results as $document) {
echo "ID: " . $document->id . "\n";
echo "Score: " . $document->score . "\n";
echo "Metadata: " . json_encode($document->metadata->getArrayCopy()) . "\n";
echo "ID: " . $document->getId() . "\n";
echo "Score: " . $document->getScore() . "\n";
echo "Metadata: " . json_encode($document->getMetadata()->getArrayCopy()) . "\n";
}
Customization

View File

@@ -168,13 +168,11 @@ Vector Store Selection
For production environments, use persistent vector stores like ChromaDB::
use Codewithkyrian\ChromaDB\ChromaDB;
use Symfony\AI\Store\Bridge\ChromaDb\Store;
$store = new Store(
$httpClient,
'http://localhost:8000',
'my_collection'
);
$client = ChromaDB::factory()->connect();
$store = new Store($client, 'my_collection');
ChromaDB is a great choice for production RAG systems as it provides: