Claude for Long Document Analysis — 200K Token Guide 2026
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 Type | Approximate 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].textChunked 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].textDocument 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) // 4as 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) // 4to 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