Hi all,
I’m working on using OpenAI’s structured output to generate filters for a custom table containing a list of parameters. The filters should be able to be chained through boolean operators. I have, therefore, come up with the following pydantic model:
from typing import Literal, Union
from pydantic import BaseModel
Item = Union['UnaryOperator', 'BinaryOperator', 'Filter']
class Filter(BaseModel):
paramId: str
paramName: str
comparator: str
value: int | float | str
class BinaryOperator(BaseModel):
operator: Literal['AND', 'OR', 'XOR']
left: Item
right: Item
class UnaryOperator(BaseModel):
operator: Literal['NOT']
right: Item
class TableConfig(BaseModel):
filter: Item
As you can see, I chose a nested approach, where the item could either be an operator or a filter. In the end, the user will get a JSON representation of filters like ((a>5 AND b>10) OR c < 2)
based on the user’s request.
I now wonder how to encode the information required to generate a valid Filter
into the TableConfig class. For example, I know that there’s a parameter ‘age’ that has ID ‘1’, allows ‘=’, ‘!=’, ‘>’, ‘<’ as comparators, etc. I know I could provide the information on the filters in the system prompt, but I would find it more intuitive to provide it through the TableConfig
class. I have thought of creating a separate Filter
class for each parameter, defining the static fields through Literals
. E.g.
class AgeFilter(BaseModel):
paramId: Literal['1']
paramName: Literal['age']
comparator: Literal['=', '!=', '>', '<']
value: int
However, I failed when I attempted to group all possible filters using a parent class in Enum style.
Does anyone know how to tackle this problem intuitively without convoluting the system prompt? Much appreciated!