Choosing the Right LLM(s)#
🧭 General Guidance#
Your choice of LLM directly affects the accuracy, speed, and cost of your extraction pipeline. ContextGem integrates with various LLM providers (via LiteLLM), enabling you to select models that best fit your needs.
Since ContextGem specializes in deep single-document analysis, models with large context windows are recommended. While each use case has unique requirements, our experience suggests the following practical guidelines. However, please note that for sensitive applications (e.g., contract review) where accuracy is paramount and speed/cost are secondary concerns, using the most capable model available for all tasks is often the safest approach.
Aspect Extraction |
Concept Extraction |
---|---|
A smaller/distilled non-reasoning model capable of identifying relevant document sections (e.g., |
For basic concepts (e.g., titles, payment amounts, dates), the same smaller/distilled non-reasoning model is often sufficient (e.g., |
🏷️ LLM Roles#
Each LLM serves a specific role in your pipeline, defined by the role
parameter. This allows different models to handle different tasks. For instance, when an aspect or concept has llm_role="extractor_text"
, it will be processed by an LLM with that matching role.
You can assign any pre-defined role to an LLM regardless of whether it’s actually a “reasoning” model (like o3-mini) or not (like gpt-4o). This abstraction helps organize your pipeline based on your assessment of each model’s capabilities and task complexity. For simpler use cases, you can omit role assignments, which will default to "extractor_text"
.
# Example of selecting different LLMs for different tasks
import os
from contextgem import Aspect, Document, DocumentLLM, DocumentLLMGroup, StringConcept
# Define LLMs
base_llm = DocumentLLM(
model="openai/gpt-4o-mini",
api_key=os.environ.get("CONTEXTGEM_OPENAI_API_KEY"),
role="extractor_text", # default
)
# Optional - attach a fallback LLM
base_llm_fallback = DocumentLLM(
model="openai/gpt-3-5-turbo",
api_key=os.environ.get("CONTEXTGEM_OPENAI_API_KEY"),
role="extractor_text", # must have the same role as the parent LLM
is_fallback=True,
)
base_llm.fallback_llm = base_llm_fallback
advanced_llm = DocumentLLM(
model="openai/gpt-4o", # can be a larger model (reasoning or non-reasoning)
api_key=os.environ.get("CONTEXTGEM_OPENAI_API_KEY"),
role="reasoner_text",
)
# You can organize LLMs in a group to use them in a pipeline
llm_group = DocumentLLMGroup(
llms=[base_llm, advanced_llm],
)
# Assign the existing LLMs to aspects/concepts
document = Document(
raw_text="document_text",
aspects=[
Aspect(
name="aspect_name",
description="aspect_description",
llm_role="extractor_text",
concepts=[
StringConcept(
name="concept_name",
description="concept_description",
llm_role="reasoner_text",
)
],
)
],
)
# Then use the LLM group to extract all information from the document
# This will use different LLMs for different aspects/concepts under the hood
# document = llm_group.extract_all(document)