Implementation:Run llama Llama index Pydantic Selectors
Overview
This module provides two pydantic-based selector classes -- PydanticSingleSelector and PydanticMultiSelector -- that leverage structured output programs (typically function-calling LLMs) to choose one or more options from a set of candidates. Instead of parsing free-text LLM output, these selectors use BasePydanticProgram instances to produce strongly-typed SingleSelection or MultiSelection objects directly.
Source File: llama-index-core/llama_index/core/selectors/pydantic_selectors.py (158 lines)
Module: llama_index.core.selectors.pydantic_selectors
Dependencies
| Module | Import |
|---|---|
llama_index.core.base.base_selector |
BaseSelector, MultiSelection, SelectorResult, SingleSelection
|
llama_index.core.program |
FunctionCallingProgram
|
llama_index.core.prompts.mixin |
PromptDictType
|
llama_index.core.schema |
QueryBundle
|
llama_index.core.selectors.llm_selectors |
_build_choices_text
|
llama_index.core.selectors.prompts |
DEFAULT_SINGLE_PYD_SELECT_PROMPT_TMPL, DEFAULT_MULTI_PYD_SELECT_PROMPT_TMPL
|
llama_index.core.tools.types |
ToolMetadata
|
llama_index.core.types |
BasePydanticProgram
|
Helper Function
_pydantic_output_to_selector_result
def _pydantic_output_to_selector_result(output: Any) -> SelectorResult
Converts the pydantic program output to a SelectorResult. Handles two output types:
| Output Type | Conversion |
|---|---|
SingleSelection |
Adjusts index from 1-based to 0-based (subtracts 1), wraps in a SelectorResult
|
MultiSelection |
Adjusts each selection's index from 1-based to 0-based, extracts the selections list into a SelectorResult
|
Raises ValueError for any other output type.
PydanticSingleSelector
Class Definition
class PydanticSingleSelector(BaseSelector)
A selector that uses a pydantic program to choose exactly one option.
Constructor
def __init__(self, selector_program: BasePydanticProgram) -> None
| Parameter | Type | Description |
|---|---|---|
selector_program |
BasePydanticProgram |
The pydantic program that produces a SingleSelection output
|
from_defaults
@classmethod
def from_defaults(
cls,
program: Optional[BasePydanticProgram] = None,
llm: Optional["OpenAI"] = None,
prompt_template_str: str = DEFAULT_SINGLE_PYD_SELECT_PROMPT_TMPL,
verbose: bool = False,
) -> "PydanticSingleSelector"
If no program is provided, creates a FunctionCallingProgram with:
output_cls=SingleSelection- The provided prompt template string
- The provided LLM (or default)
_select
def _select(
self, choices: Sequence[ToolMetadata], query: QueryBundle
) -> SelectorResult
- Builds choices text via
_build_choices_text()(reused fromllm_selectors) - Calls
self._selector_program()withnum_choices,context_list, andquery_str - Converts the pydantic output to a
SelectorResult
_aselect
async def _aselect(
self, choices: Sequence[ToolMetadata], query: QueryBundle
) -> SelectorResult
Async variant using self._selector_program.acall() instead of direct invocation.
Prompt Management
_get_prompts()returns an empty dictionary (marked with a TODO noting no accessible prompts for base pydantic programs)_update_prompts()is a no-op
PydanticMultiSelector
Class Definition
class PydanticMultiSelector(BaseSelector)
A selector that uses a pydantic program to choose multiple options.
Constructor
def __init__(
self, selector_program: BasePydanticProgram, max_outputs: Optional[int] = None
) -> None
| Parameter | Type | Default | Description |
|---|---|---|---|
selector_program |
BasePydanticProgram |
required | The pydantic program that produces a MultiSelection output
|
max_outputs |
Optional[int] |
None |
Maximum number of selections; defaults to the total number of choices at runtime |
from_defaults
@classmethod
def from_defaults(
cls,
program: Optional[BasePydanticProgram] = None,
llm: Optional["OpenAI"] = None,
prompt_template_str: str = DEFAULT_MULTI_PYD_SELECT_PROMPT_TMPL,
max_outputs: Optional[int] = None,
verbose: bool = False,
) -> "PydanticMultiSelector"
If no program is provided, creates a FunctionCallingProgram with output_cls=MultiSelection.
_select
def _select(
self, choices: Sequence[ToolMetadata], query: QueryBundle
) -> SelectorResult
Same pattern as PydanticSingleSelector._select() but additionally passes max_outputs (defaulting to len(choices)) to the program.
_aselect
async def _aselect(
self, choices: Sequence[ToolMetadata], query: QueryBundle
) -> SelectorResult
Note: The async variant currently falls back to the synchronous _select() method. This is a known limitation where the multi-selector does not use async execution.
Index Conversion
Like the LLM selectors, pydantic selectors use 1-based indexing in the LLM/program output and convert to 0-based indexing in the helper function by subtracting 1 from each selection index.
Design Notes
- The pydantic selectors delegate structured output handling to
BasePydanticProgram, which typically uses function calling (e.g., OpenAI function calling) to produce typed outputs without manual parsing. - The
_build_choices_text()function is imported fromllm_selectors, sharing the same text formatting between both selector families. - The
from_defaultsmethods accept anOpenAILLM type hint (underTYPE_CHECKING), though any compatible LLM can be used with an explicit program. - The
PydanticMultiSelector._aselectfalling back to sync is a pragmatic choice, likely because the underlying program may not support async in all cases.
See Also
- LLM Selectors -- Text-parsing-based LLM selectors
- EmbeddingSingleSelector -- Embedding-based selector
- Core Types --
BasePydanticProgrambase class - RouterRetriever -- Primary consumer of selectors