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

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.omni.co/feedback

```json
{
  "path": "/guides/patterns/optimizing-ai-context-media-and-adtech",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Optimizing AI context for Media and AdTech

> A hands-on guide to configuring AI context at the model, topic, and view levels using a Media and AdTech example.

export const categoryIcons = {
  'administration': 'lock',
  'api': 'terminal',
  'connections': 'database',
  'dashboards': 'table-columns',
  'embed': 'code',
  'errors': 'exclamation',
  'modeling': 'wrench',
  'patterns': 'plus',
  'schedules & alerts': 'envelope',
  'visualizations': 'chart-column',
  'workbooks': 'book'
};

export const GuideSidebar = ({category, relatedLinks, updatedDate}) => {
  const [progress, setProgress] = React.useState(0);
  React.useEffect(() => {
    const sidebar = document.querySelector('.guide-sidebar');
    if (!sidebar) return;
    let container = sidebar.parentElement;
    while (container && !container.querySelector('.guide-header')) {
      container = container.parentElement;
    }
    if (container && !container.classList.contains('guide-page-layout')) {
      container.classList.add('guide-page-layout');
    }
  }, []);
  React.useEffect(() => {
    const handleScroll = () => {
      const scrollTop = window.scrollY;
      const docHeight = document.documentElement.scrollHeight - window.innerHeight;
      const scrollPercent = docHeight > 0 ? scrollTop / docHeight * 100 : 0;
      setProgress(Math.min(100, Math.max(0, scrollPercent)));
    };
    window.addEventListener('scroll', handleScroll, {
      passive: true
    });
    handleScroll();
    return () => window.removeEventListener('scroll', handleScroll);
  }, []);
  const icon = category ? categoryIcons[category.toLowerCase()] || 'book' : 'book';
  return <aside className="guide-sidebar">
      <div className="guide-sidebar-content">
        <a href="/guides" className="guide-sidebar-back">
          <Icon icon="arrow-left" iconType="solid" size={14} />
          <span>All guides</span>
        </a>

        <div className="guide-sidebar-section">
          <div className="guide-sidebar-label">Progress</div>
          <div className="guide-sidebar-progress">
            <div className="guide-mascot">
              <svg viewBox="0 0 450 450" width="48" height="48">
                <defs>
                  <clipPath id="progressClip">
                    <rect x="0" y={450 - progress * 4.5} width="450" height={progress * 4.5} />
                  </clipPath>
                  <linearGradient id="blobbyGradient" x1="55.9753" y1="0" x2="492.197" y2="169.724" gradientUnits="userSpaceOnUse">
                    <stop stopColor="#BCA2F3" />
                    <stop offset="0.572917" stopColor="#FF7AA2" />
                    <stop offset="1" stopColor="#F3D4A2" />
                  </linearGradient>
                </defs>

                {}
                <circle cx="223.901" cy="223.901" r="213.901" transform="matrix(-0.999988 -0.0049013 0.00491945 -0.999988 447.797 449.992)" fill="#FAFAFA" stroke="#480B38" strokeWidth="20" />

                {}
                <circle cx="223.901" cy="223.901" r="213.901" transform="matrix(-0.999988 -0.0049013 0.00491945 -0.999988 447.797 449.992)" fill="url(#blobbyGradient)" stroke="#480B38" strokeWidth="20" clipPath="url(#progressClip)" />

                {}
                <path d="M310.41 195.084C310.41 200.052 301.362 212.472 284.328 212.472C266.585 212.472 258.246 201.294 258.246 195.912" stroke="#480B38" strokeWidth="17.3883" strokeMiterlimit="1.33344" strokeLinecap="round" />
                <circle cx="21.168" cy="21.168" r="21.168" transform="matrix(-1 0 0 1 388.658 169.001)" fill="#480B38" />
                <circle cx="21.168" cy="21.168" r="21.168" transform="matrix(-1 0 0 1 223.467 169.001)" fill="#480B38" />
              </svg>
            </div>
            <span className="guide-sidebar-progress-text">{Math.round(progress)}%</span>
          </div>
        </div>

        {category && <div className="guide-sidebar-section">
            <div className="guide-sidebar-label">Category</div>
            <div className="guide-sidebar-category">
              <Icon icon={icon} iconType="solid" size={14} />
              <span>{category}</span>
            </div>
          </div>}

        {updatedDate && <div className="guide-sidebar-section">
            <div className="guide-sidebar-label">Last updated</div>
            <div className="guide-sidebar-date">{updatedDate}</div>
          </div>}

        {relatedLinks && relatedLinks.length > 0 && <div className="guide-sidebar-section">
            <div className="guide-sidebar-label">Related</div>
            <ul className="guide-sidebar-links">
              {relatedLinks.map((link, index) => <li key={index}>
                  <a href={link.href}>{link.title}</a>
                </li>)}
            </ul>
          </div>}
      </div>
    </aside>;
};

export const GuideTitle = ({title}) => {
  return <div className="guide-header">
      <h1 className="guide-title">{title}</h1>
    </div>;
};

<GuideSidebar
  categoryIcons={categoryIcons}
  category="patterns"
  updatedDate="March 2026"
  relatedLinks={[
{ title: "Model-level ai_context", href: "/modeling/models/ai-context" },
{ title: "Topic-level ai_context", href: "/modeling/topics/parameters/ai-context" },
{ title: "View-level ai_context", href: "/modeling/views/parameters/ai-context" },
{ title: "Optimize models for Omni AI", href: "/modeling/develop/ai-optimization" }
]}
/>

<GuideTitle title="Optimizing AI context for Media and AdTech" />

This guide provides a hands-on reference for building out AI context within a real-world Omni instance, focusing on media organizations and advertising technology (AdTech) datasets. Whether you're managing a portfolio of global publications or a high-traffic digital platform, providing clear context ensures Omni's AI accurately interprets metrics across subscriptions, advertising spend, and content engagement.

By defining how your data relates to industry-standard concepts like CPM, audience segments, and multi-channel revenue, you empower your team to ask complex questions and receive reliable, data-driven answers.

## Why AI context matters

While Omni automatically understands your schema, `ai_context` allows you to codify company-specific knowledge that isn't captured in table names or column labels.

Think of this as training your AI analyst on your company's specific playbook. In a retail environment, this means:

* **Defining terminology:** Does *Revenue* refer to gross ad billings, net publisher payout, or recurring subscription MRR?
* **Handling personas:** Automatically filtering by a brand manager's specific publication or a sales rep's assigned advertiser categories when they ask about `my performance`.
* **Calculating yield:** Defining industry-standard formulas like CPM (Cost Per Mille) or ARPU (Average Revenue Per User) so the AI can track monetization efficiency without manual intervention.

## The AI context hierarchy

To help the AI return accurate, business-aligned answers, you can add context to the underlying data model. For this example, think of the context in three layers: model, topic, and view.

Omni applies this logic from the top down - starting at the model level - allowing you to set universal rules that get more specific as you move toward individual fields.

| **Layer**      | **Purpose**                                                                                              | **Example**                                                                                            |
| :------------- | :------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------- |
| **Model**      | **Universal truths.** Global business logic and formatting rules that apply to all queries in the model. | Setting the `revenue_by_brand` table as the source of truth for all **Total Revenue** queries.         |
| **Topic**      | **The persona.** The topic level defines more specific details scoped to your pre-defined datasets.      | Instructing the AI to use `minutes_on_site` as the primary metric when a user asks about "stickiness." |
| **View/Field** | **Field precision.** Specific definitions, synonyms, and allowed values for columns.                     | Mapping **Publication** or **Property** as synonyms for the `brand_name` dimension.                    |

## Requirements

To implement this example in your own Omni instance, you'll need:

* Familiarity with Omni's modeling layer
* Permissions in Omni that allow you to edit a shared model
* A connected data source that contains media or AdTech data

<Steps>
  <Step title="Setting universal rules in the model file" titleSize="h2">
    The [model file](/modeling/models) defines your universal rules that will exist across the entire model. These rules act as permanent guardrails, ensuring the AI adheres to your core business standards regardless of which topic in the model a user is exploring.

    ```yaml title="Model-level context" wrap theme={null}
    ai_context: |-
        ## Global Business Logic
        - Brands are the primary entities.
        - Revenue is diversified across Advertising (Campaign Spend), 				Subscriptions (MRR), and Commerce.
        - Customers are readers/viewers categorized by Segments (Free vs. Subscriber).
        - When asked for 'Total Revenue', default to the 'revenue_by_brand' table as the consolidated source of truth.
        - When users say "My Brands" or "My Vertical," always reference the `user_attributes` for assigned Brand Category.
        
        ## Data Handling & Formatting
        - Traffic and Content Performance measure engagement across formats like Articles and Videos.
        - Always use 'Signup Date' for subscriber cohort analysis and 'Campaign Start Date' for ad performance trends.
        - Hide internal technical IDs from final visualizations unless explicitly asked for "Raw Data" or "ID Level" details.
        
        ## Media & AdTech Definitions
        - "Stickiness" refers primarily to 'minutes_on_site' and session frequency.
        - A "Subscriber" refers to a unique Customer ID with an active 'plan_type'. 
        - "Yield" is calculated by dividing total ad spend by total impressions and multiplying by 1000 to return CPM.
    ```
  </Step>

  <Step title="Setting dataset logic in the topic" titleSize="h2">
    [Topic-level](/modeling/topics) context defines more specific details scoped to your pre-defined datasets. This tells the AI how to navigate things like your campaign spend, traffic, and customer data.

    ```yaml title="Topic-level context" expandable wrap theme={null}
    base_view: media_dataset_main__brands
    label: Brand Topic

    joins:
    	media_dataset_main__campaign_spend:
    		media_dataset_main__advertisers: {}
    	media_dataset_main__content_performance: {}
    	media_dataset_main__customer_monthly_activity: {}
    	media_dataset_main__customers: {}
    	media_dataset_main__revenue_by_brand: {}
    	media_dataset_main__traffic_by_brand: {}

    ai_context: |
      Use this topic to analyze Brand health, Advertiser spend, and Audience engagement.
      ## Revenue
      - Analyze monetization via 'revenue_by_brand' for high-level totals across all streams. 
      - Use 'campaign_spend' when the user asks about specific Advertisers or Ad Categories (e.g., CPG, Tech). 
      - To calculate 'Yield', always divide spend by impressions and multiply by 1000 to get CPM.
      
      ## Audience
      - Evaluate user growth and retention using the 'customers' and 'customer_monthly_activity' views. 
      - Prioritize 'segment' (Free vs. Subscriber) to understand how different cohorts consume content. 
      - Use 'minutes_on_site' as the primary metric for user "stickiness" and attention.
      
      ## Content
      - Assess editorial performance using 'content_performance' grouped by 'content_type'. 
      - Compare 'total_views' against 'content_pieces' to identify the most efficient formats (e.g., Quizzes vs. Articles). 
      - When analyzing engagement, focus on 'total_engagement' relative to total page views.
    ```
  </Step>

  <Step title="Adding precision at the view level" titleSize="h2">
    [View-level](/modeling/views) context ensures the AI understands technical identifiers, distinguishes between different types of spend and delivery, and maps editorial jargon like **Properties** or **Verticals** to the correct dimensions.

    ```yaml title="View-level context: Brands view" wrap theme={null}
      view: media_dataset_main__brands
      dimensions:
        brand_id:
          sql: '"BRAND_ID"'
          primary_key: true
          ai_context: Unique 2-3 letter code for the brand.
        
    	brand_name:
          sql: '"BRAND_NAME"'
          synonyms: [ publication, property, title, site ]
          ai_context: The primary display name of the media brand.
        
    	category:
          sql: '"CATEGORY"'
          all_values: [ Lifestyle, Fashion, Tech, Business, Entertainment ]
          synonyms: [ vertical, pillar ]
          ai_context: The industry vertical the brand operates within.
    ```

    ```yaml title="View-level context: Campaign Spend view" wrap theme={null}
      view: media_dataset_main__campaign_spend
      dimensions:
        campaign_id:
          sql: '"CAMPAIGN_ID"'
          primary_key: true
          ai_context: Unique ID for an ad campaign. Do not include in totals unless requested.
        
    	spend_usd:
          sql: '"SPEND_USD"'
          type: number
          synonyms: [ ad revenue, billing, client spend, booked revenue ]
          ai_context: Gross dollar amount spent by the advertiser on a specific brand.
        
    	impressions:
          sql: '"IMPRESSIONS"'
          type: number
          synonyms: [ ad delivery, ad views, served ads ]
          ai_context: Total count of ads served; the denominator for CPM.
    ```
  </Step>
</Steps>

## Iterating on AI context

Improving AI quality is an iterative process. Use this workflow to refine your context:

1. **Monitor**: Use the **AI usage** dashboard in the [**Analytics** section](/administration/analytics) to find queries with negative (👎) feedback.
2. **Identify**: Did the AI fail due to a missing synonym or lack of business logic?
3. **Tune**: Update the YAML at the appropriate level (model, topic, or view).
4. **Verify**: Re-run the prompt in the [**Omni Agent**](/ai/chat) to ensure the fix worked.

<Tip>
  When you correct the AI in a chat session (e.g., `"Actually, always use Fiscal Year"`), click the <Icon icon="brain" iconType="regular" /> (brain) icon to have the AI [learn from the conversation](/ai/learn-from-conversation) and propose model changes to incorporate the correction.
</Tip>

## Next steps

* [Model-level ai\_context](/modeling/models/ai-context) — Reference for model-level `ai_context` syntax
* [Topic-level ai\_context](/modeling/topics/parameters/ai-context) — Reference for topic-level `ai_context` syntax
* [View-level ai\_context](/modeling/views/parameters/ai-context) — Reference for view-level `ai_context` syntax
* [Optimize models for Omni AI](/modeling/develop/ai-optimization) — Broader guidance on optimizing your model for AI
