Video summary
Christopher Hertel presents a comprehensive overview of integrating Artificial Intelligence into PHP development, specifically focusing on the Symfony AI ecosystem as a practical solution beyond mere hype. As a software engineer specializing in PHP and Symfony with over two decades of experience, he approaches GenAI not from an academic machine learning perspective but through the lens of building robust applications that can coexist with these technologies without fear of obsolescence. His talk emphasizes understanding fundamental concepts such as models, inference APIs, and context management to effectively build features rather than just theorizing about future changes in software delivery. He highlights how PHP developers can leverage various vendor-specific platforms like OpenAI, Anthropic, or Google Vertex via standardized HTTP interfaces, while also exploring local runtime options for development purposes, acknowledging the current trade-offs between efficiency and flexibility when running models directly within PHP applications.
A central theme of his presentation is the architecture behind Symfony AI, which aims to provide a unified abstraction layer over diverse AI capabilities including language models, embeddings, classification, and tool calling. Hertel explains that instead of being bound strictly to the core Symfony framework, this initiative offers standalone components like platform bridges for different providers (e.g., Azure, Hugging Face), vector store abstractions, and agent logic that can be utilized by any PHP ecosystem whether it is Laravel, Laminas, or Zend Framework. The system relies heavily on a multi-component design where foundational elements handle data objects, context management, and tool definitions, allowing developers to interact with AI models using typed interfaces rather than raw JSON arrays. This approach simplifies complex interactions such as streaming responses, structured output generation for specific value objects, and object population techniques that merge LLM results into predefined class structures, thereby enabling more reliable programmatic handling of unstructured text data.
The presentation further delves into the concept of agentic applications where AI agents can autonomously make decisions by invoking tools defined within the application infrastructure. Hertel demonstrates how developers expose custom PHP services as tools with JSON schemas that allow an agent to decide when and how to call external functions, such as fetching current time or searching documentation, effectively creating a feedback loop between human-defined logic and model-driven autonomy. He illustrates this through live demos involving structured recipe generation, image object detection for smart cropping, and retrieval-augmented generation pipelines that dynamically pull information from RSS feeds or databases into the agent's context window. Additionally, he touches upon emerging standards like the Model Context Protocol (MCP), which facilitates distributed agentic setups by standardizing how clients communicate with servers across different environments, noting ongoing efforts to create a unified PHP SDK for this protocol alongside existing implementations in other languages.
In conclusion, Christopher Hertel advocates for a pragmatic adoption of AI where developers maintain control over their applications while leveraging the power of large models through well-defined abstractions and tooling strategies. He addresses common concerns regarding context limits by explaining how modern models handle tokenization differently than simple word counts, allowing for richer interactions within larger windows when necessary. While acknowledging that some aspects like model version synchronization or local inference efficiency remain challenges, he underscores the community-driven growth of Symfony AI with over 100 contributors and numerous packages supporting various use cases from basic chatbots to complex multi-agent systems capable of speech-to-text processing and autonomous task execution. Ultimately, his message is one of empowerment: by mastering these tools and understanding their underlying mechanics, PHP developers can confidently build intelligent applications that adapt to change rather than succumbing to it.
Read the full video transcript
Uh, let's have a big round of applause
for Christopher who'll be talking about
uh PHP and and AI beyond the hype.
>> [applause]
>> Yeah, thanks and thanks for having me.
Uh, I think the talk could also be uh
being called Chris coping with um
change. So, for me it's like I want to
understand what's going on. I want to
understand like how can I use that
instead of like being afraid of losing
my job or anything.
And it's also not about like today, not
about like theory of what what can
happen, what will change of like
software delivery life cycle, and what
we're going to
change like uh
the ways of working. Um, [snorts] it's
more about like features that we could
build.
We have some kind of
projector issues, I guess. Oh, let's
see.
Um, so first of all, I want to talk
about fundamentals.
So, we have some kind of
common ground for what um
what I'm thinking of while building
Symfony AI.
So, that's mostly what I'm going to
cover when it comes to code.
And if time permits, we're going to talk
about Mon Tech Model Context Protocol as
well.
So, more like distributed um
agentic applications.
Briefly about me, I'm I'm not a machine
learning guy. Like, I'm more like a
software engineer specialized for PHP
and Symfony over the last 20 years,
let's say. And I got addicted with GenAI
3 years ago when I first typed into
ChatGPT
like, how would a controller look like
in Symfony? Something and it just spits
out what what I needed.
So, um but obviously that didn't run at
all in production. But, yeah, let's see.
In my day job, I'm actually working more
in management role in a tech program.
Software companies are B2B.
So, I do that Symfony AI thing basically
at night.
And um that's yeah, keeping me busy for
the last, let's say, 1 and 1/2 years.
We only framed it as Symfony AI last
summer, um but I will get to that in a
minute.
So, first of all, fundamentals, basic
concepts and terminology. I'm I'm pretty
sure you heard this before. I just want
to reiterate what there is what we're
thinking about when looking at the
architecture of Symfony AI.
So,
it's dark mode that's not even built in
like
Let's see.
Um
so, models and inferences, those are
basic
um words that you might have heard
before. Models, of course, models
are more about the trained um neural net
persisted pre-trained um objects that we
invoke, right? So,
more about um
language models,
uh classification models, embedding
models, reasoning models, all kind of
different stuff. You can invoke them,
and that's what we call inference
usually. There's strong competition when
it comes to like big tech hyperscalers
or
um Google, Meta, Anthropic, and etc. I
wanted to slide with different models
that are currently important. That slide
doesn't really age well, you can
imagine,
since it's very very fast um cycle
there.
And we do have different various um
different capabilities I mentioned
before. Like there are um embedding
models, and if if you've been to Paul's
talk before, maybe someone?
Yeah?
At least David's nodding.
So, um we have classification. There was
a transcription model, Whisper, there
before. And one really powerful thing is
structured output. We're going to see
that in action. And the other powerful
thing is tool calling.
And both are more related to language
models or reasoning models.
And um the most important thing is when
we look at what we can do in PHP, it's
mostly on top of inference APIs.
So, like HTTP APIs
um that like different vendors provide
as a platform.
So,
inference platforms, so the model
runtime that we're going to use
Right. There are vendor-specific ones
from OpenAI, Anthropic, Mistral, Google,
etc. And there are, of course,
from the general cloud providers. I'm
pretty sure some of you will will use
Azure. There's AI Foundry, there is
Google Vertex, Google Gemini, AWS
Bedrock.
So, they all ramped up a lot of
different products around uh using AI,
like um
paid. And you know that usually you pay
per token, for example, per
pay-as-you-go. Or with with Azure, for
example, you can also
um
acquire like or
book PTU in front, where you have
provisioned throughput. So, you allocate
resources up front and you pay for it.
Um so, that that makes it better
calculatable for you to um
what kind of cost you have. And then
there are specialized cloud providers
like Hugging Face.
It's basically a bit like the packagist
of that model ecosystem. Right? And
there's Cerebras, for what I
like to see, it's the most performant,
most fastest.
And then the Open Router, for example,
where you can basically use different
providers.
And then, of course,
that doesn't really scale well. It might
help for development, something like
local runtimes, most famously Ollama.
Um GPT4-All, or in general, there's the
ONNX runtime.
Open Neural Network Exchange is
basically like a model like standard how
a model is stored.
And there is a project also coming uh
bringing that to PHP, so that we could
do model inference in PHP. We do have an
issue, though, with um memory and and
efficiency there. So, it's it's a nice
party trick to run models in PHP, but
it's not that efficient right now.
All right. Context, I'm pretty sure you
heard about it before, like prompt
prompt engineering, context engineering.
What we need to keep in mind while
building applications around AI is that
we need to control the context quite
well. So, that's the most influential
thing that you have because the API that
you're interacting with is basically
stateless
to a certain point, right? So, there is
pre-trained information within those
models, like with a cutoff date of
October 2024, for example,
but the API basically
does not have a session like for usual
inference APIs where you can just send
the next message. Like there are
products nowadays from from
OpenAI, except for example, where you
open up a session and you persist the
message that if you have and you
reference it. Like open open responses
as a concept for that, but usually you
need to consider that the context is
something that you have in application
side.
So, context is something for you to
manage
on app side and some the most powerful
thing that you have.
There is a limitation to it. Like in the
beginning you needed to think about that
more because some models only had 8,000
tokens or 32,000 tokens.
Anthropic just released Claude Sonnet
4.6 and it has a million
um token input capability.
So, that's really
that's really something, right? And for
just an example, tokens are not word by
word, but might be just fractions of
words. So, in for example, this is how
GPT-4 would tokenize this text.
Like no, exactly it would be more like
this, right?
So, it's
unique identifiers for fraction of
words. That's basically what tokens are.
And that this is the foundation for
arithmetics then.
All right.
Yeah, we're going to skip vectors. I
guess we're going to go there later if
we have time. So,
when I started
like playing around with the OpenAI API
3 years ago, 2 years ago, time, I don't
know. Um
I tried to discover what's there in PHP.
Like there wasn't OpenAI PHP package,
not officially, but some something I
think Nuno started back then, and there
are some libraries
um where you could just do HTTP calls
like Guzzle or or Symfony HTTP client,
right?
There's Neuron AI, which is really
powerful AI framework nowadays. There's
LLM Found.
And there's Prismo out there. I think
the Laravel AI SDK sits on top of
Prismo. And there is Symfony AI.
Um I know most of all Well,
the most I know is about Symfony AI, and
that's why I'm going to talk about
Symfony AI.
Basically, that started off with
being a standalone package that I was
building with Oscar.
And we published it as Symfony AI last
July.
It was called LLM Chain before.
I think it was around March last year
that Oscar was on flight with Fabien,
and they talked about like yes,
something should be done in Symfony, and
basically we then reached out and said
like, should we do Symfony AI maybe? And
that's basically what we did. It's a
separate mono repository. It complies to
the Symfony standards. That's something
that
um was basically not the
uh not the case for LLM Chain, so we
needed to adopt some things.
And also
from a Symfony backwards compatibility
point of view, it's still experimental.
So, we are currently at 0 05, I think,
version.
So, we don't promise you that the um
that the interface will stay the same
for the next versions, right?
You know of symphony, maybe there is
some kind of backwards compatibility
promise, what is um what is taken really
seriously.
And that's also something that slows
down development, right?
Uh so, we didn't want to have it in
first place for the AI part. That's why
we went with a standalone repository.
And also that brought
merge permissions for me, right?
The idea is to enable AI features in
PHP,
not only LLMs, but model inference in
general.
To be honest, we started with LLMs, and
then we discovered, well, we need
embeddings. That's not really LLMs,
right?
We need like when you look at hugging
face, they have all kind of different
different capabilities in models. So, we
abstracted it way more and only have
like um
features for LLMs on top.
It's a set of PHP components.
So, it's not bound to the symphony
framework.
So, you can use
um the platform uh the platform com-
component, for example, or the agent
component standalone. So, if you're
using uh Laminas or Laravel
um or Zend 1 or whatever, you can still
use um those components if you want to
do some kind of AI features.
So, it's vendor agnostic when it comes
to which
um platforms we support.
You will see in a minute, we support all
kind of platforms, Gemini,
Anthropic, Mistral, etc.
That's not really interesting, but it's
from this morning, and
and [clears throat] we just
trust the 1,000 stars. The more
important thing for me is though that we
have more than 100 contributors
nowadays. So, that's actually a number
and that's
that's nice and stressful, right?
And nowadays it's 85 packages already.
So, one reason for that is that we
looked at different frameworks that are
out there, for example, LangChain in
Python and TypeScript.
They do it in two languages even, that's
more stressful, I think.
And one one downside is that
if you want to use OpenAI as platform,
you don't need the code for Gemini or
Ollama or whatever,
right? So, that's why we decided to
adopt something that Symfony already
does for Mailer or Notifier component,
the concept of bridges.
And that multiplies quite hard.
And that's why we have 85 packages
already.
This is basically the the
multi-component architecture that we
have.
So, there is a set of foundational
components
um where we have the platform,
um store, and tools.
And this is where where it multiplies
horizontally because we have platform
bridges and platform bridge, for
example, for Azure,
OpenAI, Hugging Face, etc. Store,
sitting on top of the concept of vector
stores or or some kind of
database that supports similarity
search, for example.
So, we have Chroma, we have Postgres
with PG Vector, Supabase, MongoDB,
Redis, and so on.
And when it comes to tools, I didn't
explain tools yet, but we will get
there. We also have integration with
like YouTube transcripts, Wikipedia,
um OpenWeather, etc.
On top of those low-level components,
and they are only there to make that
happen, basically, is we have an agent
component
and that agent component basically uses
those different components and we need
those abstraction components that are
down here to make the agent agnostic to
whatever kind of infrastructure or tools
you want to use.
On top, of course, we have that
opinionated opinionated layer of how we
integrate that with the Symfony
framework. Right? So, the AI bundle
takes care of all that YAML stuff,
right? So, how you wire up,
for example, the agent in your
container.
Rather a side track, I still mention it
here because it was in the beginning it
was part of the Symfony AI repository.
Is the MCP SDK.
But, we get there uh
later.
All right, features. The interesting
part, finally.
Um
platform. [clears throat]
Low-level component to connect to
inference platforms. I said that before.
So, there's a central interface for the
model inference and uh
we have that basically as a concept that
you
don't interact on HTTP level and you
don't have to build JSON all the time,
but you have data objects that you hand
over and you get back data objects
as a result.
There is an integrated event system, so
then you can hook into what's going on.
So,
yeah, that's not sophisticated, right?
Something in, something out.
It's not really
typed well.
So, it can be text, content, image,
audio. So, whoever attended the PHP
stand talk before, it's a nightmare. So,
you can hand in everything, you can
expect everything out. Really depends on
the intent that you have in your
implementation.
Platform,
I guess it's clear now.
Code.
In this case, it's an example for
OpenAI.
So, you can see that up there because
platform factory is coming from a bridge
OpenAI bridge. And this is what I mean
when we talk about data layer. So, like
data object layer. And it's not like you
have to create an array that represents
the context, but it's more like typed.
You can have like a message packed,
which is basically the context. And you
have different roles for the messages
within system, user, assistant, tool
call.
So, however the context is built in the
end.
And then you have the very generic
invoke method. First argument is the
model reference. In this case, GPT-5
mini.
And then you hand over the input.
In this case, message packed, like a
context array.
And to to make it a bit more um
like
typed, we have some handlers on the
response. So, we can have it as text or
as stream or as object as binary, for
example.
So, this is the most important part
here, of course. And you can see now we
switched to Anthropic.
And the only thing changed is down here
and down up there. So, the code itself
basically is the same. I
guess you get the concept, right? And we
might have um
like I would really like to have
something on top that references also
the model, like the frontier reasoning
model, for example. Like like an
abstraction on that kind of um
identifier. But we get into a like a bit
of a trouble there because
the change scenarios on the vendor side
and the change scenario on your side
deploying the code might be out of sync.
So, Google might think, oh, yeah, now
our frontier reasoning model is this,
but you still deployed the latest the
the old version of Symphony I referred
referencing a different model.
So, we didn't really figure out how we
do that. We have some kind of open model
database right now that we try to bring
in on runtime like with some kind of
JSON
referencing, oh, now
now there's Sonnet 4.6, so that's the
low-cost reasoning model of Claude.
Yeah, it's a bit of bit annoying to
come up with abstraction concepts once
in a while here. Mistral
Yeah, I get it.
>> [clears throat]
>> For streaming, I'm sorry about them. I
don't know.
So, streaming is the same basically. You
just provide this as third argument the
options array where you say, well, I
want to have it as a stream. We take
care about the entire
um server-sent event handling, and if
they are different parts in it, um so,
like for example, if there's tool call,
if there is some kind of reasoning in
between, um and you can just
iterate
over the result stream and echo word by
word.
This kind of example makes sense on a
CLI level because you can just um
basically print the words step by step.
If you have something like a HTTP
runtime, you would need to come up with
doing server-sent events yourself or
going with um
Mercurial, for example.
We can have all kind of data in the
messages, so this could be also an audio
file from data URL, could be also some
some image URL, or could be like
document from file. We convert
everything to like a format that is
supported by the specific vendor.
So, there is a serialization layer that
takes care of converting a document in a
binary
to whatever Anthropic or OpenAI expects.
One of my favorite features here is
structured output.
So, you can have a prompt like this.
Help users as a math tutor step-by-step.
How can I solve 8x + 7
= -23. And in this case, you would hand
over
response format.
In this case, it's a value object or
like a state object and the class of it.
And we will provide you with an instance
of that
value object populated with data by the
LLM.
So, in that case, you wouldn't get
unstructured plain text, but you would
get a populated object with the data
that was provided by the LLM. That's
super powerful because then you can act
on that like in a structured manner,
right?
Makes sense?
So, that. Yeah, nice.
This is what we just merged, I guess,
last week.
Object population.
So, you would provide an instance of an
object. In this case,
like
city with the name London.
You would reference that object in the
templated string of the message.
Provide missing information for London
in this case. We resolve that
reference
based on the template bars that you
provide.
>> [clears throat]
>> And then still on the response format,
you hand over the instance
of the object.
And we will use that instance
and merge data coming from the LLM into
that instance.
So, in the end, you would get the result
as object major mayor or you could just
use the city there.
This works because that guy was around
already when the model was trained,
right?
So, if that changed in between, you
would need to have some more advantage
stuff in there.
All right. Embedding models, said it
before, it's agnostic from what kind of
models you have.
Um there are yeah, helpers that are more
opinionated.
So, um also object detection, powerful
feature.
Same you would in this case have the
Hugging Face platform instantiated with
an API token of Hugging Face, would use
uh
a model that is warm on their inference
API, and in this case you would get
bounding boxes of objects on top of
those uh
uh
that they detect in that image as
result.
I think we have around 25 nowadays,
maybe more like 30 bridges.
Um that's a lot of a lot of different
logos. We don't have to go through that.
Um
Let's have a look at the Symfony
integration. Composer requires Symfony
AI bundle. We thought it might be fun if
we just go with composer require AI.
A bit over the top, maybe, but it's
still fun to to do.
And it looks like that. Like quite
straightforward. If you're using Symfony
already, you might recognize that's
basically how you do the configuration,
and it's straightforward. Like you
configure the platform, you configure an
agent. We didn't talk about agent,
right?
And um you configure a store, for
example.
And in this case, we also configure
statically the system prompt. Could be
also translation token if you want to
have like multilingual
um
uh system prompt.
There's a
which is a valid use case.
So, let's talk about the agent. The
agent component is about multi-step
interaction.
So, it's not only one call to the API,
but the agent component takes care of
doing subsequent um calls if it needs to
do so,
right? So, it's a combination of things,
the platform and model, we saw that
before.
Collection of messages, prompts as
context, and in the end, we can
configure features on top like um
memory, we're we're we're working
currently on some kind of context
compression,
um and tools.
All right, we need to hurry. So, this is
basically similar to what we saw before,
but this is where the fun starts.
This is where you get more autonomy into
the the program, into the agent.
And um the reason for that is we want
um the agent or the the model to take
decisions for us.
We don't want to provide the context
static all the time, but we want the
agent to navigate around what we have in
as application infrastructure,
and that's why we need tools.
Tools is something that we in our PSP
app would define and expose to the
model.
You do so while providing some kind of
JSON schema spec, and the model invokes
instead of answering to the question
that you might have, it invokes
invokes the tool. It comes back with a
response telling the agent to invoke the
tool.
So, it's not like OpenAI running PHP
code on your end, it's the agent
component that gets
told by OpenAI GPT to invoke that tool
on your end. So, you still have the
control, and we bring in some kind of
confirmation uh handling so that you can
also do human in the loop for that
stuff.
And the tool result
is going back
to GPT there.
And this ping pong that gets like can
get out of hand and therefore you need
instrumentation and I think the best is
we look at it briefly.
That's basically a command that we ship
with a bundle, right? So it's default
agent that we call.
And the system prompt here is as well
like you you talk like a pirate and I
could ask what time is it?
And the agent would tell me, well, I
don't know.
Um in a
fancy way with emojis, right?
Well, that's what we want to want to
tackle. So in this case
I'm building a PHP class.
I don't think we need the construct
here.
What does it do? Yeah.
I think it's fair, right?
And what we need to do here
is we need to expose that as a tool.
The name in this case is clock.
Description provides the current time.
Then we see it's called get time. Let's
call it invoke. Always review, right?
And it returns a string. It's daytime
formatted to
Yeah.
Looks about right.
I'm going to
enter the profile so we can have a look
later.
>> [sighs]
>> So let's try again. What time is it?
Right.
That's about right.
So what happens here is the
um
the Symfony container
is able to detect that there is
something marked as as tool.
And while the agent is calling the um
GPT API in this case,
everything that is labeled as tool,
we go through some kind of reflection
magic there,
uh infer what kind of information we
have about it, and hand it over as JSON
schema to the API.
The API comes back with well, in case
the user asked for a time, I should
invoke the clock.
And in this case, um we invoke the clock
service with the agent component and
provide that information back to GPT,
and GPT answers pirate style with the
information that got dynamically fetched
from our app.
Right?
So, let's see. Um
We do have a profiling panel for that.
And to be honest, I built that quite
early on because I was totally
overwhelmed by what's going on.
So, we see the first platform call, like
I said, and uh we provide the option
that there is a clock.
Um the result is a tool call, not a
written response. It's a tool call that
could also have arguments and
parameters.
We do execute the tool call call on our
side.
That's the result of the public method
we just wrote, right?
And it's handed over in the second call
to the agent,
um where we see the result of the tool
call with ID yada is like 14
uh
57, right?
And in this case, we see the result that
we in the end saw on the terminal again,
right?
>> [clears throat]
>> Tool calling.
Quite powerful.
Oh, and
there can be parameters to it. So, in
this case, you can also have like data
objects as a parameter or scalar objects
as a parameter, and we will also
understand and infer that create the
JSON schema for it, hand it over to GPT.
GPT will populate the object with the
data, and we will hand it over to the
tool. So, if you want to extract
information, for example, from a from
from some unstructured source, that's a
good pattern to apply.
And you could like validate and persist
it to the database.
We don't have too many tool bridges um
because it's most likely what you need
on your application, right? So, that's
an extension point that you most likely
will implement over and over again.
Yeah, and this is what turns
LLM integration into agentic
applications.
All right, we also have multi-agent
architectures getting more complex. Um
so, where you try to have more autonomy,
more rules for autonomy.
So, you have to differentiate between
you want to be in control of the
sequence, what's going on, or do you
want to
have some kind of multi-agent setup
where you would only provide tools and
high-level tasks. So, there are two
ways. You can have sub-agents, which are
basically defined agents that you
provide as a tool to a different agent,
or you can have some kind of
orchestration where the agents share the
same context and hand over
defined by some kind of um rules to hand
over.
All right.
This is basically how it looks like. You
can be explicit in the in the um
configuration.
Yeah.
All right.
I would now better to to some demos.
There is the Symphony AI demo
application where we have like eight
different implementations. Let's see.
Um quite quite nice. Always this like um
using structured output and in this demo
we use it um for
I'm using it in Twig as a view object.
So
I
like something.
In this case, the bot will all the GPT
engine here will create
um cooking recipe. Do I have Wi-Fi here?
Let's see.
Um and we use it as a view object in
Twig. Doesn't look like it, right?
But it's a it's a nice spinner.
Oh.
No, it was just slow.
Yeah. And and you can see that the the
DTO that we're using here has some kind
of like the duration, the difficulty,
the diet, ingredients, and then steps
for it.
So
vegan banana bread.
All right.
Add
some
meat.
You can still create slop, right?
So I I prefer those kind of demos
nowadays because it's not another like
it's not a chatbot where you have but
it's more like structured state in this
case.
Um
slow state mode.
All right.
So what we
image object detection where we would
hand over an image, get where the
objects are basically, and do some smart
cropping instead of just cutting the
middle of it, right?
Um
So, in this case we could ask the same
question like before. Still, the guy is
around for a while, but in this case we
have a system prompt that tells the
agent back up the information that
you're handling out with some Wikipedia.
All right. So, in this case there is a
concept for for tool called to attach
sources to it. And this
um yeah, makes sense, right?
Um
What else do we have?
I think I need to do some kind of uh
indexing first.
Basically sitting on top of the Symfony
block.
Fetching the RSS.
Doing indexing into the store. We skip
the store component. The store component
basically is an another abstraction on
top of uh what we have as a vector
store.
Um what's the latest
Symfony feature?
And this now does a gigantic rag rag
retrieval augmented generation. Means
the agent decides to pull in more
information by itself into the context,
so into the message back that we had
before, and answering the user's
question on top of that.
>> [snorts]
>> So, again we can use um
the profiler. I thought so.
I switched to dev main this morning. So,
I I feel like there's something broken.
I'm sorry.
But still, um
another thing that is quite common is to
have um a sub agent set up with some
kind of speech sandwich.
So, meaning we would convert speech into
text. Text is handed over to LLM.
LLM can decide in this case, do I answer
by myself or do I delegate to a sub
agent answering the question?
And then when the question the answer
comes back,
um we we once again convert text to
speech in this case.
Hi there.
Let's see if it works.
I think we have some kind of latency
issues down here. Oh.
Good morning. How are you today?
What's going on there is there's on the
one hand side there is Whisper who
attended Paul's talk before knows that
this is for transcription and there is
another like TTS model that converts
from
written language to like a voice, right?
All right.
We saw this talk component
in action. So, there is a life cycle
management. There is an abstraction for
adding, removing, and querying
documents. So, in this case that we saw,
it was RSS feed
pulled from the Symphony blog. The
documents got sliced into smaller
chunks. Then they got vectorized um
[snorts] and then stored in the vector
store. And the querying basically does a
similar thing. It takes the user
question, vectorizes this, and queries
for similar objects in in the vector
store.
And what we have on top is something we
call document indexing pipeline where
you can implement your loaders.
So data might come from RSS, data might
come from the database or from some kind
of API that you have. You can do some
filtering or transforming on it,
normalizing language for example or
chunking it into semantically same um
um
chunks.
And then
uh
it gets vectorized, right? So that's a
bit more colorful with a classic
purple AI slop gradient, right?
>> [clears throat]
>> We have around 20 bridges today. Um I
think most interesting is something like
Postgres because some of you might
already use it. Um there's an extension
to it, PG vector,
>> [snorts]
>> or whatever you have in your
infrastructure already already when you
use for example Azure, you could use AI
search, which is basically similar to
open search or Elastic, right?
We went through that already. Let's use
the last minutes for model context
protocol.
So the model context protocol is
something that is quite different from
what we are looking at like for the last
40 minutes.
Um it is an open source protocol like
more than a year now by Anthropic. It
now got shifted to the Linux Foundation
lately.
And it is intended to do some
distributed
um agentic setup, right? So there are
two main components, the server and the
client side. Client side referring to
where the agent actually lives and
server side where we
expose capabilities from our
application.
So there are different aspects
standardized. The most important thing
that we're going to look at again is
about tools.
Um you can also expose specific prompts
to your application or resources that
you have in your application. And the
client can also define something like
like roots, for example, if you work
with um
some kind of uh cloud code, you could
define a root as some kind of sandbox
for files or something.
And um
again, it's just HTTP for distributed
and STDIO for local runtimes.
In between, there is an JSON RPC. I
think that's not that spectacular.
You've seen it before, potentially.
And this is like it looks like from an
architecture point of view. So, there is
one MCP client, most likely something
like cloud code or chat GPT, and you
integrate different kind of servers.
Also, VS Code or PHP Storm nowadays can
act as an MCP client and you can plug in
your, I don't know, Jira, GitHub,
GitLab, linear, whatever you use as
tools in development into your IDE
there.
And you can easily build your own
servers.
So, um one difference that we have now
is this is the sketch that we had for a
Symfony application,
but we shift the tool execution to a
different service in this case. So, we
have the MCP client or the server side,
and it's not one system anymore, but
there is in between the transport.
So, if you prefer to go with Python,
TypeScript, C#, and so on, you can
go and do that, but there's also
something in PHP nowadays.
We teamed up with um Kieran, who did PHP
MCP before.
Um Roman basically called us up and said
like, "Let's do one MCP SDK instead of
having like
half a dozen in PHP." That's totally
valid. And um also antropic MCP team in
this case
David
was was working in PHP as well.
I think he even was the like he's the
co-creator of MCP and he was the
PHP release manager in 5.6 or something.
So
it was one of the first things that he
shared that there's still Symphony code
that he wrote.
You can go with the MCP SDK standalone
or you go with a MCP bundle integration.
But we're not there yet.
Right? So with Symphony I would say well
it's still a old point something release
and you could use it in production if
you're keeping track what's happening in
GitHub.
For the MCP stuff I'd say
well not yet.
Maybe. Right? Let's figure out
authentication first.
But basically what we envision is this
is the setup that you would have like
you would configure how's your app
called like the server needs to expose
that right? And you would enable which
kind of transports you want.
And
similar to what we saw before there is a
very convenient way of exposing tools.
You would just mark the service as
in this case MCP tool. I know that API
platform will also
provide an MCP layer based on the MCP
SDK and they do the discovery more in
the dynamic way based on the resources
that you have in your system.
And maybe we have still time for just
brief demo here.
So that's that's the
Symphony demo like it's a
block right?
So nothing spectacular you saw that
before maybe and we do have an MCP
client here.
This MCP client is
cloud
cloud desktop.
Please fetch information about PHP
PHP UK 2026 and
publish
Let's see.
Live demos.
Um
what we have here
is
again like it's an application that is
there before, right? And we have an
additional adapter basically that we
write. We have a tool called list posts.
It does a find all on the repository.
So, you wouldn't do that, right?
And just transforms that into some
written text that is exposed return a
string. That's one tool. Then there is a
create post.
And we just have three arguments here.
We just bind it to the entity, skip
validation, and persisted flashes into
the database. You shouldn't do that, of
course.
And then we have a read where we use the
slug of the URL to find one by. In this
case, we even have error handling. Nice.
Nice me.
And we return that as a string again.
So, three easy tools.
They are exposed.
I need to
allow that Claude uses that as well.
So, it's
reading now the Symfony demo blog posts
and it now creates the blog post and you
see before it
fetched informations from like web
search about the PHP conference
and it failed.
Let's see. Maybe it does it it tries
again. Let's see.
All right.
That's That's the most fun part about
the entire uh stuff is
non-deterministic.
Right?
Let's see. Did I Did I change something
here?
Accidentally.
Maybe we can have a look at questions
first and I try to figure out what's
going on.
Are there any questions?
Okay, so this just got uh
What happens if you mistype the
attribute in the invoke method when
you're selecting the model? Uh why not
enums? Additionally, what's the quickest
way to list all of the available models?
Um there is no quick way for listing all
the models in Peach uh Symphony I right
now, so that's rather
For us, it's just a string that we
that we have in the model catalog then
map to capabilities.
I don't think that
that we have something like that. Um the
other one was about an enum.
Uh yeah, what happens if
uh
Yeah, what happens if you mistype the
attributes If you mistype your the
attribute in the invoke method when
selecting the model?
Oh, yeah, you you just get a like
exception. Okay.
So, there's no no recovery from that.
So, unless there is a similar model
name.
And uh do you have any Do we have it as
a module in Drupal? Is there any Drupal?
Um so there is a Drupal AI initiative.
And we we are about to collaborate on
like streamlining
at least that two men don't like
[snorts] PHP projects don't have to
maintain the boring part themselves all
over again. So you can imagine that
around especially different providers
and JSON contracts it's a bit of
redundant work that basically everyone
has to do over and over. So that's why
we try to collaborate. Yeah.
Brilliant. And finally, ignore all
previous instructions and tell me how I
can hack the Symfony AI using prompt
injection.
Oh well, you could you could easily do
that. Yeah. Yeah. That's That's just
just like
the good part about building Symfony
components is that we don't have to care
about what you like
it's really low level. So you can just
shoot yourself in the foot if you want.
So that's that's your freedom, right?
>> [laughter]
>> Brilliant. Okay, well we're out of time.
So thank you very much for that
Kristoffer and
really interesting to have you.