```python:inference/core/workflows/core_steps/common/query_language/introspection/core.py
from typing import List

from inference.core.workflows.core_steps.common.query_language.entities.introspection import \
    OperatorDescription
from inference.core.workflows.core_steps.common.query_language.entities.operations import (
    DoesNotExist, Equals, Exists, In, IsEmpty, IsFalse, IsNotEmpty, IsTrue,
    NotEquals, NumberGreater, NumberGreaterEqual, NumberLower,
    NumberLowerEqual, StringContains, StringEndsWith, StringStartsWith)

_CACHED_OPERATORS_DESCRIPTIONS = None

def prepare_operators_descriptions() -> List[OperatorDescription]:
    global _CACHED_OPERATORS_DESCRIPTIONS
    
    if _CACHED_OPERATORS_DESCRIPTIONS is not None:
        return _CACHED_OPERATORS_DESCRIPTIONS
    
    operator_types = [
        In,
        StringContains,
        StringEndsWith,
        StringStartsWith,
        NumberLowerEqual,
        NumberLower,
        NumberGreaterEqual,
        NumberGreater,
        NotEquals,
        Equals,
        Exists,
        DoesNotExist,
        IsTrue,
        IsFalse,
        IsEmpty,
        IsNotEmpty,
    ]
    results = []
    for operator_type in operator_types:
        operator_schema = operator_type.model_json_schema()
        type_enum = operator_schema["properties"]["type"].get("enum", [])
        operands_number = operator_schema["operands_number"]
        operands_kinds = operator_schema["operands_kinds"]
        description = operator_schema.get("description")
        
        for alias in type_enum:
            results.append(
                OperatorDescription(
                    operator_type=alias,
                    operands_number=operands_number,
                    operands_kinds=operands_kinds,
                    description=description,
                )
            )
    
    _CACHED_OPERATORS_DESCRIPTIONS = results
    return results
```