.. meta::
   :description: What ContextGem already does that is easy to miss when you build on it, or when a coding agent does: references, your own IDs, retries and refusals, errors, costs, and tests without API calls.

Before You Build on ContextGem
==============================

Each point below is something that ContextGem already does, and that is easy to build again, or to get wrong, at first sight. Each links to the page that describes it.

- **References are the document's own objects.** A paragraph in ``reference_paragraphs`` of an extracted item is the same object as in ``document.paragraphs``, and each paragraph and sentence has a ``unique_id``. Put your own data, e.g. the ID of the record that a paragraph comes from, in the paragraph's ``custom_data``, and read it from the references. Do not match references by their text, which two paragraphs can share. See :ref:`locating-paras-and-sents`.
- **A document holds copies of the aspects and concepts you give it.** They are copied when they are assigned or added, so that you can reuse them for other documents: read the extracted items from ``document.aspects`` and ``document.concepts``, e.g. with ``get_concept_by_name()``, or from the list that the extraction method returns, not from the objects you created. See :class:`~contextgem.public.documents.Document`.
- **An answer that cannot be used is asked for again.** An answer of an LLM or a decision model that cannot be parsed or validated, or that the model or its provider declined to give, and an empty answer in a chat, is requested again, up to ``max_retries_invalid_data`` times (3 by default), and then the fallback models are tried. A refusal that none of them answers raises ``ModelRefusalError``, which you can catch apart from the other failures. The exception is a decision model that refuses to answer on some of the paragraphs of an aspect while it answers on the others: these paragraphs go to its fallback models, and what none of them decides is left out of the aspect. See :ref:`llm-retries-label` and :ref:`llm-refusals-label`.
- **Errors are exceptions of their own.** ``ContextGemError`` is the base of the errors of a run, e.g. ``ModelExtractionError`` and ``ModelAPIError``, while a mistake in your code, e.g. an invalid argument, is a ``ValueError`` or a ``TypeError``. With ``raise_exception_on_extraction_error=False``, a failed extraction logs a warning instead. See :doc:`api/exceptions`.
- **The costs of a model without prices.** With ``auto_pricing=True``, a model that ``genai-prices`` has no prices for gets an ``UnknownPricesWarning``, and its costs stay at zero. A warning filter on that category makes it raise where it is created, e.g. for a budget. See :ref:`llm-unknown-prices-label`.
- **Tests without API calls.** Replace ``litellm.acompletion`` and ``litellm.adecisions``, which ContextGem looks up at each request, with a stand-in in your tests. See :doc:`testing`.
- **Which version the documentation describes.** This documentation describes the latest release. The docstrings of the installed package describe the installed version, and the `changelog <https://github.com/shcherbak-ai/contextgem/blob/main/CHANGELOG.md>`_ gives the changes between versions.
