diff --git a/docs/bundles/profiler.png b/docs/bundles/profiler.png new file mode 100644 index 000000000..6aa2b5fe1 Binary files /dev/null and b/docs/bundles/profiler.png differ diff --git a/docs/components/chat.rst b/docs/components/chat.rst index ec1c08f0d..2a07af83d 100644 --- a/docs/components/chat.rst +++ b/docs/components/chat.rst @@ -26,7 +26,7 @@ with a ``Symfony\AI\Agent\AgentInterface`` and a ``Symfony\AI\Chat\MessageStoreI $platform = PlatformFactory::create($apiKey); - $agent = new Agent($platform, 'gpt-40-mini'); + $agent = new Agent($platform, 'gpt-4o-mini'); $chat = new Chat($agent, new InMemoryStore()); $chat->submit(Message::ofUser('Hello')); diff --git a/docs/components/platform.rst b/docs/components/platform.rst index 9b811f933..071e2c2b9 100644 --- a/docs/components/platform.rst +++ b/docs/components/platform.rst @@ -283,10 +283,10 @@ Server Tools Some platforms provide built-in server-side tools for enhanced capabilities without custom implementations: -1. **[Gemini](platform/gemini-server-tools.rst)** - URL Context, Google Search, Code Execution -1. **[VertexAI](platform/vertexai-server-tools.rst)** - URL Context, Google Search, Code Execution +* :doc:`platform/gemini-server-tools` - URL Context, Google Search, Code Execution +* :doc:`platform/vertexai-server-tools` - URL Context, Google Search, Code Execution -For complete Vertex AI setup and usage guide, see :doc:`vertexai`. +For complete Vertex AI setup and usage guide, see :doc:`platform/vertexai`. Parallel Platform Calls ----------------------- diff --git a/docs/components/store.rst b/docs/components/store.rst index 09b21594c..4a6d50f61 100644 --- a/docs/components/store.rst +++ b/docs/components/store.rst @@ -124,7 +124,7 @@ This leads to a store implementing two methods:: } } -.. _`Retrieval Augmented Generation`: https://de.wikipedia.org/wiki/Retrieval-Augmented_Generation +.. _`Retrieval Augmented Generation`: https://en.wikipedia.org/wiki/Retrieval-augmented_generation .. _`Similarity Search with Cloudflare (RAG)`: https://github.com/symfony/ai/blob/main/examples/rag/cloudflare.php .. _`Similarity Search with MariaDB (RAG)`: https://github.com/symfony/ai/blob/main/examples/rag/mariadb-gemini.php .. _`Similarity Search with Meilisearch (RAG)`: https://github.com/symfony/ai/blob/main/examples/rag/meilisearch.php diff --git a/docs/cookbook/chatbot-with-memory.rst b/docs/cookbook/chatbot-with-memory.rst new file mode 100644 index 000000000..9f4b334cd --- /dev/null +++ b/docs/cookbook/chatbot-with-memory.rst @@ -0,0 +1,167 @@ +Building a Chatbot with Memory +============================== + +This guide demonstrates how to build a chatbot that remembers context across conversations +using Symfony AI's memory management features. + +Overview +-------- + +Memory providers allow your agents to access conversation history and user-specific information, +enabling more personalized and context-aware responses. In this example, we'll build a personal +trainer chatbot that remembers facts about the user. + +Prerequisites +------------- + +* Symfony AI Agent component installed +* OpenAI API key (or any other supported platform) +* Basic understanding of Symfony AI concepts + +Implementation +-------------- + +The complete implementation consists of three main parts: + +1. Creating a memory provider with user facts +2. Configuring the agent with memory support +3. Processing user messages with context awareness + +Complete Example +~~~~~~~~~~~~~~~~ + +.. literalinclude:: ../../examples/memory/static.php + :language: php + :linenos: + +Key Components +-------------- + +Memory Provider +~~~~~~~~~~~~~~~ + +The :class:`Symfony\\AI\\Agent\\Memory\\StaticMemoryProvider` stores fixed information that should be consistently available +to the agent:: + + use Symfony\AI\Agent\Memory\StaticMemoryProvider; + + $personalFacts = new StaticMemoryProvider( + 'My name is Wilhelm Tell', + 'I wish to be a swiss national hero', + 'I am struggling with hitting apples but want to be professional with the bow and arrow', + ); + +This information is automatically injected into the system prompt, providing the agent with +context about the user without cluttering the conversation messages. + +Memory Input Processor +~~~~~~~~~~~~~~~~~~~~~~ + +The :class:`Symfony\\AI\\Agent\\Memory\\MemoryInputProcessor` handles the injection of memory content into the agent's context:: + + use Symfony\AI\Agent\Memory\MemoryInputProcessor; + + $memoryProcessor = new MemoryInputProcessor($personalFacts); + +This processor works alongside other input processors like :class:`Symfony\\AI\\Agent\\InputProcessor\\SystemPromptInputProcessor` +to build a complete context for the agent. + +Agent Configuration +~~~~~~~~~~~~~~~~~~~ + +The agent is configured with both system prompt and memory processors:: + + use Symfony\AI\Agent\Agent; + + $agent = new Agent( + $platform, + 'gpt-4o-mini', + [$systemPromptProcessor, $memoryProcessor] + ); + +Processors are applied in order, allowing you to build up the context progressively. + +How It Works +------------ + +1. **Memory Loading**: When a user message is submitted, the ``MemoryInputProcessor`` loads + relevant facts from the memory provider. + +2. **Context Injection**: The memory content is prepended to the system prompt, giving the + agent access to user-specific information. + +3. **Response Generation**: The agent generates a personalized response based on both the + current message and the remembered context. + +4. **Conversation Flow**: The memory persists across multiple calls, enabling continuous + personalized interactions. + +Use Dynamic Memory with Embeddings +---------------------------------- + +For more sophisticated scenarios, use :class:`Symfony\\AI\\Agent\\Memory\\EmbeddingProvider` to retrieve relevant context +based on semantic similarity:: + + use Symfony\AI\Agent\Memory\EmbeddingProvider; + + $embeddingsMemory = new EmbeddingProvider( + $platform, + $embeddings, // Your embeddings model + $store // Your vector store + ); + +This approach allows the agent to recall specific pieces of information from a large +knowledge base based on the current conversation context. + +Bundle Configuration +-------------------- + +When using the AI Bundle, you can configure memory directly in your configuration: + +.. code-block:: yaml + + # config/packages/ai.yaml + ai: + agent: + trainer: + model: 'gpt-4o-mini' + prompt: + text: 'Provide short, motivating claims' + memory: 'You are a professional trainer with personalized advice' + +For dynamic memory using a custom service: + +.. code-block:: yaml + + ai: + agent: + trainer: + model: 'gpt-4o-mini' + prompt: + text: 'Provide short, motivating claims' + memory: + service: 'app.user_memory_provider' + +Best Practices +-------------- + +* **Keep Static Memory Concise**: Only include essential facts to avoid overwhelming the agent +* **Separate Concerns**: Use system prompt for behavior, memory for context +* **Update Dynamically**: For user-specific applications, update memory as you learn more about the user +* **Test Without Memory**: Verify your agent works correctly both with and without memory enabled +* **Monitor Token Usage**: Memory content consumes input tokens, so balance comprehensiveness with cost + +Use Cases +--------- + +* **Personal Assistants**: Remember user preferences, habits, and history +* **Customer Support**: Recall previous interactions and customer details +* **Educational Tools**: Track student progress and learning style +* **Healthcare Applications**: Maintain patient history and treatment context + +Related Documentation +--------------------- + +* :doc:`../components/agent` - Agent component documentation +* :doc:`../bundles/ai-bundle` - AI Bundle configuration reference +* :doc:`rag-implementation` - Retrieval Augmented Generation guide diff --git a/docs/cookbook/index.rst b/docs/cookbook/index.rst new file mode 100644 index 000000000..ec372ba92 --- /dev/null +++ b/docs/cookbook/index.rst @@ -0,0 +1,24 @@ +Cookbook +======== + +The cookbook contains practical guides and complete examples for common use cases +with Symfony AI. Each guide includes working code, explanations, and best practices. + +Getting Started Guides +---------------------- + +.. toctree:: + :maxdepth: 1 + + chatbot-with-memory + rag-implementation + +Memory & Context Management +--------------------------- + +* :doc:`chatbot-with-memory` - Build chatbots that remember user preferences and conversation history + +Retrieval Augmented Generation +------------------------------ + +* :doc:`rag-implementation` - Implement complete RAG systems with vector stores and semantic search diff --git a/docs/cookbook/rag-implementation.rst b/docs/cookbook/rag-implementation.rst new file mode 100644 index 000000000..cdccb395b --- /dev/null +++ b/docs/cookbook/rag-implementation.rst @@ -0,0 +1,393 @@ +Implementing Retrieval Augmented Generation (RAG) +================================================= + +This guide walks you through implementing a complete RAG (Retrieval Augmented Generation) +system using Symfony AI. RAG allows your agent to retrieve relevant information from a +knowledge base and use it to generate accurate, context-aware responses. + +What is RAG? +------------ + +Retrieval Augmented Generation combines the power of vector search with language models +to provide agents with access to external knowledge. Instead of relying solely on the +model's training data, RAG systems: + +1. Convert documents into vector embeddings +2. Store embeddings in a vector database +3. Find similar documents based on user queries +4. Provide retrieved context to the language model +5. Generate responses based on the retrieved information + +This approach is ideal for: + +* Knowledge bases and documentation +* Product catalogs +* Customer support systems +* Research assistants +* Domain-specific chatbots + +Prerequisites +------------- + +* Symfony AI Platform component +* Symfony AI Agent component +* Symfony AI Store component +* An embeddings model (e.g., OpenAI's text-embedding-3-small) +* A language model (e.g., gpt-4o-mini) +* Optional: A vector store (or use in-memory for testing) + +Complete Implementation +----------------------- + +.. literalinclude:: ../../examples/rag/in-memory.php + :language: php + :linenos: + +Step-by-Step Breakdown +---------------------- + +Step 1: Initialize the Vector Store +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +First, create a store to hold your vector embeddings:: + + use Symfony\AI\Store\Bridge\Local\InMemoryStore; + + $store = new InMemoryStore(); + +For production use, consider using persistent stores like ChromaDB, Pinecone, or MongoDB Atlas. + +Step 2: Prepare Your Documents +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Create text documents with relevant content and metadata:: + + use Symfony\AI\Store\Document\Metadata; + use Symfony\AI\Store\Document\TextDocument; + use Symfony\Component\Uid\Uuid; + + $documents = []; + foreach ($movies as $movie) { + $documents[] = new TextDocument( + id: Uuid::v4(), + content: 'Title: '.$movie['title'].PHP_EOL. + 'Director: '.$movie['director'].PHP_EOL. + 'Description: '.$movie['description'], + metadata: new Metadata($movie), + ); + } + +Each document should contain: + +* **ID**: Unique identifier (UUID v4 recommended) +* **Content**: The text to be embedded and searched +* **Metadata**: Additional information preserved with the document + +Step 3: Create Embeddings and Index Documents +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Use a vectorizer to convert documents into embeddings and store them:: + + use Symfony\AI\Store\Document\Loader\InMemoryLoader; + use Symfony\AI\Store\Document\Vectorizer; + use Symfony\AI\Store\Indexer; + + $platform = PlatformFactory::create(env('OPENAI_API_KEY')); + $vectorizer = new Vectorizer($platform, 'text-embedding-3-small'); + $indexer = new Indexer( + new InMemoryLoader($documents), + $vectorizer, + $store + ); + $indexer->index($documents); + +The indexer handles: + +* Loading documents from the source +* Generating vector embeddings +* Storing vectors in the vector store + +Step 4: Configure Similarity Search Tool +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Create a tool that performs semantic search on your vector store:: + + use Symfony\AI\Agent\Toolbox\AgentProcessor; + use Symfony\AI\Agent\Toolbox\Tool\SimilaritySearch; + use Symfony\AI\Agent\Toolbox\Toolbox; + + $similaritySearch = new SimilaritySearch($vectorizer, $store); + $toolbox = new Toolbox([$similaritySearch]); + $processor = new AgentProcessor($toolbox); + +The :class:`Symfony\\AI\\Agent\\Toolbox\\Tool\\SimilaritySearch` tool: + +* Converts the user's query into a vector +* Searches for similar vectors in the store +* Returns the most relevant documents + +Step 5: Create RAG-Enabled Agent +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Configure the agent with the similarity search processor:: + + use Symfony\AI\Agent\Agent; + + $agent = new Agent( + $platform, + 'gpt-4o-mini', + [$processor], // Input processors + [$processor] // Output processors + ); + +The agent will automatically use the similarity search tool when needed. + +Step 6: Query with Context +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Create messages that instruct the agent to use the similarity search:: + + use Symfony\AI\Platform\Message\Message; + use Symfony\AI\Platform\Message\MessageBag; + + $messages = new MessageBag( + Message::forSystem('Please answer all user questions only using SimilaritySearch function.'), + Message::ofUser('Which movie fits the theme of the mafia?') + ); + $result = $agent->call($messages); + +The agent will: + +1. Analyze the user's question +2. Call the similarity search tool +3. Retrieve relevant documents +4. Generate a response based on the retrieved context + +Production-Ready RAG Systems +---------------------------- + +Vector Store Selection +~~~~~~~~~~~~~~~~~~~~~~ + +For production environments, use persistent vector stores like ChromaDB:: + + use Symfony\AI\Store\Bridge\ChromaDB\ChromaStore; + + $store = new ChromaStore( + $httpClient, + 'http://localhost:8000', + 'my_collection' + ); + +ChromaDB is a great choice for production RAG systems as it provides: + +* Local or self-hosted deployment options +* Efficient vector similarity search +* Built-in persistence +* Easy integration with Symfony AI + +See :doc:`../components/store` for all supported vector stores including Pinecone, MongoDB Atlas, Weaviate, and more. + +Document Loading Strategies +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**File-based loading** for static content:: + + use Symfony\AI\Store\Document\Loader\TextFileLoader; + + $loader = new TextFileLoader('/path/to/documents'); + +**Database loading** for dynamic content:: + + use Symfony\AI\Store\Document\Loader\InMemoryLoader; + + // Fetch from database + $articles = $articleRepository->findAll(); + $documents = array_map( + fn($article) => new TextDocument( + id: Uuid::fromString($article->getId()), + content: $article->getTitle().PHP_EOL.$article->getContent(), + metadata: new Metadata(['author' => $article->getAuthor()]) + ), + $articles + ); + + $loader = new InMemoryLoader($documents); + +Advanced Configurations +----------------------- + +Chunking Large Documents +~~~~~~~~~~~~~~~~~~~~~~~~ + +For large documents, split them into smaller chunks for better retrieval using the +:class:`Symfony\\AI\\Store\\Document\\Transformer\\TextSplitTransformer`:: + + use Symfony\AI\Store\Document\Transformer\TextSplitTransformer; + + $transformer = new TextSplitTransformer( + chunkSize: 1000, + overlap: 200 + ); + + $chunkedDocuments = $transformer->transform($documents); + +The transformer automatically: + +* Splits documents into chunks of the specified size +* Adds overlap between chunks to maintain context +* Preserves original document metadata +* Tracks parent document IDs for reference + +Custom Similarity Metrics +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Some vector stores support different similarity metrics: + +.. code-block:: yaml + + # config/packages/ai.yaml + ai: + store: + memory: + default: + strategy: 'cosine' # or 'euclidean', 'manhattan', 'chebyshev' + +Metadata Filtering +~~~~~~~~~~~~~~~~~~ + +ChromaDB supports filtering search results based on metadata using the ``where`` option:: + + $result = $store->query($vector, [ + 'where' => [ + 'category' => 'technical', + 'status' => 'published', + ], + ]); + +You can also filter based on document content using ``whereDocument``:: + + $result = $store->query($vector, [ + 'where' => ['category' => 'technical'], + 'whereDocument' => ['$contains' => 'machine learning'], + ]); + +Bundle Configuration +-------------------- + +When using the AI Bundle, configure RAG with YAML: + +.. code-block:: yaml + + # config/packages/ai.yaml + ai: + platform: + openai: + api_key: '%env(OPENAI_API_KEY)%' + + vectorizer: + default: + platform: 'ai.platform.openai' + model: 'text-embedding-3-small' + + store: + chroma_db: + knowledge_base: + collection: 'docs' + + indexer: + docs: + loader: 'App\Document\Loader\DocLoader' + vectorizer: 'ai.vectorizer.default' + store: 'ai.store.chroma_db.knowledge_base' + + agent: + rag_assistant: + model: 'gpt-4o-mini' + prompt: + text: 'Answer questions using only the SimilaritySearch tool. If you cannot find relevant information, say so.' + tools: + - 'Symfony\AI\Agent\Toolbox\Tool\SimilaritySearch' + +Then use the indexer command to populate your store: + +.. code-block:: terminal + + $ php bin/console ai:store:setup chroma_db.knowledge_base + $ php bin/console ai:store:index docs + +Performance Optimization +------------------------ + +Batch Indexing +~~~~~~~~~~~~~~ + +Index documents in batches for better performance:: + + $batchSize = 100; + foreach (array_chunk($documents, $batchSize) as $batch) { + $indexer->index($batch); + } + +Caching Embeddings +~~~~~~~~~~~~~~~~~~ + +Cache embeddings to avoid recomputing:: + + use Symfony\Contracts\Cache\CacheInterface; + + class CachedVectorizer + { + public function __construct( + private Vectorizer $vectorizer, + private CacheInterface $cache, + ) { + } + + public function vectorize(string $text): Vector + { + $key = 'embedding_'.md5($text); + + return $this->cache->get($key, function() use ($text) { + return $this->vectorizer->vectorize($text); + }); + } + } + +Best Practices +-------------- + +1. **Document Quality**: Ensure documents are well-structured and contain relevant information +2. **Chunk Size**: Experiment with different chunk sizes (500-1500 tokens typical) +3. **Metadata**: Include useful metadata for filtering and context +4. **System Prompt**: Explicitly instruct the agent to use the similarity search tool +5. **Limit Results**: Configure appropriate limits to balance relevance and context size +6. **Update Strategy**: Plan for incremental updates vs. full reindexing +7. **Monitor Performance**: Track query latency and relevance metrics +8. **Test Queries**: Validate that retrieval returns expected results + +Common Pitfalls +--------------- + +* **Too Large Chunks**: Large chunks reduce retrieval precision +* **Too Small Chunks**: Small chunks lose context +* **Missing Instructions**: Agent needs explicit instructions to use similarity search +* **Poor Document Quality**: Garbage in, garbage out +* **Incorrect Embeddings Model**: Use the same model for indexing and querying +* **No Metadata**: Missing metadata limits filtering capabilities + +Related Examples +---------------- + +* `RAG with ChromaDB `_ +* `RAG with MongoDB `_ +* `RAG with Pinecone `_ +* `RAG with Meilisearch `_ + +Related Documentation +--------------------- + +* :doc:`../components/store` - Store component documentation +* :doc:`../components/agent` - Agent component documentation +* :doc:`../bundles/ai-bundle` - AI Bundle configuration +* :doc:`chatbot-with-memory` - Memory management guide diff --git a/docs/index.rst b/docs/index.rst index 3e524657d..76446e3c2 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,8 +1,109 @@ Symfony AI Documentation ======================== +Symfony AI is a set of components that integrate AI capabilities into PHP applications, +providing a unified interface to work with various AI platforms like OpenAI, Anthropic, +Google Gemini, Azure, and more. + +Getting Started +--------------- + +Symfony AI consists of several components and bundles that work together to bring +AI capabilities to your application: + +* :doc:`Platform Component `: Unified interface to various AI models and providers +* :doc:`Agent Component `: Framework for building AI agents with tools and workflows +* :doc:`Chat Component `: API to interact with agents and store conversation history +* :doc:`Store Component `: Data storage abstraction for vector databases and RAG applications +* :doc:`AI Bundle `: Symfony integration bringing all components together +* :doc:`MCP Bundle `: Integration for the Model Context Protocol SDK + +Quick Start +----------- + +Install the AI Bundle to get started with Symfony AI: + +.. code-block:: terminal + + $ composer require symfony/ai-bundle + +Configure your AI platform: + +.. code-block:: yaml + + # config/packages/ai.yaml + ai: + platform: + openai: + api_key: '%env(OPENAI_API_KEY)%' + agent: + default: + model: 'gpt-4o-mini' + +Use the agent in your service:: + + namespace App\Agent; + + use Symfony\AI\Agent\AgentInterface; + use Symfony\AI\Platform\Message\Message; + use Symfony\AI\Platform\Message\MessageBag; + + final readonly class ChatService + { + public function __construct( + private AgentInterface $agent, + ) { + } + + public function chat(string $userMessage): string + { + $messages = new MessageBag( + Message::forSystem('You are a helpful assistant.'), + Message::ofUser($userMessage), + ); + + $result = $this->agent->call($messages); + + return $result->getContent(); + } + } + +Key Features +------------ + +**Multi-Platform Support** + Connect to OpenAI, Anthropic Claude, Google Gemini, Azure OpenAI, AWS Bedrock, + Mistral, Ollama, and many more platforms with a unified interface. + +**Tool Calling** + Extend your agents with custom tools to interact with external APIs, databases, + and services. Built-in tools available for common tasks. + +**Retrieval Augmented Generation (RAG)** + Build context-aware applications using vector stores with support for + ChromaDB, Pinecone, Weaviate, MongoDB Atlas, and more. + +**Structured Output** + Extract structured data from unstructured text using PHP classes or array schemas. + +**Multi-Modal Support** + Process text, images, audio, and other content types with compatible models. + +**Streaming Support** + Stream responses from AI models for real-time user experiences. + +**Memory Management** + Add contextual memory to agents for personalized conversations. + +**Testing Tools** + Mock agents and platforms for reliable testing without external API calls. + +Documentation +------------- + .. toctree:: :maxdepth: 2 components/index bundles/index + cookbook/index