<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/symfony-ai-in-practice-building-a-writing-assistant-for-dyslexic-adults-kkudu0e2t" -->

---
title: Symfony AI in Practice: Building a Writing Assistant for...
description: A hands-on walkthrough of building an AI-powered writing assistant for dyslexic adults using the new Symfony AI component (symfony/ai-bundle, version 0.12). It...
canonical: https://daily.dev/posts/symfony-ai-in-practice-building-a-writing-assistant-for-dyslexic-adults-kkudu0e2t
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Symfony AI in Practice: Building a Writing Assistant for Dyslexic Adults | daily.dev
og:description: A hands-on walkthrough of building an AI-powered writing assistant for dyslexic adults using the new Symfony AI component (symfony/ai-bundle, version 0.12). It...
og:url: https://daily.dev/posts/symfony-ai-in-practice-building-a-writing-assistant-for-dyslexic-adults-kkudu0e2t
og:image: https://api.daily.dev/og/posts/KKudU0E2T.png
og:image:alt: Symfony AI in Practice: Building a Writing Assistant for Dyslexic Adults
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Symfony AI in Practice: Building a Writing Assistant for Dyslexic Adults

**[marmelab](https://daily.dev/sources/Marmelab)** · 10 min read · 1 upvotes · 0 comments

## Summary

A hands-on walkthrough of building an AI-powered writing assistant for dyslexic adults using the new Symfony AI component (symfony/ai-bundle, version 0.12). It covers configuring agents via ai.yaml, using structured output to map LLM responses to PHP DTOs, text-to-speech via the Platform component, a coach chat built with Symfony UX Turbo (no JavaScript framework needed), translating prompts alongside UI strings, tool calling to ground the coach's grammar rules, switching between OpenAI and Mistral providers via configuration, profiler integration for debugging LLM calls, and testing with an InMemoryPlatform stub. The author concludes Symfony AI is a strong contender among AI SDKs, praising its low boilerplate and native Symfony feel, while noting it is still pre-1.0 and subject to API changes.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://marmelab.com/blog/2026/09/29/symfony-ai.html>

## Questions this post answers

### How do I get structured JSON output from an LLM call in Symfony AI instead of parsing free text?

Symfony AI's structured output feature accepts a PHP class as the response_format option instead of prompting for JSON and parsing it manually. You define a DTO class (e.g., a Mistake class) whose property docblocks become the description fields of the generated JSON schema, guiding the model to fill each field correctly, and the agent call hydrates the response directly into that DTO.

_daily.dev surfaces practical Symfony AI patterns like this for developers wiring LLM output into typed PHP code._

### How can I switch between OpenAI and Mistral models in a Symfony AI app without changing PHP code?

Add the provider's bridge package (for example symfony/ai-mistral-platform) and a config block in ai.yaml, then split each agent into one version per provider sharing the same prompt (e.g., coach_openai and coach_mistral). A small ModelRouter service maps a UI-selected provider to the matching agent, so model names and prompts stay entirely in configuration with no hardcoded model strings in PHP.

_Developers comparing LLM providers can track config-driven approaches like this via daily.dev before committing to one._

### How do you prevent an LLM coach agent from making up incorrect grammar rules?

Attach a tool to the agent that looks up curated rule cards stored in YAML files, using the #[AsTool] attribute so the model calls lookup_rule with a valid ruleId instead of inventing an answer. An input processor builds the list of available rule IDs into the system prompt at runtime from the rules files, so the catalog never goes stale as cards are added.

_daily.dev helps developers building grounded LLM agents keep up with tool-calling patterns like this._

## Similar posts on daily.dev

- [Introducing AI Skills for Symfony UX \(Symfony Blog\)](https://daily.dev/posts/introducing-ai-skills-for-symfony-ux-symfony-blog--xsseazqgh) · Symfony · 14 upvotes · 0 comments
- [SymfonyCon Amsterdam 2025: Developing the developer: Journaling with AI \(Symfony Blog\)](https://daily.dev/posts/symfonycon-amsterdam-2025-developing-the-developer-journaling-with-ai-symfony-blog--xi0ru6tpk) · Symfony · 1 upvotes · 0 comments
- [A Developer's Practical Guide to Integrating AI Tools in Modern Web Development](https://daily.dev/posts/a-developer-s-practical-guide-to-integrating-ai-tools-in-modern-web-development-tx3erth6r) · SitePoint · 0 upvotes · 0 comments

---

Tags: [#llm](https://daily.dev/tags/llm), [#ai-agents](https://daily.dev/tags/ai-agents), [#php](https://daily.dev/tags/php), [#symfony](https://daily.dev/tags/symfony)

[View this post on daily.dev](https://daily.dev/posts/symfony-ai-in-practice-building-a-writing-assistant-for-dyslexic-adults-kkudu0e2t)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Symfony AI in Practice: Building a Writing Assistant for Dyslexic Adults","url":"https://daily.dev/posts/symfony-ai-in-practice-building-a-writing-assistant-for-dyslexic-adults-kkudu0e2t","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/symfony-ai-in-practice-building-a-writing-assistant-for-dyslexic-adults-kkudu0e2t"},"datePublished":"2026-09-29T12:43:44.093Z","dateModified":"2026-09-29T12:44:07.983Z","description":"A hands-on walkthrough of building an AI-powered writing assistant for dyslexic adults using the new Symfony AI component (symfony/ai-bundle, version 0.12). It...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/c0ca25be9621658ed57fe7ca1a67f140?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/c0ca25be9621658ed57fe7ca1a67f140?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"marmelab","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"marmelab","logo":"https://media.daily.dev/image/upload/s--AeMXoaI9--/f_auto/v1716621144/logos/Marmelab","url":"https://daily.dev/sources/Marmelab"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/symfony-ai-in-practice-building-a-writing-assistant-for-dyslexic-adults-kkudu0e2t","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"llm,ai-agents,php,symfony","timeRequired":"PT10M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"marmelab","item":"https://daily.dev/sources/Marmelab"},{"@type":"ListItem","position":3,"name":"Symfony AI in Practice: Building a Writing Assistant for Dyslexic Adults"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/symfony-ai-in-practice-building-a-writing-assistant-for-dyslexic-adults-kkudu0e2t#faq","mainEntity":[{"@type":"Question","name":"How do I get structured JSON output from an LLM call in Symfony AI instead of parsing free text?","acceptedAnswer":{"@type":"Answer","text":"Symfony AI's structured output feature accepts a PHP class as the response_format option instead of prompting for JSON and parsing it manually. You define a DTO class (e.g., a Mistake class) whose property docblocks become the description fields of the generated JSON schema, guiding the model to fill each field correctly, and the agent call hydrates the response directly into that DTO. daily.dev surfaces practical Symfony AI patterns like this for developers wiring LLM output into typed PHP code."}},{"@type":"Question","name":"How can I switch between OpenAI and Mistral models in a Symfony AI app without changing PHP code?","acceptedAnswer":{"@type":"Answer","text":"Add the provider's bridge package (for example symfony/ai-mistral-platform) and a config block in ai.yaml, then split each agent into one version per provider sharing the same prompt (e.g., coach_openai and coach_mistral). A small ModelRouter service maps a UI-selected provider to the matching agent, so model names and prompts stay entirely in configuration with no hardcoded model strings in PHP. Developers comparing LLM providers can track config-driven approaches like this via daily.dev before committing to one."}},{"@type":"Question","name":"How do you prevent an LLM coach agent from making up incorrect grammar rules?","acceptedAnswer":{"@type":"Answer","text":"Attach a tool to the agent that looks up curated rule cards stored in YAML files, using the #[AsTool] attribute so the model calls lookup_rule with a valid ruleId instead of inventing an answer. An input processor builds the list of available rule IDs into the system prompt at runtime from the rules files, so the catalog never goes stale as cards are added. daily.dev helps developers building grounded LLM agents keep up with tool-calling patterns like this."}}]}
```

