symfony/ai
Symfony AI provides PHP components and Symfony integration for building AI-powered applications. It includes abstractions for AI platforms, agents, tool calling, embeddings, vector stores, and RAG workflows, plus bridges to popular providers and a bundle for quick setup.
Architecture fit. symfony/ai is a component suite, not a monolith: platform/provider adapters, an agent abstraction, message/tool primitives, and store integrations. That decomposition is the main reason it is viable outside Symfony. The parts Laravel would consume are largely plain PHP built on PSR-18/PSR-17 HTTP, PSR-7 messages, and Symfony contracts — all of which Laravel already ships transitively. The Symfony Bundle (symfony/ai-bundle) is the piece to deliberately skip: it assumes the Symfony DI container, configuration tree, and autoconfiguration tags, none of which map to Laravel's container semantics. Treat the package as an SDK, not a framework extension.
The conceptual model (Platform → Agent → Tools → Store → Result) maps reasonably onto Laravel idioms: a Platform factory and Agent factory as container singletons, tools as invokable classes, stores backed by Eloquent or pgvector. The gap is that no one has published that mapping, so it becomes internal, owned code.
Integration feasibility. Composer installation is low-friction in principle because Laravel already depends on a broad slice of symfony/*. The realistic friction points:
symfony/http-client, symfony/event-dispatcher, and symfony/serializer — Laravel pins ranges that may not intersect with a fast-moving 0.x AI package.config/ai.php. You must construct providers/agents manually in a service provider and keep configuration out of the bundle entirely.AIFake-style driver swap) to keep the test suite deterministic and offline.None of these are blockers, but together they represent roughly a one-to-two-week adapter build before the first production use case, plus ongoing drift management.
Technical risk. Moderate, and concentrated in volatility rather than quality:
| Risk | Severity | Note |
|---|---|---|
| Pre-1.0 API churn | High | 0.x release cadence; minors can break; pin exact versions |
| Provider abstraction leakage | Medium | Tool-calling, structured output, and streaming semantics differ per provider; "swap providers" is not free |
| Maintainership | Low–Medium | Symfony-adjacent stewardship is a positive signal; 1,226 stars means a thin community answer base relative to Laravel |
| Tool execution safety | High | Tool calling implies invoking application code from model output — needs allow-listing, argument validation, and authorization checks |
| Cost/latency observability | Medium | Token accounting and per-tenant budget enforcement are not provided out of the box |
| Licensing | Low | MIT; no procurement friction |
Key questions for the team. What is the BC policy between minors, and is there a 1.0 timeline? Does the HTTP layer accept a PSR-18 client we can swap for Laravel's Http facade (for logging, retries, and fakes)? Which store backends are first-class vs. community — and is pgvector supported? Are there lifecycle hooks for token accounting, tracing, and per-call timeouts? What is the documented path for non-Symfony frameworks, or is that explicitly out of scope? How does tool-calling loop termination work — is there a max-iteration guard?
Stack fit. Compatible in principle with Laravel 11/12 on PHP 8.2+, precisely because Laravel's dependency graph already overlaps with Symfony components. The correct posture is "consume components, reject the bundle." Do not attempt to boot the Symfony bundle inside Laravel; the resulting container gymnastics will be brittle and hard to explain to the next maintainer.
Migration path. There is no migration — this is greenfield glue, so frame it as an incremental capability rollout rather than a replacement. Build a thin internal package (app/Ai or a first-party laravel-ai-bridge if reuse is expected) that provides:
config/ai.php with provider credentials, default models, timeouts, retry policy, and per-tenant token ceilings.AiServiceProvider binding a Platform singleton and an AgentFactory, with a driver/environment switch pointing at a fake in testing.RunAgentJob base class so agent loops execute on the queue with explicit timeouts and retry semantics, not in the request cycle.Compatibility management. Pin exact versions ("symfony/ai-*": "0.x.y"), commit the lockfile, and gate upgrades behind a scheduled PR rather than a floating constraint. Run composer why-not before each bump to expose transitive conflicts with illuminate/*. Consider composer require --dev a compatibility smoke test that boots the container and instantiates a fake agent.
Sequencing. Deliver in this order, each stage independently shippable:
Maintenance. Expect ongoing glue maintenance rather than passive dependency consumption. Budget roughly 0.2–0.5 FTE during the first two quarters, tapering to upgrade-and-monitor cadence. The primary cost driver is not Symfony releases but provider API drift — model deprecations and parameter changes will force adapter updates regardless of package stability.
Support. Documentation is Symfony-flavored and framework-neutral at best; there will be no Laravel-specific tutorials and few Stack Overflow answers at 1,226 stars. Institutional knowledge concentrates in whoever builds the adapter, which is a real bus-factor risk. Mitigate with an internal README covering the container wiring, the fake driver, and the upgrade runbook.
Scaling. Agents are stateless per invocation, so horizontal scaling is straightforward if execution is queued. The scaling constraints are external: provider rate limits, per-minute token quotas, and latency variance. Streaming responses are the exception — they require Octane/Swoole or careful SSE handling under FPM, and they pin a worker for the duration. Vector stores should reuse existing infrastructure (pgvector) rather than introducing a new datastore; otherwise a search feature quietly becomes a second platform to operate.
Failure modes to instrument explicitly:
Ramp-up. A mid-level Laravel developer should reach productivity on a single-provider, single-call use case in one to two weeks, most of which is container wiring and testing strategy rather than AI concepts. Tool-calling and multi-step agents add three to four weeks and require review from someone who understands injection and authorization boundaries. The package itself is not hard to learn; the absent Laravel-native documentation is the real ramp-up tax, and the internal adapter is what converts that tax into a one-time cost.
How can I help you explore Laravel packages today?