> ## 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.

# Optimizing AI context for retail and ecommerce

> A hands-on guide to configuring AI context at the model, topic, and view levels using a retail and ecommerce 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 retail and ecommerce" />

This guide provides a hands-on reference for building out AI context within a real-world Omni instance.

By following this retail and orders example, you can see exactly how to move beyond basic schema discovery to a **high-precision setup** where the AI understands your specific business logic, key performance indicators, and reporting nuances.

## 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 which status codes (e.g., "Shipped," "Complete") represent valid revenue
* Specifying which unique identifier to use when counting orders
* Providing preferred dimensions for "top-n" queries

## 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. | "Our fiscal year starts in Feb; use USD for all currency."                                      |
| **Topic**      | **The persona.** Definitions for specific datasets and how views relate to each other.                   | "You are a Retail Analyst; use the Order Items table for all sales queries."                    |
| **View/Field** | **Field precision.** Specific definitions, synonyms, and allowed values for columns.                     | "This ID is internal; don't show it unless asked. `'Bought at'` is a synonym for `created_at`." |

## 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 retail-related 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
      - Our Fiscal Year starts in February. If a user asks for "this year" without specifying, assume Fiscal Year.
      - "Revenue" always refers to 'Gross Sales' (before discounts) unless 'Net' is specified.
      - When comparing time periods, always use 'Complete' weeks (Monday-Sunday) to avoid partial-week skew.

      ## Data Handling & Formatting
      - Never display internal database keys or UUIDs in the final result unless explicitly requested for troubleshooting.
      - For any currency output, default to USD.
      - If a query results in zero records, explain that the filters (like 'Status = Shipped') might be too restrictive.

      ## Retail Definitions
      - A "New Customer" is a user whose first_order_date is within the last 30 days.
      - "Active Inventory" refers only to items where 'Stock Count' > 0 and 'Discontinued' is false.
    ```
  </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 example shows how to tell the AI how to handle an ecommerce dataset specifically focused on orders and fulfillment.

    ```yaml title="Topic-level context" wrap theme={null}
    base_view: omni_dbt_ecomm__order_items
    label: Order Transactions
    group_label: Orders & Fulfillment

    # Limit the search space to relevant fields to reduce noise
    ai_fields: [ all_views.*, -tag:exclude_from_AI ]

    ai_context: |-
      You are an expert data analyst with vast experience analyzing ecommerce data to find trends.

      Our data includes order line items (order_items), users (users), inventory (inventory_items), and products (products).

      ## Key Business Logic:
      - Any queries regarding sales should always use the total_sale_price field on the order items table.
      - If asked about drivers of a metric change, start with: country, traffic_source, category, or brand.
      - If asked about "who" or "users", use full_name and email. Never return an ID unless explicitly asked.
      - For total orders or order count, use orders.order_id_count_distinct.
      - For revenue metrics, filter only on valid statuses: Complete, Shipped, Processing.

    sample_queries:
      Monthly Sales by Country:
        query:
          fields:
            [
              "omni_dbt_ecomm__order_items.created_at[month]",
              omni_dbt_ecomm__users.country,
              omni_dbt_ecomm__order_items.total_sale_price
            ]
          base_view: omni_dbt_ecomm__order_items
          filters:
            omni_dbt_ecomm__order_items.status:
              not: [ Returned, Cancelled ]
          pivots: [ omni_dbt_ecomm__users.country ]
        description: A monthly breakdown of all sales by user's country
        prompt: What do our sales look like by country?
    ```

    <Tip>
      **Use sample queries:** Adding `sample_queries` creates a "happy path" for the AI. It ensures high-value KPIs use your exact join logic and filter sets, mirroring how a human analyst would build the report.
    </Tip>
  </Step>

  <Step title="Adding precision at the view level" titleSize="h2">
    [View-level](/modeling/views) context eliminates ambiguity when two fields have similar names or when a field has a cryptic database label.

    ```yaml title="View and field-level context" wrap theme={null}
    # order_items.view.omni
    dimensions:
      id:
        sql: '"ID"'
        primary_key: true
        ai_context: >
          Generated automatically for each product in an order.
          Do not include this in queries unless specifically requested.

      status:
        sql: '"STATUS"'
        # Prevent hallucinations by defining all possible values
        all_values: [ Complete, Shipped, Processing, Cancelled, Returned ]
        ai_context: Current processing status of the individual item within the order.

      created_at:
        sql: '"CREATED_AT"'
        timeframes: [ date, week, month, quarter, year ]
        synonyms: [ purchase time, bought at ] # Map natural language to the field
        ai_context: >
          Timestamp of record creation. Preferred grains are date, week, and month.
    ```
  </Step>
</Steps>

## Iterating on AI context

Improving AI quality is an iterative process. Use this workflow to refine your instance based on real usage:

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 cryptic name, a missing join, or a lack of business logic?
3. **Tune**: Update the YAML at the appropriate level (model, topic, 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
