Adding an AI Chatbot to a Laravel or Symfony Application
Adding an AI chatbot to an existing PHP app does not mean rewriting your backend in Python. Here is a concrete architecture for wiring an LLM into Laravel or Symfony without unnecessary complexity.
Most AI chatbot tutorials assume a Python backend. In reality, most business applications run on Laravel or Symfony, and there is no reason to rewrite them just to add a chat feature. The LLM lives behind an API,your existing PHP backend stays the entry point.
Architecture: where the LLM lives
Two realistic options. First: call a provider's API directly (OpenAI, Anthropic, Mistral) from Laravel/Symfony over HTTP,simplest, no AI infrastructure to manage. Second: route through a dedicated Python microservice (FastAPI) once RAG logic gets complex,clean decoupling, but one more service to operate.
// app/Services/ChatService.php
final class ChatService
{
public function __construct(private readonly Http $http) {}
public function ask(string $question, array $history = []): string
{
$response = Http::withToken(config('services.anthropic.key'))
->withHeaders(['anthropic-version' => '2026-01-01'])
->post('https://api.anthropic.com/v1/messages', [
'model' => 'claude-sonnet-5',
'max_tokens' => 1024,
'messages' => [...$history, ['role' => 'user', 'content' => $question]],
]);
return $response->json('content.0.text');
}
}Stream the response instead of waiting for it
An LLM call can take several seconds. Waiting for the full response before showing anything hurts the experience,streaming tokens as they arrive via Server-Sent Events (SSE) gives an immediate feeling of responsiveness, even though full generation takes the same time.
- ✓Laravel: `response()->stream()`, flushing after each chunk received from the LLM.
- ✓Symfony: `StreamedResponse`, same principle,write to the output buffer as data arrives.
- ✓Frontend: consume the stream via `EventSource` or `fetch` with a `ReadableStream`, no polling.
Business context: the real work is not the LLM call
Most of the work is not calling the model's API,it is giving it the right context. Inject relevant application data (customer history, product catalog, internal docs) into the prompt, or wire up lightweight vector search (pgvector, directly inside PostgreSQL, no extra service) before calling the LLM.
Never give the LLM direct write access to your database through unvalidated function calls. Any destructive action (cancel an order, delete an account) must go back through your existing business layer with its own validation rules,the LLM proposes the action, your code executes or refuses it.
Cost, latency, and fallback
- ✓Cache answers to frequent questions,no need to re-pay for an LLM call on the same question asked a hundred times.
- ✓Always have a fallback response (static FAQ, contact form) if the LLM times out or fails.
- ✓Track token usage per user to avoid unpleasant billing surprises at scale.
A well-integrated AI chatbot in existing Laravel or Symfony only adds a thin layer,an HTTP service, a streaming endpoint, some business context. The rest of your architecture, your auth, your database, your business rules, stays unchanged.
Need help with this topic? AI & RAG Integration
Discover this service →