# How context_window_chars Improves Coreference Resolution in LangExtract

> Learn how context_window_chars enhances coreference resolution in LangExtract by providing crucial context across text chunks. Improve pronoun and reference accuracy.

- Repository: [Google/langextract](https://github.com/google/langextract)
- Tags: deep-dive
- Published: 2026-02-16

---

**The `context_window_chars` parameter injects a trailing slice of the previous chunk's text into each prompt, giving the language model the context necessary to resolve pronouns and references that span chunk boundaries.**

When processing long documents with the `google/langextract` library, texts are split into chunks to fit within model token limits. Without additional context, the model processes each chunk in isolation, making it impossible to link coreferential expressions like "she," "it," or "the company" to their antecedents when those antecedents appear in previous chunks. The `context_window_chars` parameter solves this by configuring a look-back window that preserves cross-chunk context.

## The Coreference Problem in Document Chunking

Language models operate within fixed context windows. When `langextract` divides a long document into chunks, each chunk becomes an independent prompt. If the first chunk mentions "Dr. Sarah Johnson" and the second chunk states "She performed the surgery," the model lacks the context to resolve that "She" refers to "Dr. Sarah Johnson."

This **coreference resolution** failure leads to incomplete extractions, particularly for entities that span multiple paragraphs or sections. The model extracts "Dr. Sarah Johnson" from the first chunk but fails to associate the pronoun "She" with that entity in subsequent chunks.

## How context_window_chars Works

The `context_window_chars` parameter activates the `ContextAwarePromptBuilder` class, which maintains state across chunk processing to inject previous context into subsequent prompts.

### The ContextAwarePromptBuilder Class

Located in [`langextract/prompting.py`](https://github.com/google/langextract/blob/main/langextract/prompting.py), the `ContextAwarePromptBuilder` class manages the context injection mechanism. When initialized with a `context_window_chars` value, the constructor stores this configuration for use during prompt building.

The builder uses the `_build_effective_context` method to extract the trailing characters from the previous chunk. If `context_window_chars` is set to `100`, the method captures the last 100 characters of the preceding text and formats them with a `[Previous text]:` prefix. This implementation appears in [`langextract/prompting.py`](https://github.com/google/langextract/blob/main/langextract/prompting.py) between lines 191-262.

### Per-Document Isolation

To prevent context leakage between different documents, the builder maintains a `_prev_chunk_by_doc_id` dictionary keyed by `document_id`. This ensures that when processing multiple documents concurrently, context from "Document A" never bleeds into "Document B." The isolation mechanism is implemented in the state management methods of [`langextract/prompting.py`](https://github.com/google/langextract/blob/main/langextract/prompting.py) between lines 196-207.

### Prompt Composition and State Management

The `build_prompt` method orchestrates the full prompt construction process through the following steps:

1. Calls `_build_effective_context` to retrieve the previous chunk slice
2. Combines this with any additional context provided
3. Renders the final prompt through the underlying `QAPromptGenerator`

After building the prompt, the `_update_state` method stores the current chunk text for use in the next iteration, creating a rolling window of context that moves through the document. This state update occurs in [`langextract/prompting.py`](https://github.com/google/langextract/blob/main/langextract/prompting.py) between lines 266-276.

### Annotation Pipeline Integration

The integration occurs in [`langextract/annotation.py`](https://github.com/google/langextract/blob/main/langextract/annotation.py), where the `Annotator.annotate_documents` method instantiates `ContextAwarePromptBuilder` with the user-provided `context_window_chars` value. Lines 58-62 of this file show the builder being passed to the inference loop, ensuring every batch of chunks receives the injected previous-chunk context.

## Practical Code Examples

### Using context_window_chars with the Annotator API

The simplest way to enable coreference resolution is through the high-level `Annotator` interface:

```python
from langextract import Annotator, PromptGenerator

# Configure your prompt generator

generator = PromptGenerator(
    system_message="You are a medical information extractor."
)

# Initialize the annotator with your language model

annotator = Annotator(
    language_model=my_llm,
    prompt_generator=generator,
)

# Process documents with a 100-character context window

for annotated_doc in annotator.annotate_documents(
    documents=my_documents,
    context_window_chars=100,
):
    print(annotated_doc.extractions)

```

When `context_window_chars=100` is specified, the `Annotator` creates a `ContextAwarePromptBuilder` that injects the last 100 characters of each previous chunk into the subsequent prompt. This allows the model to resolve references like "She" back to "Dr. Sarah Johnson" when the name appears in the trailing portion of the preceding chunk.

### Direct Use of ContextAwarePromptBuilder

For advanced customization, instantiate the builder directly to control context injection manually:

```python
from langextract.prompting import ContextAwarePromptBuilder
from langextract.prompt_generator import QAPromptGenerator

# Create the base prompt generator

generator = QAPromptGenerator(
    system_message="Extract person names."
)

# Initialize the context-aware builder with a 50-character window

builder = ContextAwarePromptBuilder(
    generator=generator,
    context_window_chars=50,
)

# First chunk - no previous context exists yet

prompt1 = builder.build_prompt(
    chunk_text="Dr. Sarah Johnson performed the surgery yesterday.",
    document_id="doc1",
)

# Second chunk - automatically receives context from the first chunk

prompt2 = builder.build_prompt(
    chunk_text="She was praised for her exceptional skill.",
    document_id="doc1",
)

print("Prompt 1 (no context):")
print(prompt1)
print("\nPrompt 2 (with context):")
print(prompt2)

# Output contains: "[Previous text]: ...Johnson performed the surgery yesterday."

```

In this example, the second prompt includes the trailing 50 characters from the first chunk ("Johnson performed the surgery yesterday"), providing the necessary context for the model to understand that "She" refers to "Dr. Sarah Johnson".

## Summary

- **Coreference resolution fails** when language models process document chunks in isolation, unable to link pronouns or references to antecedents in previous chunks.
- **`context_window_chars`** solves this by injecting a configurable number of trailing characters from the previous chunk into each subsequent prompt.
- **`ContextAwarePromptBuilder`** manages the stateful context injection, using `_prev_chunk_by_doc_id` to maintain isolation between different documents.
- **Implementation** spans [`langextract/prompting.py`](https://github.com/google/langextract/blob/main/langextract/prompting.py) (builder logic and `_build_effective_context` method), [`langextract/annotation.py`](https://github.com/google/langextract/blob/main/langextract/annotation.py) (pipeline integration), and [`langextract/prompt_generator.py`](https://github.com/google/langextract/blob/main/langextract/prompt_generator.py) (prompt rendering).
- **Usage** is available through the high-level `Annotator.annotate_documents(context_window_chars=...)` API or direct instantiation of `ContextAwarePromptBuilder`.

## Frequently Asked Questions

### What is the optimal value for context_window_chars?

The optimal value depends on your document structure and the types of references you need to resolve. Values between **50 and 200 characters** typically capture sufficient context for pronoun resolution without consuming excessive prompt space. For documents with long entity names or complex coreference chains, larger values (300-500 characters) may be necessary. Note that larger windows increase token usage and latency, so benchmark against your specific use case.

### Does context_window_chars affect processing speed or cost?

Yes, enabling `context_window_chars` increases both **token consumption** and **latency**. Each chunk after the first includes additional text from the previous chunk, increasing the prompt size by approximately the `context_window_chars` value per chunk. This results in higher API costs for LLM inference and slightly longer processing times. However, the trade-off is often justified by significantly improved extraction accuracy for coreferential entities.

### Can context_window_chars be used with multiple documents simultaneously?

Yes, `context_window_chars` is designed for **concurrent document processing**. The `ContextAwarePromptBuilder` uses a `_prev_chunk_by_doc_id` dictionary to isolate context between documents. When processing multiple documents simultaneously, ensure each document has a unique `document_id`. The builder automatically maintains separate context windows for each document ID, preventing cross-document contamination while allowing parallel processing.

### How does context_window_chars interact with other context parameters?

The `context_window_chars` parameter operates alongside the `additional_context` parameter available in `build_prompt`. When both are provided, the `ContextAwarePromptBuilder` concatenates the previous chunk slice (from `context_window_chars`) with any `additional_context` strings before passing the combined context to the underlying `QAPromptGenerator`. This allows you to combine automatic coreference context with custom domain knowledge or document metadata in a single prompt.