# Model groups

Module for handling processing logic using model groups.

This module provides the class for grouping models in document processing workflows.
Each model of a group extracts the aspects and concepts routed to it by its role,
e.g. to use a smaller model for simpler tasks and a more capable model for more
complex ones.

### *class* contextgem.public.models.DocumentModelGroup(\*\*data)

Bases: `_DocumentModelGroup`

Represents a group of models with unique roles for processing document content.

This class manages multiple models, each of which extracts the aspects and concepts routed
to it by its role, e.g. to use a smaller model for simpler tasks and a more capable
model for more complex ones. A group can also have decision models
(`DocumentDecisionModel`) next to its LLMs: a decision model extracts the aspects
routed to it, and the concepts routed to it that have values from a closed set
of options.

* **Variables:**
  * **models** ([*list*](https://docs.python.org/3/builtins/stdtypes.html#list) *[*[*DocumentLLM*](https://contextgem.shcherbak.ai/api/llms/index.html.md#contextgem.public.llms.DocumentLLM) *|* [*DocumentDecisionModel*](https://contextgem.shcherbak.ai/api/decision_models/index.html.md#contextgem.public.decision_models.DocumentDecisionModel) *]*) – A list of models (DocumentLLM instances, DocumentDecisionModel instances,
    or both), each with a unique `role`. An aspect/concept
    is extracted by the model with the `role` equal to the `model_role` of the aspect/concept,
    and an aspect/concept without `model_role` is extracted by the model without `role`.
    Only one model in the group can have no role. At least 2 instances are required.
  * **output_language** (*LanguageRequirement*) – Language for produced output text (justifications, explanations).
    Values: “en” (always English) or “adapt” (matches document/image language).
    All LLMs in the group must share the same output_language setting.
    Defaults to “en”. Applies to the extraction prompts of the LLMs, and to their
    default system messages.
    Does not apply to the decision models in the group, which produce no text.
* **Parameters:**
  * **models** ([*list*](https://docs.python.org/3/builtins/stdtypes.html#list) *[* *\_DocumentModel* *]*)
  * **output_language** ([*Literal*](https://docs.python.org/3/library/typing.html#typing.Literal) *[* *'en'* *,*  *'adapt'* *]*)

Note:
: Refer to the [`DocumentLLM`](https://contextgem.shcherbak.ai/api/llms/index.html.md#contextgem.public.llms.DocumentLLM) class for more information on constructing LLMs
  for the group.

Example:
: ```python
  from contextgem import DocumentLLM, DocumentModelGroup
  <br/>
  <br/>
  # Create an extractor LLM with a fallback. This LLM has no role, i.e. it extracts
  # the aspects and concepts that have no `model_role`.
  extractor = DocumentLLM(
      model="openai/gpt-6-luna",
      api_key="your-openai-api-key",  # Replace with your actual API key
  )
  <br/>
  # Create a fallback LLM for the extractor
  extractor_fallback = DocumentLLM(
      model="anthropic/claude-haiku-4-5",
      api_key="your-anthropic-api-key",  # Replace with your actual API key
      is_fallback=True,  # Must have the same role as the primary LLM (here: no role)
  )
  <br/>
  # Assign the fallback LLM to the primary extractor
  extractor.fallback_models = [extractor_fallback]
  <br/>
  # Create a reasoner LLM. A role is a label of your choice: this LLM extracts
  # the aspects and concepts that have `model_role="reasoner"`.
  reasoner = DocumentLLM(
      model="openai/gpt-6.1-sol",
      api_key="your-openai-api-key",  # Replace with your actual API key
      role="reasoner",  # For more complex tasks that require reasoning
  )
  <br/>
  # Create an LLM dedicated to images. This LLM extracts the concepts that have
  # `model_role="vision"`, e.g. the concepts with `modality="image"`.
  vision_extractor = DocumentLLM(
      model="openai/gpt-5.6-luna",
      api_key="your-openai-api-key",  # Replace with your actual API key
      role="vision",  # For extraction from images
  )
  <br/>
  # Create a DocumentModelGroup with all three LLMs
  model_group = DocumentModelGroup(
      models=[extractor, reasoner, vision_extractor],
      output_language="en",  # All LLMs must have the same output language ("en" is default)
  )
  # This group will have 4 LLMs: three main ones (one without a role, two with roles),
  # and one fallback LLM for a specific LLM. Each LLM can have one or more fallback models.
  <br/>
  # Get usage statistics for the whole group or for a specific role
  group_usage = model_group.get_usage()
  reasoner_usage = model_group.get_usage(model_role="reasoner")
  <br/>
  # Get cost statistics for the whole group or for a specific role
  all_costs = model_group.get_cost()
  reasoner_cost = model_group.get_cost(model_role="reasoner")
  <br/>
  # Reset usage and cost statistics for the whole group or for a specific role
  model_group.reset_usage_and_cost()
  model_group.reset_usage_and_cost(model_role="reasoner")
  ```

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be
validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

#### \_eq_deserialized_llm_config(other)

Custom config equality method to compare this \_DocumentModelGroup with a deserialized instance.

Uses the \_eq_deserialized_model_config method of each model in the group, of any
kind, to compare it with its counterpart, including fallbacks, if any.

* **Parameters:**
  **other** (`contextgem.internal.base.models._DocumentModelGroup`) – Another \_DocumentModelGroup instance to compare with
* **Returns:**
  True if the instances are equal, False otherwise
* **Return type:**
  [`bool`](https://docs.python.org/3/builtins/functions.html#bool)

#### extract_all(document, \*, overwrite_existing=False, max_items_per_call=0, use_concurrency=False, max_paragraphs_to_analyze_per_call=0, max_images_to_analyze_per_call=0, raise_exception_on_extraction_error=True)

Extracts all aspects and concepts from a document and its aspects.

This method performs comprehensive extraction by processing the document for aspects
and concepts, then extracting concepts from each aspect. The operation can be
configured for concurrent processing and customized extraction parameters.

This is the synchronous version of extract_all_async().

* **Parameters:**
  * **document** (`contextgem.internal.base.documents._Document`) – The document to analyze.
  * **overwrite_existing** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to overwrite already processed aspects and concepts with
    newly extracted information. Defaults to False.
  * **max_items_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum number of items with the same extraction params to process
    in each call. Defaults to 0 (all items in one call). If concurrency is enabled, defaults to 1.
    For complex tasks, you should not set a high value, in order to avoid prompt overloading.
  * **use_concurrency** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, enables concurrent processing of multiple items.
    Concurrency can considerably reduce processing time, but may cause rate limit errors
    with model providers. Use this option when API rate limits allow for multiple concurrent
    requests. Defaults to False.
  * **max_paragraphs_to_analyze_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum paragraphs to include in a
    single LLM prompt. A decision model is sent each paragraph in a request of
    its own for aspects, whatever the value. For concepts, it is sent a text
    with more paragraphs in parts of at most that many paragraphs, each in
    a request of its own: a concept then gets an extracted item for each part,
    and a concept with `singular_occurrence=True` is rejected with
    `ValueError`. Defaults to 0 (all paragraphs). Cannot be negative.
  * **max_images_to_analyze_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum images to include in a single LLM prompt.
    Defaults to 0 (all images). Cannot be negative. Relevant only for document-level
    concepts.
  * **raise_exception_on_extraction_error** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to raise an exception if the extraction fails
    due to invalid data returned by a model or an error in the model API. If False, a warning will
    be issued instead, and no extracted items will be returned. Defaults to True.
* **Returns:**
  The document with extracted aspects and concepts.
* **Return type:**
  `contextgem.internal.base.documents._Document`

#### *async* extract_all_async(document, \*, overwrite_existing=False, max_items_per_call=0, use_concurrency=False, max_paragraphs_to_analyze_per_call=0, max_images_to_analyze_per_call=0, raise_exception_on_extraction_error=True)

Asynchronously extracts all aspects and concepts from a document and its aspects.

This method performs comprehensive extraction by processing the document for aspects
and concepts, then extracting concepts from each aspect. The operation can be
configured for concurrent processing and customized extraction parameters.

* **Parameters:**
  * **document** (`contextgem.internal.base.documents._Document`) – The document to analyze.
  * **overwrite_existing** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to overwrite already processed aspects and concepts with
    newly extracted information. Defaults to False.
  * **max_items_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum number of items with the same extraction params to process
    in each call. Defaults to 0 (all items in one call). If concurrency is enabled,
    defaults to 1. For complex tasks, you should not set a high value, in order to avoid
    prompt overloading.
  * **use_concurrency** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, enables concurrent processing of multiple items.
    Concurrency can considerably reduce processing time, but may cause rate limit errors
    with model providers. Use this option when API rate limits allow for multiple concurrent
    requests. Defaults to False.
  * **max_paragraphs_to_analyze_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum paragraphs to include in a
    single LLM prompt. A decision model is sent each paragraph in a request of
    its own for aspects, whatever the value. For concepts, it is sent a text
    with more paragraphs in parts of at most that many paragraphs, each in
    a request of its own: a concept then gets an extracted item for each part,
    and a concept with `singular_occurrence=True` is rejected with
    `ValueError`. Defaults to 0 (all paragraphs). Cannot be negative.
  * **max_images_to_analyze_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum images to include in a single LLM prompt.
    Defaults to 0 (all images). Cannot be negative. Relevant only for document-level
    concepts.
  * **raise_exception_on_extraction_error** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to raise an exception if the extraction fails
    due to invalid data returned by a model or an error in the model API. If False, a warning will
    be issued instead, and no extracted items will be returned. Defaults to True.
* **Returns:**
  The document with extracted aspects and concepts.
* **Return type:**
  `contextgem.internal.base.documents._Document`

#### extract_aspects_from_document(document, \*, from_aspects=None, overwrite_existing=False, max_items_per_call=0, use_concurrency=False, max_paragraphs_to_analyze_per_call=0, raise_exception_on_extraction_error=True)

Extracts aspects from the provided document using predefined models.

If an aspect instance has `extracted_items` populated, the `reference_paragraphs` field will be
automatically populated from these items. For an aspect with the “sentences” reference depth,
the `reference_sentences` field is populated from them as well: with the extracted sentences,
and not with the other sentences of the reference paragraphs.

This is the synchronous version of extract_aspects_from_document_async().

* **Parameters:**
  * **document** (`contextgem.internal.base.documents._Document`) – The document from which aspects are to be extracted.
  * **from_aspects** ([`collections.abc.Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)[`contextgem.internal.base.aspects._Aspect`] | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Existing aspects to use as a base for extraction. If None, uses all
    document’s aspects. An aspect that is given more than once is extracted once.
  * **overwrite_existing** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to overwrite already processed aspects with newly extracted information.
    Defaults to False.
  * **max_items_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum items with the same extraction params to process per call.
    Defaults to 0 (all items in single call). For complex tasks, you should not set a value, to avoid
    prompt overloading. If concurrency is enabled, defaults to 1 (each item processed separately).
  * **use_concurrency** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, enables concurrent processing of multiple items.
    Concurrency can considerably reduce processing time, but may cause rate limit errors
    with model providers. Use this option when API rate limits allow for multiple concurrent
    requests. Defaults to False.
  * **max_paragraphs_to_analyze_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum paragraphs to analyze in a single LLM
    prompt. Changes nothing for a decision model, which is sent each paragraph in
    a request of its own. Defaults to 0 (all paragraphs). Cannot be negative.
  * **raise_exception_on_extraction_error** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to raise an exception if the extraction fails
    due to invalid data returned by a model or an error in the model API. If False, a warning will
    be issued instead, and no extracted items will be returned. Defaults to True.
* **Returns:**
  List of processed \_Aspect objects with extracted items.
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[`contextgem.internal.base.aspects._Aspect`]

#### *async* extract_aspects_from_document_async(document, \*, from_aspects=None, overwrite_existing=False, max_items_per_call=0, use_concurrency=False, max_paragraphs_to_analyze_per_call=0, raise_exception_on_extraction_error=True)

Extracts aspects from the provided document using predefined models asynchronously.

If an aspect instance has `extracted_items` populated, the `reference_paragraphs` field will be
automatically populated from these items. For an aspect with the “sentences” reference depth,
the `reference_sentences` field is populated from them as well: with the extracted sentences,
and not with the other sentences of the reference paragraphs.

* **Parameters:**
  * **document** (`contextgem.internal.base.documents._Document`) – The document from which aspects are to be extracted.
  * **from_aspects** ([`collections.abc.Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)[`contextgem.internal.base.aspects._Aspect`] | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Existing aspects to use as a base for extraction. If None, uses all
    document’s aspects. An aspect that is given more than once is extracted once.
  * **overwrite_existing** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to overwrite already processed aspects with newly extracted information.
    Defaults to False.
  * **max_items_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum number of items with the same extraction params to process
    per call. Defaults to 0 (all items in one call). If concurrency is enabled,
    defaults to 1. For complex tasks, you should not set a high value, in order to avoid
    prompt overloading.
  * **use_concurrency** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, enables concurrent processing of multiple items.
    Concurrency can considerably reduce processing time, but may cause rate limit errors
    with model providers. Use this option when API rate limits allow for multiple concurrent
    requests. Defaults to False.
  * **max_paragraphs_to_analyze_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum paragraphs to analyze in a single LLM
    prompt. Changes nothing for a decision model, which is sent each paragraph in
    a request of its own. Defaults to 0 (all paragraphs). Cannot be negative.
  * **raise_exception_on_extraction_error** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to raise an exception if the extraction fails
    due to invalid data returned by a model or an error in the model API. If False, a warning will
    be issued instead, and no extracted items will be returned. Defaults to True.
* **Returns:**
  List of processed \_Aspect objects with extracted items.
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[`contextgem.internal.base.aspects._Aspect`]

#### extract_concepts_from_aspect(aspect, document, \*, from_concepts=None, overwrite_existing=False, max_items_per_call=0, use_concurrency=False, max_paragraphs_to_analyze_per_call=0, raise_exception_on_extraction_error=True)

Extracts concepts associated with a given aspect in a document.

This method processes an aspect to extract related concepts using models.
If the aspect has not been previously processed, a ValueError is raised.

This is the synchronous version of extract_concepts_from_aspect_async().

* **Parameters:**
  * **aspect** (`contextgem.internal.base.aspects._Aspect`) – The aspect from which to extract concepts.
  * **document** (`contextgem.internal.base.documents._Document`) – The document that contains the aspect.
  * **from_concepts** ([`collections.abc.Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)[`contextgem.internal.base.concepts._Concept`] | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – List of existing concepts to process. Defaults to None.
    A concept that is given more than once is extracted once.
  * **overwrite_existing** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to overwrite already processed concepts with newly
    extracted information. Defaults to False.
  * **max_items_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum number of items with the same extraction params to process
    in each call. Defaults to 0 (all items in one call). If concurrency is enabled,
    defaults to 1. For complex tasks, you should not set a high value, in order to avoid
    prompt overloading.
  * **use_concurrency** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, enables concurrent processing of multiple items.
    Concurrency can considerably reduce processing time, but may cause rate limit errors
    with model providers. Use this option when API rate limits allow for multiple concurrent
    requests. Defaults to False.
  * **max_paragraphs_to_analyze_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum paragraphs to include in a
    single LLM prompt. A decision model is sent a text with more
    paragraphs in parts of at most that many paragraphs, each in a request of
    its own: a concept then gets an extracted item for each part, and
    a concept with `singular_occurrence=True` is rejected with `ValueError`.
    Defaults to 0 (all paragraphs). Cannot be negative.
  * **raise_exception_on_extraction_error** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to raise an exception if the extraction fails
    due to invalid data returned by a model or an error in the model API. If False, a warning will
    be issued instead, and no extracted items will be returned. Defaults to True.
* **Returns:**
  List of processed concept objects.
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[`contextgem.internal.base.concepts._Concept`]

#### *async* extract_concepts_from_aspect_async(aspect, document, \*, from_concepts=None, overwrite_existing=False, max_items_per_call=0, use_concurrency=False, max_paragraphs_to_analyze_per_call=0, raise_exception_on_extraction_error=True)

Asynchronously extracts concepts from a specified aspect using models.

This method processes an aspect to extract related concepts using models.
If the aspect has not been previously processed, a ValueError is raised.

* **Parameters:**
  * **aspect** (`contextgem.internal.base.aspects._Aspect`) – The aspect from which to extract concepts.
  * **document** (`contextgem.internal.base.documents._Document`) – The document that contains the aspect.
  * **from_concepts** ([`collections.abc.Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)[`contextgem.internal.base.concepts._Concept`] | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – List of existing concepts to process. Defaults to None.
    A concept that is given more than once is extracted once.
  * **overwrite_existing** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to overwrite already processed concepts with newly
    extracted information. Defaults to False.
  * **max_items_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum number of items with the same extraction params to process
    in each call. Defaults to 0 (all items in one call). If concurrency is enabled,
    defaults to 1. For complex tasks, you should not set a high value, in order to avoid
    prompt overloading.
  * **use_concurrency** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, enables concurrent processing of multiple items.
    Concurrency can considerably reduce processing time, but may cause rate limit errors
    with model providers. Use this option when API rate limits allow for multiple concurrent
    requests. Defaults to False.
  * **max_paragraphs_to_analyze_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum paragraphs to include in a
    single LLM prompt. A decision model is sent a text with more
    paragraphs in parts of at most that many paragraphs, each in a request of
    its own: a concept then gets an extracted item for each part, and
    a concept with `singular_occurrence=True` is rejected with `ValueError`.
    Defaults to 0 (all paragraphs). Cannot be negative.
  * **raise_exception_on_extraction_error** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to raise an exception if the extraction fails
    due to invalid data returned by a model or an error in the model API. If False, a warning will
    be issued instead, and no extracted items will be returned. Defaults to True.
* **Returns:**
  List of processed concept objects.
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[`contextgem.internal.base.concepts._Concept`]

#### extract_concepts_from_document(document, \*, from_concepts=None, overwrite_existing=False, max_items_per_call=0, use_concurrency=False, max_paragraphs_to_analyze_per_call=0, max_images_to_analyze_per_call=0, raise_exception_on_extraction_error=True)

Extracts concepts from the provided document using predefined models.

This is the synchronous version of extract_concepts_from_document_async().

* **Parameters:**
  * **document** (`contextgem.internal.base.documents._Document`) – The document from which concepts are to be extracted.
  * **from_concepts** ([`collections.abc.Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)[`contextgem.internal.base.concepts._Concept`] | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Existing concepts to use as a base for extraction. If None, uses all
    document’s concepts. A concept that is given more than once is extracted once.
  * **overwrite_existing** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to overwrite already processed concepts with
    newly extracted information. Defaults to False.
  * **max_items_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum items with the same extraction params to process per call.
    Defaults to 0 (all items in single call). For complex tasks, you should not set a value, to avoid
    prompt overloading. If concurrency is enabled, defaults to 1 (each item processed separately).
  * **use_concurrency** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, enables concurrent processing of multiple items.
    Concurrency can considerably reduce processing time, but may cause rate limit errors
    with model providers. Use this option when API rate limits allow for multiple concurrent
    requests. Defaults to False.
  * **max_paragraphs_to_analyze_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum paragraphs to analyze in a single LLM
    prompt. A decision model is sent a text with more
    paragraphs in parts of at most that many paragraphs, each in a request of
    its own: a concept then gets an extracted item for each part, and
    a concept with `singular_occurrence=True` is rejected with `ValueError`.
    Defaults to 0 (all paragraphs). Cannot be negative.
  * **max_images_to_analyze_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum images to include in a single LLM prompt.
    Defaults to 0 (all images). Cannot be negative.
  * **raise_exception_on_extraction_error** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to raise an exception if the extraction fails
    due to invalid data returned by a model or an error in the model API. If False, a warning will
    be issued instead, and no extracted items will be returned. Defaults to True.
* **Returns:**
  List of processed Concept objects with extracted items.
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[`contextgem.internal.base.concepts._Concept`]

#### *async* extract_concepts_from_document_async(document, \*, from_concepts=None, overwrite_existing=False, max_items_per_call=0, use_concurrency=False, max_paragraphs_to_analyze_per_call=0, max_images_to_analyze_per_call=0, raise_exception_on_extraction_error=True)

Extracts concepts from the provided document using predefined models asynchronously.

This method processes a document to extract concepts using configured models.

* **Parameters:**
  * **document** (`contextgem.internal.base.documents._Document`) – The document from which concepts are to be extracted.
  * **from_concepts** ([`collections.abc.Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)[`contextgem.internal.base.concepts._Concept`] | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Existing concepts to use as a base for extraction. If None, uses all
    document’s concepts. A concept that is given more than once is extracted once.
  * **overwrite_existing** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to overwrite already processed concepts with
    newly extracted information. Defaults to False.
  * **max_items_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum number of items with the same extraction params to process
    per call. Defaults to 0 (all items in one call). If concurrency is enabled,
    defaults to 1. For complex tasks, you should not set a high value, in order to avoid
    prompt overloading.
  * **use_concurrency** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, enables concurrent processing of multiple items.
    Concurrency can considerably reduce processing time, but may cause rate limit errors
    with model providers. Use this option when API rate limits allow for multiple concurrent
    requests. Defaults to False.
  * **max_paragraphs_to_analyze_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum paragraphs to analyze in a single LLM
    prompt. A decision model is sent a text with more
    paragraphs in parts of at most that many paragraphs, each in a request of
    its own: a concept then gets an extracted item for each part, and
    a concept with `singular_occurrence=True` is rejected with `ValueError`.
    Defaults to 0 (all paragraphs). Cannot be negative.
  * **max_images_to_analyze_per_call** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum images to include in a single LLM prompt.
    Defaults to 0 (all images). Cannot be negative.
  * **raise_exception_on_extraction_error** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to raise an exception if the extraction fails
    due to invalid data returned by a model or an error in the model API. If False, a warning will
    be issued instead, and no extracted items will be returned. Defaults to True.
* **Returns:**
  List of processed Concept objects with extracted items.
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[`contextgem.internal.base.concepts._Concept`]

#### *classmethod* from_dict(obj_dict)

Reconstructs an instance of the class from a dictionary representation.

This method deserializes a dictionary containing the object’s attributes and values
into a new instance of the class. It handles complex nested structures like aspects,
concepts, and extracted items, properly reconstructing each component.

A deserialized model or model group has no API credentials, as they are not
included in the serialized data, i.e. they are to be set again.

* **Parameters:**
  **obj_dict** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`typing.Any`](https://docs.python.org/3/library/typing.html#typing.Any)]) – Dictionary containing the serialized object data.
* **Returns:**
  A new instance of the class with restored attributes.
* **Return type:**
  [`typing.Self`](https://docs.python.org/3/library/typing.html#typing.Self)

#### *classmethod* from_disk(file_path)

Loads an instance of the class from a JSON file stored on disk.

This method reads the JSON content from the specified file path and
deserializes it into an instance of the class using the from_json
method.

* **Parameters:**
  **file_path** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`pathlib.Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to the JSON file to load (must end with ‘.json’).
  Can be a string or a Path object.
* **Returns:**
  An instance of the class populated with the data from the file.
* **Return type:**
  [`typing.Self`](https://docs.python.org/3/library/typing.html#typing.Self)
* **Raises:**
  * [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If the file path doesn’t end with ‘.json’, or if the file
    does not hold valid serialized data, e.g. it is not a valid UTF-8 text
    (`UnicodeDecodeError`) or JSON (`json.JSONDecodeError`), or the data
    fails validation (pydantic’s `ValidationError`). These errors are
    subclasses of `ValueError`.
  * [**TypeError**](https://docs.python.org/3/builtins/exceptions.html#TypeError) – If the serialized data is of another class.
  * [**OSError**](https://docs.python.org/3/builtins/exceptions.html#OSError) – If the file cannot be read, e.g. it does not exist.
    The error is the one raised by the file operation, e.g.
    `FileNotFoundError` or `PermissionError`.

#### *classmethod* from_json(json_string)

Creates an instance of the class from a JSON string representation.

This method deserializes the provided JSON string into a dictionary and uses
the from_dict method to construct the class instance. It validates that the
class name in the serialized data matches the current class.

* **Parameters:**
  **json_string** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – JSON string containing the serialized object data.
* **Returns:**
  A new instance of the class with restored state.
* **Return type:**
  [`typing.Self`](https://docs.python.org/3/library/typing.html#typing.Self)
* **Raises:**
  * [**json.JSONDecodeError**](https://docs.python.org/3/library/json.html#json.JSONDecodeError) – If the string is not a valid JSON. The error
    gives the position of what is invalid, and does not hold the string.
  * [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If the JSON value is not an object with a class name,
    i.e. not serialized data.
  * [**TypeError**](https://docs.python.org/3/builtins/exceptions.html#TypeError) – If the class name in the serialized data doesn’t match.

#### get_cost(model_role=None)

Retrieves the accumulated cost information of the models in the group, filtered by the specified
model role if provided.

* **Parameters:**
  **model_role** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Optional; A string representing the role of the model to filter
  the cost data, validated in the same way as the roles assigned to models.
  If None, returns cost for all models in the group, including the model
  without a role.
* **Returns:**
  A list of cost statistics containers for the specified models and their fallbacks.
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[`contextgem.internal.data_models._ModelCostOutputContainer`]
* **Raises:**
  [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If the specified role is invalid, or if no model with
  the specified role exists in the group.

#### get_usage(model_role=None)

Retrieves the usage information of the models in the group, filtered by the specified
model role if provided.

* **Parameters:**
  **model_role** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Optional; A string representing the role of the model to filter
  the usage data, validated in the same way as the roles assigned to models.
  If None, returns usage for all models in the group, including the model
  without a role.
* **Returns:**
  A list of usage statistics containers for the specified models and their fallbacks.
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[`contextgem.internal.data_models._ModelUsageOutputContainer`]
* **Raises:**
  [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If the specified role is invalid, or if no model with
  the specified role exists in the group.

#### group_update_output_language(output_language)

Updates the output language for all LLMs in the group.

* **Parameters:**
  **output_language** ([`typing.Literal`](https://docs.python.org/3/library/typing.html#typing.Literal)[`'en'`, `'adapt'`]) – The new output language to set for all LLMs
* **Returns:**
  None
* **Return type:**
  [`None`](https://docs.python.org/3/builtins/constants.html#None)

#### *property* is_group *: [bool](https://docs.python.org/3/builtins/functions.html#bool)*

Returns True indicating this is a group of models.

* **Returns:**
  Always True for DocumentModelGroup instances.
* **Return type:**
  [bool](https://docs.python.org/3/builtins/functions.html#bool)

#### *property* list_roles *: [list](https://docs.python.org/3/builtins/stdtypes.html#list)[[str](https://docs.python.org/3/builtins/stdtypes.html#str) | [None](https://docs.python.org/3/builtins/constants.html#None)]*

Returns a list of all roles assigned to the models in this group.

* **Returns:**
  A list of model roles, with None standing for the model without a role
* **Return type:**
  [list](https://docs.python.org/3/builtins/stdtypes.html#list)[[str](https://docs.python.org/3/builtins/stdtypes.html#str) | None]

#### reset_usage_and_cost(model_role=None)

Resets the usage and cost statistics for models in the group.

This method clears accumulated usage and cost data, which is useful when processing
multiple documents sequentially and tracking metrics for each document separately.

* **Parameters:**
  **model_role** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Optional; A string representing the role of the model to reset statistics for,
  validated in the same way as the roles assigned to models. If None, resets statistics
  for all models in the group, including the model without a role.
* **Returns:**
  None
* **Return type:**
  [`None`](https://docs.python.org/3/builtins/constants.html#None)
* **Raises:**
  [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If the specified role is invalid, or if no model with
  the specified role exists in the group.

#### to_dict()

Transforms the current object into a dictionary representation.

Converts the object to a dictionary that includes:
- All public attributes
- Special handling for specific public and private attributes

When a model or model group is serialized, its API credentials and usage/cost stats are removed.

* **Returns:**
  A dictionary representation of the current object with all necessary data for serialization
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`typing.Any`](https://docs.python.org/3/library/typing.html#typing.Any)]

#### to_disk(file_path)

Saves the serialized instance to a JSON file at the specified path.

This method converts the instance to a dictionary representation using to_dict(),
then writes it to disk as a formatted JSON file with UTF-8 encoding.

* **Parameters:**
  **file_path** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`pathlib.Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path where the JSON file should be saved (must end with ‘.json’).
  Can be a string or a Path object.
* **Return type:**
  [`None`](https://docs.python.org/3/builtins/constants.html#None)
* **Returns:**
  None
* **Raises:**
  * [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If the file path doesn’t end with ‘.json’.
  * [**OSError**](https://docs.python.org/3/builtins/exceptions.html#OSError) – If the file cannot be written, e.g. its directory does not
    exist. The error is the one raised by the file operation, e.g.
    `FileNotFoundError` or `PermissionError`.

#### to_json()

Converts the object to its JSON string representation.

Serializes the object into a JSON-formatted string using the dictionary
representation provided by the to_dict() method.

* **Returns:**
  A JSON string representation of the object.
* **Return type:**
  [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)

#### models *: [list](https://docs.python.org/3/builtins/stdtypes.html#list)[\_DocumentModel]*

#### output_language *: [Literal](https://docs.python.org/3/library/typing.html#typing.Literal)['en', 'adapt']*
