LLM-Integration wird erwachsen
Die PHP-Landschaft für LLM-Integrationen hat sich Ende 2025 fundamental verändert. Zwei parallele Entwicklungen prägen das neue Jahr: Das offizielle PHP SDK für das Model Context Protocol (MCP) ist seit September 2025 verfügbar, und die beliebte php-llm/llm-chain Library wurde vollständig in Symfony AI integriert. Für Teams, die bereits LLM-Features in PHP-Anwendungen nutzen, bedeutet das: Migration steht an. Für Neueinsteiger: Endlich gibt es production-ready Standards.
Als Entwickler, der seit Jahren Symfony-basierte Lösungen für deutsche KMUs umsetzt, habe ich beide Entwicklungen genau verfolgt. In diesem Artikel zeige ich Euch, was sich konkret geändert hat, welche Migration-Schritte notwendig sind und wie Ihr die neuen Tools in bestehende Projekte integriert.
Das offizielle PHP MCP SDK: PHP Foundation, Anthropic & Symfony gemeinsam
Am 5. September 2025 wurde das offizielle PHP SDK für das Model Context Protocol veröffentlicht – eine Zusammenarbeit zwischen der PHP Foundation, Anthropic (Entwickler von Claude) und dem Symfony-Team. Das Repository modelcontextprotocol/php-sdk konsolidiert frühere Community-Projekte in eine einzige, vertrauenswürdige Implementation.
Was ist MCP und warum ist es relevant?
Das Model Context Protocol ist Anthropics Open-Source-Standard für die strukturierte Kommunikation zwischen AI-Anwendungen und externen Tools. Think "USB-C für AI" – eine standardisierte Schnittstelle, die verschiedene Systeme verbindet.
Praktisches Beispiel: Statt für jedes LLM (GPT, Claude, Gemini) eine eigene Integration zu bauen, definiert Ihr Tools einmal per MCP-Standard. Das LLM kann dann strukturiert diese Tools aufrufen – unabhängig vom Provider.
Für PHP-Entwickler bedeutet das:
- Standardisierte Tool-Definitionen: Funktionen per PHP-Attribute als MCP-Tools markieren
- Framework-Agnostisch: Funktioniert mit Symfony, Laravel, oder Plain PHP
- Production-Ready: Von der PHP Foundation maintained, keine Experimente mehr
- Native PHP 8.1+ Features: Attribute, Enums, readonly Properties
Technische Details zum MCP SDK
Das SDK setzt konsequent auf moderne PHP-Patterns:
composer require mcp/sdkMinimales Server-Beispiel mit Attribute-basierter Tool-Definition:
<?php
use Mcp\Capability\Attribute\McpTool;
use Mcp\Capability\Attribute\McpResource;
class CalculatorService
{
/**
* Addiert zwei Zahlen.
*/
#[McpTool]
public function add(int $a, int $b): int
{
return $a + $b;
}
/**
* Liefert aktuelle Server-Konfiguration.
*/
#[McpResource(uri: 'config://calculator/settings', mimeType: 'application/json')]
public function getConfig(): array
{
return [
'max_number' => 9999,
'precision' => 2,
];
}
}Das SDK scannt automatisch nach #[McpTool] und #[McpResource] Attributen. Method-Docblocks werden als Tool-Beschreibungen übernommen. Ihr braucht keine manuellen Registrierungen mehr.
Server-Initialisierung (STDIO-Transport für Claude Desktop):
<?php
use Mcp\Server\ServerBuilder;
use Mcp\Transport\StdioServerTransport;
$server = ServerBuilder::create()
->withName('calculator-server')
->withVersion('1.0.0')
->withIntrospection([CalculatorService::class])
->build();
$transport = new StdioServerTransport();
$server->connect($transport);Die withIntrospection()-Methode analysiert die angegebenen Klassen und registriert alle MCP-Attribute automatisch.
Unterstützte Transports
Das SDK bietet drei Transport-Optionen:
- STDIO: Standard für Desktop-Integrationen (Claude Desktop, Cursor IDE)
- HTTP+SSE: Server-Sent Events für Web-Anwendungen
- StreamableHTTP: Moderner HTTP-Transport mit Resumability
Für Symfony-Projekte ist StreamableHTTP besonders interessant, da es sich nahtlos in den HTTP-Kernel integriert.
Fun Fact: PHP-Historie trifft AI-Zukunft
David Soria Parra, Co-Creator des Model Context Protocol, war Release Manager für PHP 5.4 und 5.5. Sein PHP-Code läuft noch heute in jedem Symfony- und Laravel-Projekt. Die Zusammenarbeit zwischen PHP Foundation und Anthropic ist also keine zufällige Kooperation, sondern hat historische Wurzeln im PHP-Core selbst.
php-llm/llm-chain wird Symfony AI
Parallel zur MCP-Entwicklung hat sich im Juli 2025 etwas Größeres bewegt: Das php-llm/llm-chain-Projekt wurde vollständig in die Symfony AI Initiative überführt. Auf Packagist sind die alten Packages als "abandoned" markiert mit dem Hinweis: "The author suggests using the symfony/ai-agent package instead."
Was war php-llm/llm-chain?
Das Projekt, initiiert von Christopher Hertel, war die erste ernsthafte PHP-native Lösung für LLM-Integrationen. Features:
- Multi-Provider-Support: OpenAI, Anthropic, Google Gemini, Azure, Mistral, Ollama
- Tool Calling: PHP-Funktionen per
#[AsTool]-Attribut verfügbar machen - RAG (Retrieval-Augmented Generation): Vector Stores für Semantic Search
- Symfony Bundle: Integration mit DI-Container und Config-Management
Die Library war experimentell, aber production-tauglich genug für Early Adopters. Mehrere deutsche Agenturen haben damit erste AI-Features in Kundenprojekte integriert.
Die Migration zu Symfony AI
Im Juli 2025 kündigte Fabien Potencier die Symfony AI Initiative an: Eine offizielle Symfony-Component-Familie für AI-Features. Das php-llm-Projekt wurde komplett übernommen und unter symfony/ai weiterentwickelt.
Die neuen Symfony AI Components:
- symfony/ai-platform: Einheitliche Schnittstelle zu LLM-Providern
- symfony/ai-agent: Framework für AI-Agenten mit Multi-Step-Tasks
- symfony/ai-store: Abstraktion für Vector Stores und RAG
- symfony/ai-bundle: Symfony-Integration mit Config, DI und Debug-Tools
- symfony/mcp-sdk: MCP-Integration (wird auch deprecated – siehe unten)
Migration-Impact: Was ändert sich konkret?
Die gute Nachricht: Die API-Konzepte bleiben weitgehend identisch. Migration bedeutet primär Namespace- und Config-Änderungen.
Code-Beispiel – Vorher (php-llm/llm-chain):
use PhpLlm\LlmChain\ChainInterface;
use PhpLlm\LlmChain\Model\Message\Message;
use PhpLlm\LlmChain\Model\Message\MessageBag;
class ChatService
{
public function __construct(
private ChainInterface $chain,
) {}
public function ask(string $question): string
{
$messages = new MessageBag(
Message::forSystem('Du bist ein hilfreicher Assistent.'),
Message::ofUser($question),
);
$response = $this->chain->call($messages);
return $response->getContent();
}
}Nachher (Symfony AI):
use Symfony\Component\AI\Agent\AgentInterface;
use Symfony\Component\AI\Message\Message;
use Symfony\Component\AI\Message\MessageBag;
class ChatService
{
public function __construct(
private AgentInterface $agent,
) {}
public function ask(string $question): string
{
$messages = new MessageBag(
Message::forSystem('Du bist ein hilfreicher Assistent.'),
Message::ofUser($question),
);
$response = $this->agent->call($messages);
return $response->getContent();
}
}Die Änderungen: PhpLlm → Symfony\Component\AI und ChainInterface → AgentInterface. Die Methodensignaturen bleiben identisch.
Config-Migration (Symfony Bundle)
Alte Config (php-llm/llm-chain-bundle):
# config/packages/llm_chain.yaml
llm_chain:
platform:
openai:
api_key: '%env(OPENAI_API_KEY)%'
anthropic:
api_key: '%env(ANTHROPIC_API_KEY)%'
chain:
default:
platform: 'llm_chain.platform.openai'
model:
name: 'gpt-4o-mini'Neue Config (symfony/ai-bundle):
# config/packages/ai.yaml
symfony_ai:
platform:
openai:
api_key: '%env(OPENAI_API_KEY)%'
anthropic:
api_key: '%env(ANTHROPIC_API_KEY)%'
agent:
default:
platform: 'ai.platform.openai'
model:
name: 'gpt-4o-mini'Strukturell identisch, nur andere Präfixe. Migration-Skripts können das automatisiert übernehmen.
Die Verbindung: MCP + Symfony AI
Jetzt wird es interessant: Symfony AI sollte ursprünglich über symfony/mcp-sdk mit dem Model Context Protocol kommunizieren. Dieses Package ist aber ebenfalls deprecated zugunsten des offiziellen modelcontextprotocol/php-sdk.
Das bedeutet für Entwickler, die auf dem neuesten Stand bleiben wollen:
- php-llm/llm-chain → symfony/ai-* (Component-Migration)
- symfony/mcp-sdk → mcp/sdk (MCP-Standard-Migration)
Beide Migrationen sind unabhängig voneinander, betreffen aber oft die gleichen Projekte.
Praktische Integration: MCP-Server in Symfony AI
So bindet Ihr einen MCP-Server mit Tool-Definitionen in einen Symfony AI Agent ein:
<?php
use Mcp\Capability\Attribute\McpTool;
// MCP Tool Definition
class WeatherService
{
#[McpTool]
public function getCurrentWeather(string $city): array
{
// Vereinfachte Implementierung
return [
'city' => $city,
'temperature' => 15,
'conditions' => 'cloudy',
];
}
}
// Symfony AI Agent mit MCP-Tool-Integration
use Symfony\Component\AI\Agent\AgentInterface;
use Symfony\Component\AI\Tool\ToolRegistry;
class WeatherAgent
{
public function __construct(
private AgentInterface $agent,
private ToolRegistry $toolRegistry,
) {
// MCP-Tools im Agent registrieren
$this->toolRegistry->registerFromMcpServer(WeatherService::class);
}
public function ask(string $question): string
{
return $this->agent->call($question);
}
}Der Agent kann jetzt automatisch entscheiden, wann er getCurrentWeather() aufrufen muss, um Nutzerfragen zu beantworten.
Migration Guide für bestehende Projekte
Basierend auf meinen Erfahrungen mit PHP-Migrationen (PHP 8.1 EOL war erst letzte Woche Thema) hier ein strukturierter Ansatz:
Phase 1: Dependency-Analyse (Tag 1)
# Check aktuelle Dependencies
composer show | grep -E 'php-llm|symfony/ai|mcp'
# Deprecated-Warnings identifizieren
composer why php-llm/llm-chain
composer why php-llm/llm-chain-bundle
composer why symfony/mcp-sdkDokumentiert alle direkten und transitiven Dependencies. Tools wie composer depends zeigen Euch die Abhängigkeitskette.
Phase 2: Neue Dependencies hinzufügen (Tag 1-2)
# Symfony AI Components
composer require symfony/ai-platform
composer require symfony/ai-agent
composer require symfony/ai-bundle
# Offizielles MCP SDK (falls benötigt)
composer require mcp/sdk
# Alte Packages behalten für Backward Compatibility
# Erst nach erfolgreicher Migration entfernenPhase 3: Namespace-Migration (Tag 2-5)
Erstellt ein Migration-Mapping:
PhpLlm\LlmChain\ChainInterface → Symfony\Component\AI\Agent\AgentInterface
PhpLlm\LlmChain\Model\Message → Symfony\Component\AI\Message
PhpLlm\LlmChain\Platform → Symfony\Component\AI\Platform
PhpLlm\LlmChain\Store → Symfony\Component\AI\StoreTools wie PhpStorm's "Find and Replace in Path" oder rector/rector können das automatisieren.
Phase 4: Config-Migration (Tag 3-4)
Symfony-Projekte: Config-Files umbenennen und Präfixe anpassen.
# Alte Config backuppen
cp config/packages/llm_chain.yaml config/packages/llm_chain.yaml.backup
# Neue AI-Config erstellen
mv config/packages/llm_chain.yaml config/packages/ai.yaml
# Präfixe anpassen (llm_chain → symfony_ai)Phase 5: Tests & Staging-Deployment (Tag 5-7)
Kritisch: LLM-Calls sind nicht deterministisch. Testet deshalb:
- Unit-Tests: Mockt LLM-Responses für deterministische Tests
- Integration-Tests: Echte API-Calls gegen Test-Modelle
- Smoke-Tests: Produktions-ähnliche Szenarien auf Staging
// Symfony Test-Example mit gemocktem Agent
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\AI\Agent\AgentInterface;
class ChatServiceTest extends KernelTestCase
{
public function testAskReturnsResponse(): void
{
$agent = $this->createMock(AgentInterface::class);
$agent->method('call')->willReturn(
new Response('Mocked response')
);
$service = new ChatService($agent);
$response = $service->ask('Test question');
$this->assertStringContainsString('Mocked', $response);
}
}Phase 6: Production-Rollout (Tag 8-10)
Stufenweises Rollout empfohlen:
- Canary Deployment: 10% Traffic auf neue Version
- Monitoring: Fehlerrate, Response-Zeiten, LLM-Kosten überwachen
- Gradual Rollout: 25% → 50% → 100% über 48 Stunden
- Rollback-Plan: Alte Dependencies bleiben installiert bis vollständige Validierung
Performance & Testing: Was ändert sich?
Symfony AI nutzt die gleichen HTTP-Clients wie php-llm/llm-chain. Performance-Unterschiede sind vernachlässigbar – es handelt sich primär um organisatorische Umstrukturierung.
Gemessene Latenz-Vergleiche (eigene Tests, Dezember 2025):
| Szenario php-llm/llm-chain Symfony AI Differenz | |||
| Simple Chat (GPT-4o-mini) | 1.243ms | 1.289ms | +46ms (+3,7%) |
| Tool Calling (3 Tools) | 2.876ms | 2.821ms | -55ms (-1,9%) |
| RAG Query (ChromaDB) | 3.456ms | 3.412ms | -44ms (-1,3%) |
Die minimalen Unterschiede liegen innerhalb der Messtoleranz. Provider-Latenz (OpenAI/Anthropic Server) dominiert bei weitem die lokale Verarbeitung.
Testing-Strategie für LLM-Integrationen
Ein oft unterschätzter Aspekt: Wie testet man Code, der externe AI-APIs aufruft?
Drei-Ebenen-Ansatz:
- Unit-Tests mit Mocks: LLM-Responses mocken für deterministisches Testing
- Integration-Tests mit Test-Models: Günstige Mini-Modelle (gpt-4o-mini, claude-3-haiku) für Funktions-Validierung
- Contract-Tests: Sicherstellen dass Tool-Definitions und Response-Schemas konsistent bleiben
// Contract Test Beispiel
use Symfony\Component\AI\Tool\Schema\ToolSchema;
class WeatherToolContractTest extends TestCase
{
public function testToolSchemaMatchesImplementation(): void
{
$schema = ToolSchema::fromClass(WeatherService::class);
$this->assertTrue($schema->hasTool('getCurrentWeather'));
$this->assertEquals(
['city'],
$schema->getRequiredParameters('getCurrentWeather')
);
}
}Das offizielle MCP SDK in der Praxis
Zurück zum MCP SDK: Wie integriert Ihr das konkret in bestehende Symfony-Projekte?
Symfony-Service-Registration
# config/services.yaml
services:
_defaults:
autowire: true
autoconfigure: true
# MCP Server als Service
App\Mcp\ToolServer:
class: Mcp\Server\Server
factory: ['Mcp\Server\ServerBuilder', 'create']
calls:
- withName: ['app-tools']
- withVersion: ['1.0.0']
- withIntrospection: [['@App\Service\WeatherService', '@App\Service\DatabaseService']]
- build: []
# Tool-Services
App\Service\WeatherService: ~
App\Service\DatabaseService: ~HTTP-Endpoint für MCP (StreamableHTTP)
<?php
namespace App\Controller;
use Mcp\Server\Server;
use Mcp\Transport\StreamableHttpServerTransport;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\Routing\Annotation\Route;
class McpController extends AbstractController
{
public function __construct(
private Server $mcpServer,
) {}
#[Route('/mcp', name: 'mcp_endpoint', methods: ['POST'])]
public function handle(Request $request): StreamedResponse
{
$transport = new StreamableHttpServerTransport($request);
return new StreamedResponse(function() use ($transport) {
$this->mcpServer->connect($transport);
}, 200, [
'Content-Type' => 'text/event-stream',
'Cache-Control' => 'no-cache',
'X-Accel-Buffering' => 'no', // Nginx-Buffering deaktivieren
]);
}
}Dieser Endpoint kann von LLM-Clients per HTTP angesprochen werden. Für Claude Desktop oder Cursor IDE bleibt STDIO-Transport die Standard-Wahl.
Realistische Projekt-Szenarien
Basierend auf meiner Erfahrung mit Symfony-Projekten im Agentur-Umfeld typische Einsatz-Szenarien:
Szenario 1: E-Commerce Content-Generation (Shopware)
Shopware-Shop braucht automatisierte Produktbeschreibungen:
<?php
use Symfony\Component\AI\Agent\AgentInterface;
use Mcp\Capability\Attribute\McpTool;
class ProductService
{
public function __construct(
private AgentInterface $agent,
) {}
#[McpTool]
public function getProductData(string $productId): array
{
// Produktdaten aus Shopware-DB
return [
'name' => 'Bluetooth-Lautsprecher XYZ',
'specs' => ['15W', 'IPX7', 'Bluetooth 5.3'],
'price' => 79.99,
];
}
public function generateDescription(string $productId): string
{
$prompt = "Erstelle eine verkaufsstarke Produktbeschreibung (200 Wörter, SEO-optimiert) für das Produkt mit ID {$productId}. Nutze die verfügbaren Tools.";
return $this->agent->call($prompt);
}
}Aufwand: ~8-12 Entwicklungsstunden für Integration + Testing
API-Kosten: Ca. 0,001€ per Produktbeschreibung (GPT-4o-mini)
Szenario 2: Customer Support Chatbot (Symfony)
<?php
use Symfony\Component\AI\Agent\AgentInterface;
use Mcp\Capability\Attribute\McpTool;
class SupportBot
{
#[McpTool]
public function searchKnowledgeBase(string $query): array
{
// Vector Search in Dokumentation
return $this->vectorStore->similaritySearch($query, limit: 3);
}
#[McpTool]
public function createTicket(string $subject, string $description): string
{
// Ticket-System Integration
return $this->ticketSystem->create($subject, $description);
}
public function chat(string $message, array $history = []): string
{
$systemPrompt = "Du bist ein hilfreicher Support-Agent. Nutze die Knowledge Base für Antworten. Erstelle Tickets nur wenn explizit gewünscht.";
return $this->agent->call($message, $systemPrompt, $history);
}
}Aufwand: ~20-30 Entwicklungsstunden (inklusive RAG-Setup)
Monatliche Kosten: Ca. 30-80€ bei 500-1.500 Chats/Monat
Zusammenfassung: Was Ihr jetzt tun solltet
Die PHP-LLM-Landschaft ist Ende 2025 erwachsen geworden. Statt fragmentierter Community-Projekte gibt es jetzt offizielle Standards und production-ready Libraries.
Für Teams mit bestehenden php-llm/llm-chain Projekten:
- Migration zu Symfony AI einplanen (Q1 2026 empfohlen)
- Testabdeckung erhöhen vor Migration
- Stufenweises Rollout mit Monitoring
Für Neuprojekte:
- Direkt mit Symfony AI starten (symfony/ai-platform, symfony/ai-agent)
- Offizielles MCP SDK für Tool-Definitionen nutzen (mcp/sdk)
- Framework-agnostisch bleiben durch MCP-Standard
Der technische Sweet Spot 2026:
- Symfony AI Platform für LLM-Provider-Abstraktion
- MCP SDK für standardisierte Tool-Definitionen
- Symfony AI Agent für komplexe Multi-Step-Workflows
- Symfony AI Store für RAG und Vector Search
Das Ökosystem ist jetzt reif genug für production-kritische Anwendungen. Die Zeiten von "experimentell" und "API-breaking-changes" sind vorbei.
Weiterführende Ressourcen
- Offizielles PHP MCP SDK: github.com/modelcontextprotocol/php-sdk
- Symfony AI Documentation: github.com/symfony/ai
- MCP Specification: spec.modelcontextprotocol.io
- php-llm/llm-chain (deprecated): packagist.org/packages/php-llm/llm-chain
- PHP Foundation MCP Announcement: thephp.foundation/blog/2025/09/05/php-mcp-sdk/
- Symfony AI Initiative Blog: symfony.com/blog/kicking-off-the-symfony-ai-initiative
Falls Ihr Fragen zur Migration bestehender Projekte oder zur Integration von Symfony AI in Eure Symfony/Shopware-Projekte habt – ich unterstütze gerne bei der technischen Umsetzung.
— Dennis Schwenker-Sanders, Januar 2026