Source code for contextgem.public.decision_models

# SPDX-FileCopyrightText: Shcherbak AI AS
# SPDX-License-Identifier: Apache-2.0

"""
Module for handling processing logic using decision models.

This module provides the class for using a decision model in document processing
workflows. A decision model takes a text and a set of closed questions (yes/no, pick
one option, rate on a scale) and returns the probabilities of the answers. It generates
no text. It is used for what can be put as such questions: which paragraphs or
sentences of a document belong to an aspect, and the concepts whose values come from
a closed set of options. The probabilities are the model's own estimate of each answer.

The requests are sent through the litellm library, which supports several providers
of decision models. The module covers the configuration of a model, the requests to
its API, and the tracking of token usage and costs.
"""

from __future__ import annotations

from contextgem.internal.base.decision_models import _DocumentDecisionModel
from contextgem.internal.decorators import _expose_in_registry


[docs] @_expose_in_registry(additional_key=_DocumentDecisionModel) class DocumentDecisionModel(_DocumentDecisionModel): """ Handles processing documents with a specific decision model. A decision model answers closed questions on a text with probabilities and generates no text. It extracts aspects, by deciding on each paragraph whether the paragraph belongs to an aspect and, for an aspect with ``reference_depth="sentences"``, on each sentence of such a paragraph whether the sentence does, and the concepts whose values come from a closed set of options: ``BooleanConcept``, ``LabelConcept`` and ``RatingConcept``. Each extracted item has the probabilities of all the options in its ``probabilities`` attribute. A decision model can be used on its own or, with a role assigned, as a part of a model group, next to the LLMs that extract everything else. :ivar model: Model identifier in format {model_provider}/{model_name}, e.g. ``"typesafe/jev-latest"``. The model has to be served by one of the providers of decision models that ``litellm`` supports: a model of another provider is rejected when the decision model is created. For a model deployed in Microsoft Foundry, the name of the deployment takes the place of the model name, i.e. ``"azure_ai/<deployment_name>"``. :vartype model: str :ivar api_key: API key for authentication. Not required for self-hosted models. Not included in the serialized model data, i.e. to be set again after deserialization. Not shown when the model is printed, nor in the text of a validation error of the model, which names the invalid parameter and the reason without showing the values passed. The values are still returned by the ``errors()`` and ``json()`` methods of the error, unless ``include_input=False`` is passed, with ``'**********'`` in place of a key that is passed as a value, e.g. a rejected key or the key among the parameters that a model is created with, and in place of the value of any parameter that a model does not have, as it may be the key passed under a misspelled name. A model that is among the values is returned by ``errors()`` as it is, i.e. with the key as its attribute, and is written out by ``json()`` without its key. A key that is passed as the value of another parameter, e.g. of ``model``, is returned as any other value. :vartype api_key: str | None :ivar api_base: Base URL of the API endpoint, e.g. the address of a self-hosted server, or the endpoint of the Microsoft Foundry resource that the model is deployed in. Not included in the serialized model data, i.e. to be set again after deserialization. :vartype api_base: str | None :ivar role: Free-form role label of the model (up to 64 printable characters), used for routing in a ``DocumentModelGroup``: the model extracts the aspects/concepts with the same ``model_role``. Defaults to None, in which case the model extracts the aspects/concepts without ``model_role``. Ignored when the model is used on its own, as it then extracts all the aspects/concepts it is given. :vartype role: str | None :ivar num_retries_failed_request: Number of retries when a request fails with a transient error (request timeout, rate limit, server or connection error). Retries are performed with exponential backoff and jitter. Non-transient errors (e.g. invalid request, failed authentication) are not retried. Defaults to 3. :vartype num_retries_failed_request: int :ivar timeout: Timeout in seconds for API calls. Defaults to 600 seconds. :vartype timeout: int :ivar pricing_details: ModelPricing object with pricing details for cost calculation. Decision models are usually priced by the input tokens only, in which case the price of the output tokens is to be set to ``0.0``. Defaults to None. :vartype pricing_details: ModelPricing | None :ivar auto_pricing: Enable automatic cost calculation using genai-prices. Cannot be set together with ``pricing_details``. For an OpenAI model (``openai/``), the prices of the decision requests are used, which genai-prices has apart from the prices of the chat requests to the model. Not supported for a model for which genai-prices has the prices of a text-generating model, i.e. a price of output tokens, which are the prices of the chat requests to the model (e.g. ``openrouter/openai/gpt-6-luna``), and for self-hosted models (``strands_decider/``): set ``pricing_details`` for them instead. For a model that genai-prices has no prices for, e.g. a model deployed in Microsoft Foundry, a warning is issued and the costs stay at zero: ``pricing_details`` is to be set instead for such a model too. Defaults to ``False``. :vartype auto_pricing: bool :ivar auto_pricing_refresh: Whether genai-prices should auto-refresh its cached pricing data, e.g. to price a recently released model that the bundled pricing data does not include yet. Defaults to ``False``. :vartype auto_pricing_refresh: bool :ivar is_fallback: Indicates whether the model is a fallback model. Defaults to False. :vartype is_fallback: bool :ivar fallback_models: Models to use as fallbacks if the current one fails, tried in the given order until one of them succeeds: decision models, LLMs, or both. Each must have ``is_fallback=True`` and the same role as the current model, and must differ from the current model and from each other in at least one config param. A fallback LLM extracts the same aspects/concepts with its prompts, i.e. its items have no probabilities, and is asked again when it returns invalid data, up to its ``max_retries_invalid_data`` times, while a fallback decision model is asked once. Defaults to an empty list. :vartype fallback_models: list[DocumentDecisionModel | DocumentLLM] :ivar decision_threshold: The lowest probability of "yes" (above 0, up to 1) with which a yes/no question is taken as answered "yes": a paragraph or a sentence belongs to an aspect, a ``BooleanConcept`` is ``True``, a label of a ``LabelConcept`` with ``classification_type="multi_label"`` is selected. A lower threshold extracts more, a higher one extracts only what the model is surer of. Applies unless the aspect or the concept has a ``decision_threshold`` of its own. Does not apply to a ``LabelConcept`` with ``classification_type="multi_class"`` and to a ``RatingConcept``, for which the most probable option is taken. Does not change the ``probabilities`` of the extracted items. Defaults to 0.5. :vartype decision_threshold: float :ivar async_limiter: Controls frequency of async API requests for concurrent tasks. Defaults to allowing 10 acquisitions per 10-second period to prevent rate limit issues. With concurrency enabled, the requests for the paragraphs of a document, which aspects are extracted with, are paced by the limiter: consider a higher rate for long documents, if the rate limits of the model provider allow for it. The rate applies to all the requests to the model that are sent concurrently, i.e. the extraction calls that run at the same time share it. Requests to a fallback model are controlled by the limiter of that fallback model. See https://github.com/mjpieters/aiolimiter for configuration details. :vartype async_limiter: AsyncLimiter Note: For what a decision model extracts, how its requests are formed, how the extracted items get their values and probabilities, and the limits, see https://contextgem.shcherbak.ai/decision_models/decision_models/ Example: .. literalinclude:: ../../../dev/usage_examples/docstrings/decision_models/def_decision_model.py :language: python :caption: Decision model definition """