SEO got you to page one. AEO gets you into the agent's toolkit.
This guide is specifically for Xperience by Kentico (XbK) — the modern .NET Core/NET 8+ headless-first DXP. If you're still on Kentico CMS 12 or earlier, the concepts apply but the implementation differs.
For two decades, we've optimized for search engines. Keywords, backlinks, meta tags, structured data—all designed to answer one question: How do I get Google to surface my content to humans?
That question is becoming obsolete.
AI agents don't Google things. They don't browse search results. They query APIs, parse documentation, and execute tools. The new question is: How do I get agents to discover, understand, and interact with my content?
Welcome to Agent Engine Optimization—and here's how to implement it in Xperience by Kentico.
The Discovery Problem Has Changed
When a human wants information, they:
- Search Google
- Browse results
- Click links
- Read content
- Make a decision
When an agent works on behalf of a user, it:
- Checks its available tools and knowledge sources
- Reads machine-parseable documentation
- Extracts structured data
- Executes actions or returns synthesized answers
No browsing. No clicking. No reading marketing copy. Either your content is machine-readable, or it doesn't exist to agents.
For XbK developers and marketers, this means rethinking how we structure and expose content.
The AEO Stack for XbK
1. llms.txt — The New robots.txt
Just as robots.txt tells search crawlers what to index, llms.txt tells language models what your site is about and how to consume it.
Implementation in Xperience by Kentico:
Create a custom route or use a static file at your root: https://yourdomain.com/llms.txt
// Custom endpoint approach
[Route("llms.txt")]
public IActionResult LlmsTxt()
{
var content = @"# yourdomain.com
> Brief description of your organization and what this site offers
## Content Types
- Product documentation
- Knowledge base articles
- API reference
- Pricing information
## Structured Data
- JSON-LD on all pages
- OpenAPI spec at /api/openapi.json
## Contact
support@yourdomain.com";
return Content(content, "text/plain");
}
Or simply add llms.txt as a static file in your wwwroot.
What to include:
- Clear description of your organization/site purpose
- Types of content available
- Pointers to structured data and APIs
- Contact information
Keep it concise—this is a summary for context windows, not a documentation dump.
2. llms-full.txt — The Deep Dive
For agents that want comprehensive information, provide llms-full.txt with complete content. This might include:
- Full product/service descriptions
- Complete FAQ content
- Detailed specifications
- All the context an agent might need to answer questions about your business
XbK approach: Create a scheduled task or custom endpoint that aggregates content using IContentQueryExecutor:
// Generate llms-full.txt from XbK content items
public class LlmsContentGenerator
{
private readonly IContentQueryExecutor _executor;
public LlmsContentGenerator(IContentQueryExecutor executor)
{
_executor = executor;
}
public async Task<string> GenerateLlmsFullContent()
{
var builder = new StringBuilder();
// Query reusable content items
var query = new ContentItemQueryBuilder()
.ForContentType(ArticlePage.CONTENT_TYPE_NAME,
config => config
.WithLinkedItems(1)
.OrderBy(nameof(ArticlePage.Title)));
var articles = await _executor.GetMappedResult<ArticlePage>(query);
foreach (var article in articles)
{
builder.AppendLine($"## {article.Title}");
builder.AppendLine(HtmlHelper.StripTags(article.Content));
builder.AppendLine();
}
return builder.ToString();
}
}
3. JSON-LD — Structured Data That Agents Parse
You're probably already using JSON-LD for SEO (Schema.org markup). For AEO, it becomes even more critical—and you should expand it.
In Xperience by Kentico:
Create a reusable view component for JSON-LD that works with XbK's strongly-typed content model:
public class JsonLdViewComponent : ViewComponent
{
public IViewComponentResult Invoke(ArticlePage article)
{
var jsonLd = new
{
@context = "https://schema.org",
@type = "Article",
headline = article.Title,
description = article.Summary,
datePublished = article.PublishDate?.ToString("yyyy-MM-dd"),
dateModified = article.LastModified?.ToString("yyyy-MM-dd"),
author = new
{
@type = "Organization",
name = "Your Company",
url = "https://yourdomain.com"
},
publisher = new
{
@type = "Organization",
name = "Your Company"
}
};
return View(jsonLd);
}
}
In your view, invoke it with your page's content:
@await Component.InvokeAsync("JsonLd", Model.Article)
Schema types to implement by content type:
| XbK Content Type | Schema.org Type |
|---|---|
| Article / Blog Post | Article, BlogPosting |
| Product Page | Product, Offer |
| FAQ Page | FAQPage, Question/Answer |
| Service Page | Service |
| Event | Event |
| Team Member | Person |
| Company Info | Organization, LocalBusiness |
Go beyond basic SEO schemas. Add:
FAQPageschema for any page with Q&A contentHowToschema for instructional contentItemListfor category/listing pages- Detailed
Productschemas with pricing, availability, reviews
Agents synthesize answers from this structured data. The richer your schema, the more accurately agents represent your content.
4. Headless Channel & API Optimization
XbK's headless-first architecture is a natural fit for AEO. If you're using a headless channel or exposing content via custom APIs, optimize them for agent consumption.
Create a dedicated content API with OpenAPI documentation:
[ApiController]
[Route("api/content")]
public class ContentApiController : ControllerBase
{
private readonly IContentQueryExecutor _executor;
[HttpGet("articles")]
[ProducesResponseType(typeof(IEnumerable<ArticleDto>), 200)]
public async Task<IActionResult> GetArticles([FromQuery] string? category = null)
{
var query = new ContentItemQueryBuilder()
.ForContentType(ArticlePage.CONTENT_TYPE_NAME,
config => config.WithLinkedItems(1));
var articles = await _executor.GetMappedResult<ArticlePage>(query);
return Ok(articles.Select(a => new ArticleDto(a)));
}
}
Publish your OpenAPI spec:
https://yourdomain.com/api/openapi.json
Add Swashbuckle/NSwag to auto-generate it from your controllers.
Document your API in llms.txt:
## API Access
- Endpoint: https://yourdomain.com/api/content
- OpenAPI Spec: https://yourdomain.com/api/openapi.json
- Authentication: API key (contact for access)
5. Semantic HTML Structure
Agents increasingly parse HTML directly. Your XbK views and Page Builder widget templates should output clean, semantic markup:
<article>
<header>
<h1>@Model.Title</h1>
<p class="summary">@Model.Summary</p>
</header>
<main>
@Html.Raw(Model.Content)
</main>
<footer>
<time datetime="@Model.PublishDate.ToString("yyyy-MM-dd")">
@Model.PublishDate.ToShortDateString()
</time>
</footer>
</article>
Avoid:
- Deeply nested divs with no semantic meaning
- Content hidden behind JavaScript interactions
- Important information in images without alt text
- Navigation-heavy pages with little actual content
6. Dynamic Content Considerations
XbK's personalization via Contact Groups and A/B testing creates a challenge: which version of content should agents see?
Recommendations:
- Ensure your default (non-personalized) content is comprehensive
- Consider bypassing personalization for known bot user agents
- Document any dynamic content aspects in your llms.txt
- Don't hide critical product/service information behind personalization rules
- Use Page Builder widgets that degrade gracefully to meaningful content
The AEO Checklist for XbK Sites
Discovery
- ☐
llms.txtat root domain - ☐
llms-full.txtfor comprehensive content - ☐ Clear site description and purpose
- ☐ Sitemap.xml up to date
Structured Data
- ☐ JSON-LD on all content pages
- ☐ Appropriate Schema.org types per content type
- ☐ FAQPage schema on FAQ content
- ☐ Product/Offer schemas with pricing
- ☐ Organization schema on homepage
Technical
- ☐ Semantic HTML structure
- ☐ Clean, parseable content (not locked in JavaScript)
- ☐ Mobile-friendly (agents often use mobile parsing)
- ☐ Fast load times (agents have timeouts too)
API (if applicable)
- ☐ OpenAPI/Swagger spec published
- ☐ Content API documented
- ☐ Authentication method documented
Maintenance
- ☐ Regular content audits
- ☐ Schema validation (test with Google's Rich Results Test)
- ☐ Monitor how AI tools represent your brand
The Mindset Shift
SEO optimizes for attention. You want humans to click, read, engage.
AEO optimizes for accuracy. You want agents to correctly understand and represent your content.
| SEO Thinking | AEO Thinking |
|---|---|
| Write compelling headlines | Write clear, factual descriptions |
| Optimize for keywords | Optimize for structured data |
| Increase time on page | Increase content parsability |
| Convert visitors to leads | Ensure accurate representation |
| Rank for queries | Be the source agents cite |
Why This Matters Now
The first generation of widely-deployed agents is here. ChatGPT, Claude, Copilot—they're answering questions about your products, your services, your company.
Where do they get that information? Increasingly, from crawling and parsing your site.
If your XbK site isn't optimized for agent consumption:
- Agents may misrepresent your offerings
- Competitors with better structured data get cited instead
- You lose influence over how AI represents your brand
This isn't theoretical. Search "your company name" in ChatGPT. See what it says. That's your AEO baseline.
Getting Started
- Today: Add
llms.txtto your XbK site's wwwroot (or create a custom route) - This week: Audit JSON-LD across your content types—use view components for consistency
- This month: Build an
llms-full.txtgenerator usingIContentQueryExecutor - This quarter: Implement comprehensive Schema.org markup and consider exposing a headless API with OpenAPI docs
The sites that optimize for agents now will be the ones agents trust and cite later. AEO isn't replacing SEO—but for content-driven XbK sites, it's becoming equally important.
Mike Rahel builds with Xperience by Kentico at Refined Element and agent-native commerce infrastructure at Lightning Enable.