Adobe AEM

Adobe Agentic AI & AEM Cloud Service: The Complete Enterprise Architecture Guide

23 min read

A comprehensive deep dive into Adobe Agentic AI in AEM as a Cloud Service. Learn how Adobe Sensei GenAI, Firefly, and intelligent agents are transforming content creation, asset management, architecture, and developer workflows.

AEMAIArchitectureAdobe I/OReference
Adobe Agentic AI & AEM Cloud Service: The Complete Enterprise Architecture Guide

If you remember only one thing from this guide, it is this: Adobe's shift to Agentic AI within AEM as a Cloud Service (AEMaaCS) isn't just about adding generative text boxes—it represents a fundamental replatforming of how content is orchestrated, personalized, and delivered at an enterprise scale. Most teams get this wrong because they treat AI as a bolt-on feature rather than an architectural paradigm shift. By leveraging true autonomous agents within AEM, organizations can move from manual content assembly to goal-driven content generation, bridging the gap between Experience Manager, Adobe Target, and Adobe Experience Platform (AEP) natively.

In this exhaustive, production-focused enterprise architecture guide, we are going completely under the hood. You will learn:

  • The precise evolution from legacy Adobe Sensei to Sensei GenAI and the new Agentic AI architecture.
  • How Agentic AI integrates natively into AEMaaCS, including deep dives into JCR implications, Oak repository structures, and OSGi configurations required to connect AEM to Adobe Sensei GenAI via IMS Auth.
  • Real-world architectures for auto-tagging AEM Assets using AI microservices, and how to govern this data effectively.
  • Edge Delivery Services (EDS) and how AI personalizes Edge blocks in real-time, rewriting the rules of the traditional AEM dispatcher.
  • Deep dive into Adobe Firefly API integration, complete with JSON payloads for generation, smart cropping, and outpainting directly from the DAM.
  • Automated Content Generation using the AI Assistant for copy generation, variations, tone adjustment, and maintaining brand compliance.
  • Agentic Workflows for Marketers, detailing how AEM agents orchestrate content delivery and dynamic personalization at scale.
  • Writing custom Adobe App Builder (Adobe I/O) actions in Node.js to act as custom agents for AEM workflows, interacting seamlessly with external LLMs and AEM's core APIs.
  • The security and architecture behind AEM's communication with Adobe's AI microservices, enterprise compliance guardrails, and C2PA content credentials.
  • Developer integration patterns, complete code examples (Java OSGi services, HTL, Adobe I/O Node.js scripts), and operational considerations.

Before we dive into the AI specific architectures, I highly recommend reviewing these foundational concepts if you haven't already. Understanding cloud native AEM is mandatory before introducing AI orchestration:

1. The Evolution: From Sensei to Agentic AI

To understand where we are and why the architecture looks the way it does, we must understand how we got here. The evolution of AI within the Adobe ecosystem can be distinctly categorized into three phases. Understanding these phases is crucial for enterprise architects who need to explain why AEM 6.5 on-premise cannot support the modern AI paradigms without significant anti-patterns.

Phase 1: Adobe Sensei (Predictive & Analytical AI)

Originally, Adobe Sensei was synonymous with machine learning algorithms designed for specific, deterministic tasks. Think Smart Crop, Smart Tags, and basic anomaly detection in Adobe Analytics. In AEM 6.5, Sensei operated via backend microservices that AEM would call synchronously or asynchronously (e.g., during DAM Update Asset workflows).

It was powerful, but it wasn't generative, and it certainly wasn't autonomous. The architecture was fundamentally a "call and response" model. AEM sent an image; Sensei returned a list of tags. AEM sent an image; Sensei returned coordinates for a focal point. The orchestrator was always the AEM Workflow Engine (specifically, the com.day.cq.dam.core.impl.process packages). This meant that scaling AI operations required scaling the AEM JVMs, which led to the dreaded "Workflow offloading" architectures that plagued many AEM 6.x implementations.

Phase 2: Sensei GenAI & Firefly (Generative AI)

With the explosion of Large Language Models (LLMs) and diffusion models, Adobe introduced Sensei GenAI and Adobe Firefly. This allowed authors to generate text variations within the AEM Rich Text Editor (RTE) and generate images natively.

However, this phase was heavily "human-in-the-loop"—the author prompted, the AI generated, the author approved. The architecture shifted slightly. Instead of heavy backend AEM Workflows, the calls to Sensei GenAI were often mediated through the AEM frontend (Universal Editor or SPA Editor) making calls to an Adobe-hosted AI proxy service, which then communicated with the LLM.

This relieved the AEM JVM of the processing burden, but it still required a human to sit in front of the screen. The integration was API-driven but not workflow-driven in the modern sense. It was a productivity enhancement, not a fundamental shift in content velocity.

Phase 3: Agentic AI (Goal-Driven Autonomous Orchestration)

Agentic AI marks the transition from "tools" to "teammates." Instead of asking AEM to "rewrite this paragraph to be more professional," an Agentic workflow allows a marketer to define a goal: "Increase conversion rate for this landing page for the 18-25 demographic in North America."

The AI Agent then:

  1. Analyzes the current Content Fragments and their performance via Adobe Analytics APIs.
  2. Generates new text variations via Sensei GenAI, aligning with the brand guidelines vector database.
  3. Requests new image assets from Firefly, using the original hero image as a style reference.
  4. Assembles an Experience Fragment or Edge Delivery block.
  5. Pushes the variations to Adobe Target for an Auto-Allocate A/B test.
  6. Monitors performance via AEP and continuously iterates, eventually promoting the winning variation to the Master AEM Experience Fragment.

This is true orchestration. It requires an entirely different architectural mindset. AEM is no longer just a repository; it is a state machine for content assets, while the AI Agents operate asynchronously in the cloud, interacting with AEM via its REST/GraphQL APIs.

2. Native Integration in AEM as a Cloud Service

Agentic AI requires the elasticity, decoupled architecture, and microservices ecosystem of AEM as a Cloud Service. You cannot run full Agentic AI in AEM 6.5 on-premise without building a massive, brittle custom integration layer.

The Architectural Shift: Microservices and IMS

In AEMaaCS, AI capabilities are exposed as serverless functions running on Adobe's infrastructure. Access to these services is strictly governed by Adobe IMS (Identity Management System).

Unlike legacy AEM integrations that used basic authentication or shared secrets, modern AEMaaCS uses JWT (JSON Web Token) or Server-to-Server OAuth credentials to authenticate with Adobe I/O, which serves as the gateway to the AI microservices.

+-------------------+       +-----------------------+       +-------------------+
|                   |       |                       |       |                   |
|  AEM Author Tier  +------>+ Adobe API Gateway     +------>+ Adobe AI Agents   |
|  (Cloud Service)  | IMS   | (Adobe I/O)           | API   | (Sensei / Firefly)|
|                   | Auth  |                       |       |                   |
+---------+---------+       +-----------+-----------+       +---------+---------+
          |                             |                             |
          |                             |                             |
+---------v---------+                   |                   +---------v---------+
|                   |                   |                   |                   |
|  Content Repos.   |                   +------------------>+  Adobe Target /   |
|  (JCR / Oak)      |                                       |  AEP / Analytics  |
|                   |                                       |                   |
+-------------------+                                       +-------------------+

OSGi Configurations and IMS Auth required to connect AEM to Adobe Sensei GenAI

To enable AEMaaCS to communicate with Sensei GenAI autonomously (e.g., via a backend OSGi service rather than just a frontend UI call), you must configure the IMS integration. Most teams get this wrong by trying to hardcode credentials.

In AEMaaCS, Adobe manages the core IMS configuration for built-in services, but if you are building custom backend agents that need to call Adobe's AI APIs, you need to set up an IMS Configuration tied to an Adobe Developer Console project.

1. The Adobe Developer Console Project

You create a project in the Adobe Developer Console, add the "Adobe Sensei GenAI API" or "Adobe Firefly API" (or both), and generate Server-to-Server OAuth credentials. You will receive a Client ID, Client Secret, and scopes.

2. The OSGi Configuration

You must configure the com.adobe.granite.auth.ims.impl.ImsConfigProviderImpl for your specific AI integration. This is typically deployed via Cloud Manager in your ui.config project.

File: ui.config/src/main/content/jcr_root/apps/mybrand/osgiconfig/config/com.adobe.granite.auth.ims.impl.ImsConfigProviderImpl~ai-agent.cfg.json

{
  "oauth.authz.server": "https://ims-na1.adobelogin.com",
  "ims.resource.id": "mybrand-ai-agent",
  "ims.client.id": "$[secret:IMS_CLIENT_ID]",
  "ims.client.secret": "$[secret:IMS_CLIENT_SECRET]",
  "ims.scope": "openid,AdobeID,additional_info.projectedProductContext,sao.aem.assets,firefly_enterprise"
}

Note the use of Cloud Manager secret variables ($[secret:IMS_CLIENT_ID]). Never commit the actual client ID or secret to Git.

3. The Java OSGi Service

Now, you can inject the ImsConfigProvider and TokenProvider into your custom Java OSGi service to retrieve an access token before calling the AI API.

package com.mybrand.aem.core.ai.services.impl;

import com.adobe.granite.auth.ims.ImsConfigProvider;
import com.adobe.granite.auth.ims.ImsConfigProviderFactory;
import com.adobe.granite.auth.ims.TokenProvider;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

@Component(service = AIAgentService.class)
public class AIAgentServiceImpl implements AIAgentService {

    private static final Logger log = LoggerFactory.getLogger(AIAgentServiceImpl.class);
    private static final String IMS_CONFIG_ID = "mybrand-ai-agent";
    private static final String SENSEI_API_ENDPOINT = "https://sensei.adobe.io/genai/v1/generate";

    @Reference
    private TokenProvider tokenProvider;

    @Reference
    private ImsConfigProviderFactory imsConfigProviderFactory;

    @Override
    public String generateContentVariation(String originalText, String targetAudience) {
        try {
            // 1. Get the IMS Access Token
            String accessToken = tokenProvider.getAccessToken(IMS_CONFIG_ID);

            // 2. Prepare the Payload
            String payload = String.format("{\"prompt\": \"Rewrite this for %s: %s\", \"model\": \"sensei-genai-v2\"}", targetAudience, originalText);

            // 3. Call the Sensei GenAI API
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(SENSEI_API_ENDPOINT))
                    .header("Authorization", "Bearer " + accessToken)
                    .header("x-api-key", getClientIdFromImsConfig()) // Custom method to extract client ID
                    .header("Content-Type", "application/json")
                    .POST(HttpRequest.BodyPublishers.ofString(payload))
                    .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

            if (response.statusCode() == 200) {
                return parseApiResponse(response.body());
            } else {
                log.error("AI Generation failed. Status: {}, Response: {}", response.statusCode(), response.body());
                return null;
            }

        } catch (Exception e) {
            log.error("Exception during AI generation", e);
            return null;
        }
    }
    
    private String getClientIdFromImsConfig() {
        // Retrieve the client ID from the ImsConfigProvider matching IMS_CONFIG_ID
        // implementation omitted for brevity
        return "extracted-client-id";
    }
    
    private String parseApiResponse(String json) {
        // Parse JSON and return generated text
        return json; // placeholder
    }
}

JCR Node Structures and AI Metadata

When an AI agent modifies a Content Fragment or an asset, it leaves an auditable trail in the JCR. This is critical for enterprise compliance (e.g., proving that a specific piece of legal text was generated by AI and subsequently approved by a human).

A typical Content Fragment modified by an AI agent will have properties under its jcr:content/data/master node indicating the generation source:

<jcr:content
    jcr:primaryType="dam:AssetContent"
    cq:name="hero-banner-copy">
    <data
        jcr:primaryType="nt:unstructured">
        <master
            jcr:primaryType="nt:unstructured"
            title="Summer Sale 2026"
            text="Experience the heat with our new collection."
            cq:aiGenerated="{Boolean}true"
            cq:aiModel="sensei-genai-v2"
            cq:aiPromptHash="a8f9c2e4f5..."
            cq:aiApprovedBy="aman.kumar"
            cq:aiTargetSegment="youth-na" />
    </data>
</jcr:content>

Always ensure your indexing configurations (oak:index) account for properties like cq:aiGenerated if you need to build dashboards reporting on AI-generated vs. human-generated content.

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:oak="http://jackrabbit.apache.org/oak/ns/1.0" xmlns:jcr="http://jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
    jcr:primaryType="oak:QueryIndexDefinition"
    async="async"
    compatVersion="{Long}2"
    evaluatePathRestrictions="{Boolean}true"
    type="lucene">
    <indexRules jcr:primaryType="nt:unstructured">
        <dam:AssetContent jcr:primaryType="nt:unstructured">
            <properties jcr:primaryType="nt:unstructured">
                <aiGenerated
                    jcr:primaryType="nt:unstructured"
                    name="data/master/cq:aiGenerated"
                    propertyIndex="{Boolean}true"
                    type="Boolean"/>
                <aiModel
                    jcr:primaryType="nt:unstructured"
                    name="data/master/cq:aiModel"
                    propertyIndex="{Boolean}true"/>
            </properties>
        </dam:AssetContent>
    </indexRules>
</jcr:root>

3. Deep Dive into Adobe Firefly API Integration

Adobe Firefly's native integration into the AEM Assets Cloud Service fundamentally changes the asset supply chain. But for enterprise architects, relying solely on the AEM UI isn't enough. You need to understand how to orchestrate Firefly programmatically to handle bulk generation, automated smart cropping, and outpainting.

The Firefly API Architecture

The Firefly Services API is a suite of endpoints that allow you to programmatically invoke Firefly's diffusion models. It supports:

  • Text to Image: Generating entirely new images.
  • Generative Fill / Outpainting: Expanding the borders of an existing image (crucial for responsive design).
  • Generative Remove: Removing objects and filling the background.
  • Smart Cropping: Intelligent, context-aware cropping.

JSON Payloads for Generation and Outpainting

Let's look at how an AEM Agent (or a custom App Builder action) communicates with the Firefly API.

Scenario 1: Generating a Localized Hero Image

An AEM Agent detects that a new regional campaign is missing a specific asset. It constructs a payload to the Firefly v1/generate endpoint.

{
  "prompt": "A modern electric vehicle driving on a coastal highway in Norway, photorealistic, 4k, cinematic lighting",
  "aspectRatio": "16:9",
  "contentClass": "photo",
  "styles": {
    "presets": ["hyper-realistic", "cool-tone"]
  },
  "brandReference": {
    "referenceId": "urn:aaid:sc:US:12345-67890-abcdef", 
    "weight": 0.8
  },
  "seed": 42
}

Note the brandReference. This is critical. It tells Firefly to generate the image while adhering to a specific brand style embedding previously uploaded to the Adobe Cloud.

Scenario 2: Smart Cropping and Outpainting (Generative Expand)

This is a massive pain point for AEM developers. You have a beautiful 16:9 hero image, but the mobile design requires a 9:16 vertical crop. Traditional AEM Image Core Components try to just crop the center, which often cuts off the main subject.

With Firefly API's Generative Expand, the AI can actually create new pixels above and below the image to fit the 9:16 ratio without cropping the original subject.

The payload to v1/expand:

{
  "image": {
    "source": "https://my-aem-author.adobeaemcloud.com/content/dam/campaigns/hero-16-9.jpg",
    "format": "image/jpeg"
  },
  "targetSize": {
    "width": 1080,
    "height": 1920
  },
  "alignment": "center",
  "prompt": "coastal highway background, blue sky, consistent with the original image",
  "mask": {
    "preserveOriginal": true
  }
}

Implementing Firefly in AEM Assets via Microservices

In AEMaaCS, asset processing is handled by Asset Compute microservices. You do NOT write a Java Workflow Step in AEM to call Firefly. Instead, you create a custom Asset Compute worker (Node.js) that intercepts the processing profile.

When an asset is uploaded, AEM sends a message to Adobe I/O Events, which triggers your Asset Compute worker.

// Custom Asset Compute Worker for Firefly Outpainting
const { worker, SourceCorruptError } = require('@adobe/asset-compute-sdk');
const fetch = require('node-fetch');

exports.main = worker(async (source, rendition, params) => {
    // 1. Get Firefly API Credentials from environment variables
    const clientId = process.env.FIREFLY_CLIENT_ID;
    const accessToken = params.auth.accessToken; // Provided by Asset Compute SDK

    // 2. We only process if the rendition requests a vertical expansion
    if (rendition.name === 'vertical-mobile.jpg') {
        
        // 3. Call Firefly API (Mock implementation for brevity)
        const fireflyResponse = await fetch('https://firefly-api.adobe.io/v1/expand', {
            method: 'POST',
            headers: {
                'Authorization': `Bearer ${accessToken}`,
                'x-api-key': clientId,
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                "image": {
                    "source": source.url, // URL provided by AEM
                    "format": "image/jpeg"
                },
                "targetSize": {
                    "width": 1080,
                    "height": 1920
                }
            })
        });

        const resultJson = await fireflyResponse.json();
        const expandedImageUrl = resultJson.output.url;

        // 4. Download the expanded image and write it to the rendition.path
        // AEM Asset Compute framework handles uploading it back to the JCR
        await downloadFile(expandedImageUrl, rendition.path);
    }
});

This is the correct enterprise pattern. It offloads all heavy processing and API coordination to the serverless Asset Compute layer, keeping AEM lean.

4. Edge Delivery Services (EDS) and AI Personalization

If you haven't read my Edge Delivery Services Complete Guide, do so now. EDS completely changes how AEM delivers content, moving away from the traditional Dispatcher + Publisher model to a document-based, ultra-fast CDN delivery.

When you combine EDS with Agentic AI, you unlock true real-time personalization.

Rewriting the Rules of the Dispatcher

In the traditional AEM model, the Dispatcher cached HTML. If you wanted to personalize, you either busted the cache (bad for performance) or used client-side JavaScript (Adobe Target mbox.js/at.js) which caused layout shifts (Cumulative Layout Shift - CLS) and hurt Core Web Vitals.

EDS solves this via Edge Workers (Fastly Compute@Edge or Cloudflare Workers).

How AI Personalizes Edge Blocks in Real-Time

An AI Agent in AEM generates hundreds of variations of a Content Fragment (e.g., a "Hero" block). These variations are published to EDS as distinct JSON objects or HTML fragments.

When a user requests the page:

  1. The request hits the Edge Network.
  2. The Edge Worker executes a lightweight script that inspects the incoming request (Cookies, Geo-IP, User-Agent, or an AEP Edge Network ID).
  3. The Edge Worker calls a low-latency AI decisioning endpoint (or relies on pre-computed segments pushed to the Edge KV store by the AEM AI Agent).
  4. The Edge Worker dynamically constructs the final HTML document by stitching together the specific AI-generated "Hero" block for that user's segment.

This happens in less than 50 milliseconds. Zero client-side JS required. Zero layout shift.

Example EDS Edge Worker Logic (Conceptual JavaScript)

// Executed at the CDN Edge (e.g., Fastly)
addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const url = new URL(request.url);
  
  // 1. Determine User Segment
  const userSegmentCookie = request.headers.get('Cookie')?.match(/segment=([^;]+)/)?.[1] || 'default';
  
  // 2. Fetch the base page structure from EDS origin
  const basePageResponse = await fetch(`https://origin.eds.adobe.com${url.pathname}`);
  let html = await basePageResponse.text();

  // 3. If it's a personalized segment, fetch the AI-generated variation block
  if (userSegmentCookie !== 'default') {
      const variationBlockResponse = await fetch(`https://origin.eds.adobe.com/blocks/hero/${userSegmentCookie}.plain.html`);
      if (variationBlockResponse.ok) {
          const variationHtml = await variationBlockResponse.text();
          
          // 4. Inject the AI-generated block into the base HTML using HTMLRewriter
          html = html.replace('<!-- placeholder: hero-block -->', variationHtml);
      }
  }

  return new Response(html, {
    headers: { 'Content-Type': 'text/html', 'Cache-Control': 'no-store' } // Edge-assembled, not client-cached
  });
}

The AEM Agent's job is to continually generate those /{segment}.plain.html blocks and publish them to EDS based on shifting performance metrics.

5. Writing Custom Adobe App Builder Actions in Node.js

While Adobe provides out-of-the-box integrations, the reality of enterprise architecture is that you will need to build custom AI agents. Perhaps you want to integrate AEM with OpenAI, Anthropic, or an internally hosted LLM.

The officially supported pattern for this in AEMaaCS is Adobe App Builder (formerly Project Firefly, not to be confused with the image generator).

App Builder as the Custom Agent Orchestrator

App Builder allows you to run Node.js serverless actions that seamlessly integrate with AEM events (via Adobe I/O Events) and AEM APIs.

Let's build a concrete example: An App Builder action that acts as an "Auto-Translation & SEO Agent". When an author publishes an English Content Fragment, this Agent automatically generates French, German, and Spanish variations, writes them back to AEM, and generates AI-optimized SEO metadata for each.

The Node.js Action Code

// App Builder Action: Auto-Translation & SEO Agent
const { Core } = require('@adobe/aio-sdk');
const { AEMHeadless } = require('@adobe/aem-headless-client-nodejs');

// Import your LLM SDK of choice (e.g., OpenAI)
const { Configuration, OpenAIApi } = require("openai");

async function main(params) {
  const logger = Core.Logger('main', { level: params.LOG_LEVEL || 'info' });
  
  try {
    // 1. Extract Event Data (AEM I/O Event payload)
    const cfPath = params.event.activity.object['xdm:path'];
    
    // Ensure we only process the master language (English) to avoid infinite loops
    if (!cfPath.includes('/en/')) {
        return { statusCode: 200, body: "Ignored: Not master language." };
    }

    // 2. Initialize AEM Headless Client
    const aemClient = new AEMHeadless({
        serviceURL: params.AEM_HOST,
        auth: `Bearer ${params.IMS_TOKEN}` // Requires a valid IMS Token passed via params or generated dynamically
    });

    // 3. Fetch the English Content Fragment data
    // Assuming a GraphQL query exists: cfByPath
    const cfData = await aemClient.runQuery('mybrand/cfByPath', { path: cfPath });
    const englishText = cfData.data.cfByPath.item.text.plaintext;

    // 4. Initialize LLM (e.g., Custom internal LLM or OpenAI)
    const configuration = new Configuration({ apiKey: params.LLM_API_KEY });
    const openai = new OpenAIApi(configuration);

    const languages = ['fr', 'de', 'es'];

    for (const lang of languages) {
        // 5. Call LLM for Translation and SEO generation
        const prompt = `
          You are an expert marketing translator and SEO specialist.
          Translate the following text into ${lang}.
          Also, generate a 60-character SEO title and a 150-character SEO description for ${lang}.
          Return ONLY a valid JSON object in this format:
          { "text": "...", "seoTitle": "...", "seoDescription": "..." }
          
          Original Text: ${englishText}
        `;

        const llmResponse = await openai.createChatCompletion({
            model: "gpt-4",
            messages: [{role: "user", content: prompt}],
            temperature: 0.3
        });

        const resultJson = JSON.parse(llmResponse.data.choices[0].message.content);

        // 6. Write back to AEM via AEM Assets HTTP API
        // Construct the target path (e.g., /content/dam/mybrand/fr/...)
        const targetPath = cfPath.replace('/en/', `/${lang}/`);

        const updateResponse = await fetch(`${params.AEM_HOST}/api/assets${targetPath}`, {
            method: 'PUT',
            headers: {
                'Authorization': `Bearer ${params.IMS_TOKEN}`,
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                "properties": {
                    "elements": {
                        "text": { "value": resultJson.text },
                        "seoTitle": { "value": resultJson.seoTitle },
                        "seoDescription": { "value": resultJson.seoDescription }
                    },
                    "cq:aiGenerated": true,
                    "cq:aiModel": "gpt-4"
                }
            })
        });

        if (!updateResponse.ok) {
            logger.error(`Failed to update ${lang} CF in AEM: ${updateResponse.statusText}`);
        }
    }

    return { statusCode: 200, body: "Agent workflow completed successfully" };

  } catch (error) {
    logger.error(error);
    return { statusCode: 500, body: error.message };
  }
}

exports.main = main;

This App Builder action is a perfect example of Agentic AI. It is event-driven, autonomous, performs complex multi-step reasoning (translation + SEO generation), and interacts with AEM as a system of record.

6. Real-World Architectures for Auto-Tagging AEM Assets

Historically, Smart Tags in AEM were basic. They told you a picture contained a "Dog" and "Grass." For enterprise taxonomies, this is useless. If you are a financial institution, you don't care about "Grass"; you care if the image represents "Retirement Planning" or "Wealth Management."

Agentic AI microservices change this by allowing semantic, taxonomy-aware tagging.

The Semantic Tagging Architecture

Instead of the default Smart Tags, enterprises build custom tagging pipelines using Adobe I/O, AEM Asset Compute, and custom vector databases.

  1. The Brand Taxonomy Vector Store: The enterprise taxonomy (often managed in PoolParty or a custom AEM /content/cq:tags tree) is exported and embedded into a vector database (like Pinecone or AWS OpenSearch).
  2. Asset Upload: An image is uploaded to AEM.
  3. Asset Compute Worker Triggered: The worker extracts the image and sends it to a Vision-Language Model (VLM), like GPT-4V or Claude 3 Opus.
  4. Semantic Description: The VLM generates a dense, semantic description of the image (e.g., "An elderly couple smiling while reviewing documents with a financial advisor in a modern office").
  5. Vector Search & Mapping: The worker embeds this description and performs a similarity search against the Brand Taxonomy Vector Store. It finds the closest conceptual matches: financial-services:retirement, financial-services:advisory.
  6. Tag Application: The worker updates the asset's metadata in AEM with these precise, brand-approved tags.

This completely eliminates manual tagging and ensures the DAM is highly searchable based on concepts, not just objects.

7. Security, Compliance, and Guardrails

When you give AI agents write-access to your enterprise AEM repository, security must be paramount.

Content Credentials (C2PA)

Adobe is a founding member of the Coalition for Content Provenance and Authenticity (C2PA). When Firefly generates or modifies an asset, it cryptographically signs the file with metadata detailing its provenance.

When these assets are stored in AEM, AEM reads this C2PA metadata and exposes it in the UI. If a user downloads the asset, the cryptographic signature travels with it. This is how enterprises prove that an image is AI-generated (essential for legal compliance in many jurisdictions).

Guardrails via OSGi and Cloud Manager

You must implement hard limits on what your AI agents can do. This is typically handled via OSGi configurations deployed through Cloud Manager.

File: com.mybrand.aem.core.ai.config.AIGuardrailsConfig.cfg.json

{
  "max.generation.tokens": 2048,
  "blocked.prompt.keywords": ["salary", "confidential", "internal-only"],
  "require.human.approval.for.segments": ["legal", "healthcare"],
  "allowed.ai.models": ["sensei-genai-v2", "firefly-v3"]
}

If an Agentic workflow attempts to generate content for the "legal" segment, the custom AEM service intercepts the API call, performs the generation, but saves the Content Fragment as a Draft and initiates a standard AEM Workflow (Inbox notification) for human review, enforcing the require.human.approval.for.segments rule.

8. HTL (Sightly) Considerations for AI Content

When rendering AI-generated content in traditional AEM Sites (non-EDS), your HTL must be robust. Because AI output can sometimes include unexpected markup or markdown (even when instructed to return plain text), you must rigorously apply HTL display contexts.

<!-- Example: Displaying an AI-generated summary -->
<div class="ai-summary" data-sly-use.model="com.mybrand.aem.core.models.AIGeneratedModel">
    
    <!-- WRONG: Prone to XSS or breaking layout if AI generated bad HTML -->
    <!-- <div>${model.aiGeneratedText @ context='unsafe'}</div> -->

    <!-- CORRECT: Always enforce strict HTML context or text context -->
    <div class="summary-text">
        ${model.aiGeneratedText @ context='html'}
    </div>
    
    <!-- Conditionally show AI disclosure badge -->
    <span class="ai-badge" data-sly-test="${model.isAiGenerated}">
        Generated by AI (${model.aiModelUsed @ context='text'})
    </span>
</div>

9. Comprehensive Architectural Flows for Enterprise Orchestration

It’s crucial to map out precisely how all these components interact across the Adobe ecosystem. Let's look at an end-to-end flow for launching a hyper-personalized campaign driven by AI agents.

The "Auto-Campaign" Workflow

  1. A marketer creates a central "Campaign Brief" in Workfront.
  2. AEM triggers an Event via Adobe I/O, captured by an App Builder orchestrator agent.
  3. The agent reads the Workfront brief.
  4. The agent queries Adobe Experience Platform (AEP) to identify the top 5 audience segments for this campaign based on historical conversion data.
  5. For each segment, the agent queries the AEM DAM for existing compliant assets using the AEM GraphQL API.
  6. Where assets are missing, the agent triggers Firefly API (via Asset Compute) to generate them, applying the brandReference for style consistency.
  7. The agent uses Sensei GenAI to generate targeted copy (Content Fragments) for each segment.
  8. The newly generated assets and fragments are assembled into AEM Experience Fragments.
  9. AEM pushes these Experience Fragments to Adobe Target as automated personalization activities.
  10. Target serves the experiences dynamically to end-users on Edge Delivery Services.
  11. Performance data flows back into AEP, which triggers the agent to refine and re-generate underperforming assets automatically.

This is the holy grail of content velocity, achieved not by humans manually clicking through the AEM UI, but by autonomous agents orchestrating the entire lifecycle through API integrations.

Cheat Sheet: AI Configuration Properties & PIDs

Property / ComponentDescriptionExample Value / Location
cq:aiGeneratedJCR Boolean indicating AI creationtrue (on jcr:content/data/master)
cq:aiModelSpecific model used for generationfirefly-v3, gpt-4
com.adobe.granite.auth.ims.impl.ImsConfigProviderImplOSGi PID for IMS Authenticationui.config project
x-api-keyHeader required for Adobe I/O APIsDerived from Developer Console
@adobe/asset-compute-sdkNode.js SDK for custom AI workerspackage.json in App Builder
cq:aiApprovedByID of the user who validated AI contentaman.kumar

Best Practices

  • Always Retain the Human in the Loop for High-Risk Content: Even with Agentic workflows, legal, healthcare, and finance industries must configure AEM workflows to require human approval before publishing. Use AEM Inbox and Workflow models to gate AI output.
  • Treat Prompts as Code: Store your complex system prompts in source control (Git). Treat them as you would any critical OSGi configuration or HTL script. A prompt change is a logic change.
  • Monitor API Limits and Implement Circuit Breakers: AI microservices are metered. Ensure your automated agents have safeguards to prevent infinite loops (e.g., an agent repeatedly generating content because a target goal is mathematically unreachable). Use standard Resilience4j circuit breakers in your Java OSGi services.

Do's & Don'ts

Do's

  • Do use Adobe App Builder to extend AI capabilities rather than building massive custom servlets inside AEM. Keep the heavy compute and long-polling HTTP calls off the AEM JVM.
  • Do index AI-specific JCR properties (oak:index) for auditing, reporting, and building dashboards to track AI ROI.
  • Do leverage Content Credentials (C2PA) to maintain brand trust and legal compliance.

Don'ts

  • Don't assume AI-generated Content Fragments are structurally perfect. Always validate the JSON/XML structure against your Content Fragment Models before saving to the JCR.
  • Don't hardcode IMS tokens or API keys in your App Builder actions or OSGi configs; use Adobe I/O Secrets Management and Cloud Manager secret variables.
  • Don't try to backport full Agentic AI features to AEM 6.5. The architecture fundamentally relies on AEM as a Cloud Service's event-driven microservice ecosystem. Attempting this on-premise will result in severe technical debt.

References & Official Documentation

To master Agentic AI in AEM, continually reference these official Adobe resources, as the AI landscape evolves rapidly:

Share this article

Discussion

By commenting you agree to the Privacy Policy. Guest comments are reviewed before they appear.

Loading discussion…

Subscribe to the Newsletter

Get the latest articles, tutorials, and tech insights delivered straight to your inbox. No spam, unsubscribe anytime.

Back to Blog