Submind YouTube summaries
Thumbnail for PHP & AI: Beyond the Hype - Christopher Hertel

PHP & AI: Beyond the Hype - Christopher Hertel

Watch on YouTube

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.