Claude for Long Document Analysis — 200K Token Guide 2026

Sanjeev SharmaSanjeev Sharma
6 min read

Advertisement

Introduction

Why This Matters

Claude's 200K-token context window is the largest available among major production LLMs without specialized infrastructure. It enables analysis of entire codebases, legal contracts, technical specifications, and research paper collections without complex retrieval pipelines. This guide covers practical workflows for long-document tasks — how to structure prompts, when to chunk, and when to let the full context window do the work.

Understanding Token Scale

200K tokens translates to real-world content sizes:

Content TypeApproximate Size
Novel (~80,000 words)~110K tokens
500-page PDF~130K tokens
50 Python files (500 lines each)~100K tokens
20 years of email threads~150K tokens
200-page legal contract~80K tokens

This means most single documents fit in one request. Multiple large documents, full codebases, or book-length corpora still require chunking or retrieval strategies.

Simple Long-Document Analysis

For documents that fit within 200K tokens, the workflow is straightforward:

import anthropic
from pathlib import Path
 
client = anthropic.Anthropic()
 
def analyze_document(file_path: str, question: str) -> str:
    """Load and analyze a text document with Claude."""
    content = Path(file_path).read_text(encoding="utf-8")
 
    # Rough token estimate: 1 token ≈ 4 characters
    estimated_tokens = len(content) // 4
    print(f"Document size: ~{estimated_tokens:,} tokens")
 
    if estimated_tokens > 180_000:
        raise ValueError(
            f"Document too large (~{estimated_tokens:,} tokens). "
            "Use chunked analysis instead."
        )
 
    response = client.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=4096,
        messages=[
            {
                "role": "user",
                "content": f"{content}\n\n---\n\nQuestion: {question}",
            }
        ],
    )
 
    return response.content[0].text
 
# Analyze a 200-page legal contract
result = analyze_document(
    "service_agreement.txt",
    "Identify all termination clauses, their conditions, and the notice periods required."
)
print(result)

Codebase Analysis

Sending an entire codebase to Claude for holistic analysis:

import anthropic
from pathlib import Path
 
client = anthropic.Anthropic()
 
EXCLUDE_PATTERNS = {".git", "__pycache__", "node_modules", ".venv", "dist", "build"}
INCLUDE_EXTENSIONS = {".py", ".js", ".ts", ".go", ".java", ".rs", ".sql", ".yaml", ".yml"}
 
def load_codebase(root_dir: str, max_tokens: int = 150_000) -> str:
    """Load source files from a directory into a formatted string."""
    root = Path(root_dir)
    sections = []
    total_chars = 0
    max_chars = max_tokens * 4  # Approximate: 4 chars per token
 
    for path in sorted(root.rglob("*")):
        # Skip excluded directories
        if any(excl in path.parts for excl in EXCLUDE_PATTERNS):
            continue
        if path.suffix not in INCLUDE_EXTENSIONS:
            continue
        if not path.is_file():
            continue
 
        try:
            content = path.read_text(encoding="utf-8")
        except Exception:
            continue
 
        relative = path.relative_to(root)
        section = f"=== {relative} ===\n{content}\n"
 
        if total_chars + len(section) > max_chars:
            sections.append(f"[Additional files truncated — {max_chars // 4000} file limit reached]")
            break
 
        sections.append(section)
        total_chars += len(section)
 
    return "\n".join(sections)
 
def review_codebase_security(root_dir: str) -> str:
    codebase = load_codebase(root_dir)
 
    response = client.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=4096,
        messages=[
            {
                "role": "user",
                "content": (
                    f"{codebase}\n\n"
                    "---\n\n"
                    "Perform a comprehensive security audit of this codebase.\n\n"
                    "For each finding:\n"
                    "1. File and line reference\n"
                    "2. Vulnerability type (OWASP category if applicable)\n"
                    "3. Severity: Critical / High / Medium / Low\n"
                    "4. Corrected code\n\n"
                    "Prioritize: injection flaws, authentication issues, "
                    "exposed secrets, and insecure dependencies."
                ),
            }
        ],
    )
 
    return response.content[0].text

Chunked Processing for Large Corpora

When content exceeds 180K tokens, chunk and aggregate:

import anthropic
from typing import Iterator
 
client = anthropic.Anthropic()
 
def chunk_text(text: str, chunk_size: int = 100_000) -> Iterator[str]:
    """Split text into overlapping chunks."""
    overlap = 2_000  # Characters of overlap to preserve context across chunks
    start = 0
    while start < len(text):
        end = start + chunk_size
        yield text[start:end]
        start = end - overlap
 
def analyze_large_document(
    file_path: str,
    question: str,
    synthesis_model: str = "claude-3-5-sonnet-20241022",
) -> str:
    """Analyze a document too large for a single context window."""
    content = open(file_path).read()
 
    # Step 1: Analyze each chunk
    chunk_summaries = []
    for i, chunk in enumerate(chunk_text(content)):
        response = client.messages.create(
            model="claude-3-5-haiku-20241022",  # Use Haiku for cheaper chunk processing
            max_tokens=1024,
            messages=[
                {
                    "role": "user",
                    "content": (
                        f"Chunk {i + 1} of the document:\n\n{chunk}\n\n"
                        f"Extract information relevant to this question: {question}\n"
                        "Be concise — only include directly relevant findings."
                    ),
                }
            ],
        )
        chunk_summaries.append(f"Chunk {i + 1}:\n{response.content[0].text}")
        print(f"Processed chunk {i + 1}")
 
    # Step 2: Synthesize all chunk summaries into a final answer
    combined = "\n\n".join(chunk_summaries)
    final_response = client.messages.create(
        model=synthesis_model,
        max_tokens=4096,
        messages=[
            {
                "role": "user",
                "content": (
                    f"These are summaries from different sections of a document:\n\n"
                    f"{combined}\n\n"
                    f"Based on all sections, provide a comprehensive answer to: {question}"
                ),
            }
        ],
    )
 
    return final_response.content[0].text

Document Comparison

Claude's long context enables direct comparison of multiple documents simultaneously:

def compare_documents(doc_paths: list[str], comparison_question: str) -> str:
    """Compare multiple documents within a single Claude context."""
    sections = []
    for i, path in enumerate(doc_paths):
        content = open(path).read()
        sections.append(f"=== Document {i + 1}: {path} ===\n{content}")
 
    combined = "\n\n".join(sections)
 
    response = client.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=4096,
        messages=[
            {
                "role": "user",
                "content": f"{combined}\n\n---\n\n{comparison_question}",
            }
        ],
    )
    return response.content[0].text
 
# Example: compare two API contracts
result = compare_documents(
    ["v1_api_spec.md", "v2_api_spec.md"],
    "List all breaking changes between v1 and v2. "
    "For each: what changed, who is affected, and what migration is required."
)

Common Mistakes

  • Not checking document size before submitting — a 250K-token document silently exceeds the limit and is truncated
  • Using Sonnet (expensive) for chunk processing steps when Haiku handles extraction equally well
  • Sending entire files including comments, whitespace, and test fixtures when only business logic is needed
  • Placing the question before the document in the prompt — Claude performs better when the document comes first
  • Not specifying output format — long-document responses tend toward vague prose without explicit structure instructions

Best Practices

  • Always estimate token size before submitting; use len(content) // 4 as a quick approximation
  • Place the document content before the question in the prompt for best retrieval performance
  • Use Haiku for chunk summarization passes; use Sonnet only for final synthesis
  • Request specific output formats (tables, numbered lists, JSON) to make long-document responses actionable
  • For repeated analysis of the same document, use prompt caching to cache the document content and reduce costs by 90%

Key Takeaways

  • Claude's 200K-token context fits a 500-page PDF, 50 Python files, or a 200-page legal contract in a single request
  • 1 token is approximately 4 characters — use len(text) // 4 to estimate token count before submitting
  • Place document content before the question in the prompt for best recall performance
  • For corpora exceeding 180K tokens, use Haiku for per-chunk extraction and Sonnet for final synthesis
  • Prompt caching on document content reduces repeat-analysis costs by 90% after the first request
  • Use Claude for direct document comparison — load multiple documents into one context without a retrieval pipeline
  • Chunked processing with overlap (2,000-character overlap is a good default) preserves context across chunk boundaries
  • Explicit output format instructions (table, numbered list, JSON) are especially important for long-document tasks

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro

Related reading