
Context Degradation
- 10 installs
- 1 repo stars
- Updated January 27, 2026
- bilalmk/todo_correct
context-degradation is a Claude Code skill that helps recognize, diagnose, and mitigate patterns of context degradation in agent systems.
About
This skill describes how large language model performance degrades as context grows and how to diagnose those failures. It defines patterns including the lost-in-middle effect, context poisoning, distraction, confusion, and clash, and explains how each one is detected and mitigated. A developer uses it when an agent starts producing wrong or irrelevant output during long conversations. It matters because these degradation patterns are predictable and can be addressed with architectural fixes like compaction and isolation.
- Names and defines five context degradation patterns: lost-in-middle, poisoning, distraction, confusion, and clash
- Cites research that middle-of-context information sees 10-40% lower recall
- Gives detection symptoms and recovery strategies for each pattern
Context Degradation by the numbers
- 10 all-time installs (skills.sh)
- Ranked #11,959 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Jul 28, 2026 (Skillselion catalog sync)
context-degradation capabilities & compatibility
- Capabilities
- debugging
- Use cases
- debugging · research
- Runs
- Runs locally
- Pricing
- Free
What context-degradation says it does
Recognize, diagnose, and mitigate patterns of context degradation in agent systems.
Language models exhibit predictable degradation patterns as context length increases.
relevant information placed in the middle of context experiences 10-40% lower recall accuracy
npx skills add https://github.com/bilalmk/todo_correct --skill context-degradationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 10 |
|---|---|
| repo stars | ★ 1 |
| Last updated | January 27, 2026 |
| Repository | bilalmk/todo_correct ↗ |
What it does
Diagnose why an agent degrades during long conversations and pick a mitigation for the specific context-failure pattern.
Who is it for?
Debugging why an agent produces incorrect output after long or large-context conversations.
When should I use this skill?
Context grows large, agent performance degrades unexpectedly, or you are debugging agent failures.
What you get
Identifies the specific degradation pattern behind a failure and prescribes a mitigation.
By the numbers
- Defines 5 distinct degradation patterns
- Cites 10-40% lower recall for middle-of-context information
Files
Context Degradation Patterns
Language models exhibit predictable degradation patterns as context length increases. Understanding these patterns is essential for diagnosing failures and designing resilient systems. Context degradation is not a binary state but a continuum of performance degradation that manifests in several distinct ways.
When to Activate
Activate this skill when:
- Agent performance degrades unexpectedly during long conversations
- Debugging cases where agents produce incorrect or irrelevant outputs
- Designing systems that must handle large contexts reliably
- Evaluating context engineering choices for production systems
- Investigating "lost in middle" phenomena in agent outputs
- Analyzing context-related failures in agent behavior
Core Concepts
Context degradation manifests through several distinct patterns. The lost-in-middle phenomenon causes information in the center of context to receive less attention. Context poisoning occurs when errors compound through repeated reference. Context distraction happens when irrelevant information overwhelms relevant content. Context confusion arises when the model cannot determine which context applies. Context clash develops when accumulated information directly conflicts.
These patterns are predictable and can be mitigated through architectural patterns like compaction, masking, partitioning, and isolation.
Detailed Topics
The Lost-in-Middle Phenomenon
The most well-documented degradation pattern is the "lost-in-middle" effect, where models demonstrate U-shaped attention curves. Information at the beginning and end of context receives reliable attention, while information buried in the middle suffers from dramatically reduced recall accuracy.
Empirical Evidence Research demonstrates that relevant information placed in the middle of context experiences 10-40% lower recall accuracy compared to the same information at the beginning or end. This is not a failure of the model but a consequence of attention mechanics and training data distributions.
Models allocate massive attention to the first token (often the BOS token) to stabilize internal states. This creates an "attention sink" that soaks up attention budget. As context grows, the limited budget is stretched thinner, and middle tokens fail to garner sufficient attention weight for reliable retrieval.
Practical Implications Design context placement with attention patterns in mind. Place critical information at the beginning or end of context. Consider whether information will be queried directly or needs to support reasoning—if the latter, placement matters less but overall signal quality matters more.
For long documents or conversations, use summary structures that surface key information at attention-favored positions. Use explicit section headers and transitions to help models navigate structure.
Context Poisoning
Context poisoning occurs when hallucinations, errors, or incorrect information enters context and compounds through repeated reference. Once poisoned, context creates feedback loops that reinforce incorrect beliefs.
How Poisoning Occurs Poisoning typically enters through three pathways. First, tool outputs may contain errors or unexpected formats that models accept as ground truth. Second, retrieved documents may contain incorrect or outdated information that models incorporate into reasoning. Third, model-generated summaries or intermediate outputs may introduce hallucinations that persist in context.
The compounding effect is severe. If an agent's goals section becomes poisoned, it develops strategies that take substantial effort to undo. Each subsequent decision references the poisoned content, reinforcing incorrect assumptions.
Detection and Recovery Watch for symptoms including degraded output quality on tasks that previously succeeded, tool misalignment where agents call wrong tools or parameters, and hallucinations that persist despite correction attempts. When these symptoms appear, consider context poisoning.
Recovery requires removing or replacing poisoned content. This may involve truncating context to before the poisoning point, explicitly noting the poisoning in context and asking for re-evaluation, or restarting with clean context and preserving only verified information.
Context Distraction
Context distraction emerges when context grows so long that models over-focus on provided information at the expense of their training knowledge. The model attends to everything in context regardless of relevance, and this creates pressure to use provided information even when internal knowledge is more accurate.
The Distractor Effect Research shows that even a single irrelevant document in context reduces performance on tasks involving relevant documents. Multiple distractors compound degradation. The effect is not about noise in absolute terms but about attention allocation—irrelevant information competes with relevant information for limited attention budget.
Models do not have a mechanism to "skip" irrelevant context. They must attend to everything provided, and this obligation creates distraction even when the irrelevant information is clearly not useful.
Mitigation Strategies Mitigate distraction through careful curation of what enters context. Apply relevance filtering before loading retrieved documents. Use namespacing and organization to make irrelevant sections easy to ignore structurally. Consider whether information truly needs to be in context or can be accessed through tool calls instead.
Context Confusion
Context confusion arises when irrelevant information influences responses in ways that degrade quality. This is related to distraction but distinct—confusion concerns the influence of context on model behavior rather than attention allocation.
If you put something in context, the model has to pay attention to it. The model may incorporate irrelevant information, use inappropriate tool definitions, or apply constraints that came from different contexts. Confusion is especially problematic when context contains multiple task types or when switching between tasks within a single session.
Signs of Confusion Watch for responses that address the wrong aspect of a query, tool calls that seem appropriate for a different task, or outputs that mix requirements from multiple sources. These indicate confusion about what context applies to the current situation.
Architectural Solutions Architectural solutions include explicit task segmentation where different tasks get different context windows, clear transitions between task contexts, and state management that isolates context for different objectives.
Context Clash
Context clash develops when accumulated information directly conflicts, creating contradictory guidance that derails reasoning. This differs from poisoning where one piece of information is incorrect—in clash, multiple correct pieces of information contradict each other.
Sources of Clash Clash commonly arises from multi-source retrieval where different sources have contradictory information, version conflicts where outdated and current information both appear in context, and perspective conflicts where different viewpoints are valid but incompatible.
Resolution Approaches Resolution approaches include explicit conflict marking that identifies contradictions and requests clarification, priority rules that establish which source takes precedence, and version filtering that excludes outdated information from context.
Empirical Benchmarks and Thresholds
Research provides concrete data on degradation patterns that inform design decisions.
RULER Benchmark Findings The RULER benchmark delivers sobering findings: only 50% of models claiming 32K+ context maintain satisfactory performance at 32K tokens. GPT-5.2 shows the least degradation among current models, while many still drop 30+ points at extended contexts. Near-perfect scores on simple needle-in-haystack tests do not translate to real long-context understanding.
Model-Specific Degradation Thresholds
| Model | Degradation Onset | Severe Degradation | Notes |
|---|---|---|---|
| GPT-5.2 | ~64K tokens | ~200K tokens | Best overall degradation resistance with thinking mode |
| Claude Opus 4.5 | ~100K tokens | ~180K tokens | 200K context window, strong attention management |
| Claude Sonnet 4.5 | ~80K tokens | ~150K tokens | Optimized for agents and coding tasks |
| Gemini 3 Pro | ~500K tokens | ~800K tokens | 1M context window, native multimodality |
| Gemini 3 Flash | ~300K tokens | ~600K tokens | 3x speed of Gemini 2.5, 81.2% MMMU-Pro |
Model-Specific Behavior Patterns Different models exhibit distinct failure modes under context pressure:
- Claude 4.5 series: Lowest hallucination rates with calibrated uncertainty. Claude Opus 4.5 achieves 80.9% on SWE-bench Verified. Tends to refuse or ask clarification rather than fabricate.
- GPT-5.2: Two modes available - instant (fast) and thinking (reasoning). Thinking mode reduces hallucination through step-by-step verification but increases latency.
- Gemini 3 Pro/Flash: Native multimodality with 1M context window. Gemini 3 Flash offers 3x speed improvement over previous generation. Strong at multi-modal reasoning across text, code, images, audio, and video.
These patterns inform model selection for different use cases. High-stakes tasks benefit from Claude 4.5's conservative approach or GPT-5.2's thinking mode; speed-critical tasks may use instant modes.
Counterintuitive Findings
Research reveals several counterintuitive patterns that challenge assumptions about context management.
Shuffled Haystacks Outperform Coherent Ones Studies found that shuffled (incoherent) haystacks produce better performance than logically coherent ones. This suggests that coherent context may create false associations that confuse retrieval, while incoherent context forces models to rely on exact matching.
Single Distractors Have Outsized Impact Even a single irrelevant document reduces performance significantly. The effect is not proportional to the amount of noise but follows a step function where the presence of any distractor triggers degradation.
Needle-Question Similarity Correlation Lower similarity between needle and question pairs shows faster degradation with context length. Tasks requiring inference across dissimilar content are particularly vulnerable.
When Larger Contexts Hurt
Larger context windows do not uniformly improve performance. In many cases, larger contexts create new problems that outweigh benefits.
Performance Degradation Curves Models exhibit non-linear degradation with context length. Performance remains stable up to a threshold, then degrades rapidly. The threshold varies by model and task complexity. For many models, meaningful degradation begins around 8,000-16,000 tokens even when context windows support much larger sizes.
Cost Implications Processing cost grows disproportionately with context length. The cost to process a 400K token context is not double the cost of 200K—it increases exponentially in both time and computing resources. For many applications, this makes large-context processing economically impractical.
Cognitive Load Metaphor Even with an infinite context, asking a single model to maintain consistent quality across dozens of independent tasks creates a cognitive bottleneck. The model must constantly switch context between items, maintain a comparative framework, and ensure stylistic consistency. This is not a problem that more context solves.
Practical Guidance
The Four-Bucket Approach
Four strategies address different aspects of context degradation:
Write: Save context outside the window using scratchpads, file systems, or external storage. This keeps active context lean while preserving information access.
Select: Pull relevant context into the window through retrieval, filtering, and prioritization. This addresses distraction by excluding irrelevant information.
Compress: Reduce tokens while preserving information through summarization, abstraction, and observation masking. This extends effective context capacity.
Isolate: Split context across sub-agents or sessions to prevent any single context from growing large enough to degrade. This is the most aggressive strategy but often the most effective.
Architectural Patterns
Implement these strategies through specific architectural patterns. Use just-in-time context loading to retrieve information only when needed. Use observation masking to replace verbose tool outputs with compact references. Use sub-agent architectures to isolate context for different tasks. Use compaction to summarize growing context before it exceeds limits.
Examples
Example 1: Detecting Degradation
# Context grows during long conversation
turn_1: 1000 tokens
turn_5: 8000 tokens
turn_10: 25000 tokens
turn_20: 60000 tokens (degradation begins)
turn_30: 90000 tokens (significant degradation)Example 2: Mitigating Lost-in-Middle
# Organize context with critical info at edges
[CURRENT TASK] # At start
- Goal: Generate quarterly report
- Deadline: End of week
[DETAILED CONTEXT] # Middle (less attention)
- 50 pages of data
- Multiple analysis sections
- Supporting evidence
[KEY FINDINGS] # At end
- Revenue up 15%
- Costs down 8%
- Growth in Region AGuidelines
1. Monitor context length and performance correlation during development 2. Place critical information at beginning or end of context 3. Implement compaction triggers before degradation becomes severe 4. Validate retrieved documents for accuracy before adding to context 5. Use versioning to prevent outdated information from causing clash 6. Segment tasks to prevent context confusion across different objectives 7. Design for graceful degradation rather than assuming perfect conditions 8. Test with progressively larger contexts to find degradation thresholds
Integration
This skill builds on context-fundamentals and should be studied after understanding basic context concepts. It connects to:
- context-optimization - Techniques for mitigating degradation
- multi-agent-patterns - Using isolation to prevent degradation
- evaluation - Measuring and detecting degradation in production
References
Internal reference:
- Degradation Patterns Reference - Detailed technical reference
Related skills in this collection:
- context-fundamentals - Context basics
- context-optimization - Mitigation techniques
- evaluation - Detection and measurement
External resources:
- Research on attention mechanisms and context window limitations
- Studies on the "lost-in-middle" phenomenon
- Production engineering guides from AI labs
---
Skill Metadata
Created: 2025-12-20 Last Updated: 2025-12-20 Author: Agent Skills for Context Engineering Contributors Version: 1.0.0
Context Degradation Patterns: Technical Reference
This document provides technical details on diagnosing and measuring context degradation.
Attention Distribution Analysis
U-Shaped Curve Measurement
Measure attention distribution across context positions:
def measure_attention_distribution(model, context_tokens, query):
"""
Measure how attention varies across context positions.
Returns distribution showing attention weight by position.
"""
attention_by_position = []
for position in range(len(context_tokens)):
# Measure model's attention to this position
attention = get_attention_weights(model, context_tokens, query, position)
attention_by_position.append({
"position": position,
"attention": attention,
"is_beginning": position < len(context_tokens) * 0.1,
"is_end": position > len(context_tokens) * 0.9,
"is_middle": True # Will be overwritten
})
# Classify positions
for item in attention_by_position:
if item["is_beginning"] or item["is_end"]:
item["region"] = "attention_favored"
else:
item["region"] = "attention_degraded"
return attention_by_positionLost-in-Middle Detection
Detect when critical information falls in degraded attention regions:
def detect_lost_in_middle(critical_positions, attention_distribution):
"""
Check if critical information is in attention-favored positions.
Args:
critical_positions: List of positions containing critical info
attention_distribution: Output from measure_attention_distribution
Returns:
Dictionary with detection results and recommendations
"""
results = {
"at_risk": [],
"safe": [],
"recommendations": []
}
for pos in critical_positions:
region = attention_distribution[pos]["region"]
if region == "attention_degraded":
results["at_risk"].append(pos)
else:
results["safe"].append(pos)
# Generate recommendations
if results["at_risk"]:
results["recommendations"].extend([
"Move critical information to attention-favored positions",
"Use explicit markers to highlight critical information",
"Consider splitting context to reduce middle section"
])
return resultsContext Poisoning Detection
Hallucination Tracking
Track potential hallucinations across conversation turns:
class HallucinationTracker:
def __init__(self):
self.claims = []
self.verifications = []
def add_claims(self, text):
"""Extract claims from text for later verification."""
claims = extract_claims(text)
self.claims.extend([{"text": c, "verified": None} for c in claims])
def verify_claims(self, ground_truth):
"""Verify claims against ground truth."""
for claim in self.claims:
if claim["verified"] is None:
claim["verified"] = check_claim(claim["text"], ground_truth)
def get_poisoning_indicators(self):
"""
Return indicators of potential context poisoning.
High ratio of unverified claims suggests poisoning risk.
"""
unverified = sum(1 for c in self.claims if not c["verified"])
verified_false = sum(1 for c in self.claims if c["verified"] == False)
return {
"unverified_count": unverified,
"false_count": verified_false,
"poisoning_risk": verified_false > 0 or unverified > len(self.claims) * 0.3
}Error Propagation Analysis
Track how errors flow through context:
def analyze_error_propagation(context, error_points):
"""
Analyze how errors at specific points affect downstream context.
Returns visualization of error spread and impact assessment.
"""
impact_map = {}
for error_point in error_points:
# Find all references to content after error point
downstream_refs = find_references(context, after=error_point)
for ref in downstream_refs:
if ref not in impact_map:
impact_map[ref] = []
impact_map[ref].append({
"source": error_point,
"type": classify_error_type(context[error_point])
})
# Assess severity
high_impact_areas = [k for k, v in impact_map.items() if len(v) > 3]
return {
"impact_map": impact_map,
"high_impact_areas": high_impact_areas,
"requires_intervention": len(high_impact_areas) > 0
}Distraction Metrics
Relevance Scoring
Score relevance of context elements to current task:
def score_context_relevance(context_elements, task_description):
"""
Score each context element for relevance to current task.
Returns scores and identifies high-distraction elements.
"""
task_embedding = embed(task_description)
scored_elements = []
for i, element in enumerate(context_elements):
element_embedding = embed(element)
relevance = cosine_similarity(task_embedding, element_embedding)
scored_elements.append({
"index": i,
"content_preview": element[:100],
"relevance_score": relevance
})
# Sort by relevance
scored_elements.sort(key=lambda x: x["relevance_score"], reverse=True)
# Identify potential distractors
threshold = calculate_relevance_threshold(scored_elements)
distractors = [e for e in scored_elements if e["relevance_score"] < threshold]
return {
"scored_elements": scored_elements,
"distractors": distractors,
"recommendation": f"Consider removing {len(distractors)} low-relevance elements"
}Degradation Monitoring System
Context Health Dashboard
Implement continuous monitoring of context health:
class ContextHealthMonitor:
def __init__(self, model, context_window_limit):
self.model = model
self.limit = context_window_limit
self.metrics = []
def assess_health(self, context, task):
"""
Assess overall context health for current task.
Returns composite score and component metrics.
"""
metrics = {
"token_count": len(context),
"utilization_ratio": len(context) / self.limit,
"attention_distribution": measure_attention_distribution(self.model, context, task),
"relevance_scores": score_context_relevance(context, task),
"age_tokens": count_recent_tokens(context)
}
# Calculate composite health score
health_score = self._calculate_composite(metrics)
result = {
"health_score": health_score,
"metrics": metrics,
"status": self._interpret_score(health_score),
"recommendations": self._generate_recommendations(metrics)
}
self.metrics.append(result)
return result
def _calculate_composite(self, metrics):
"""Calculate composite health score from components."""
# Weighted combination of metrics
utilization_penalty = min(metrics["utilization_ratio"] * 0.5, 0.3)
attention_penalty = self._calculate_attention_penalty(metrics["attention_distribution"])
relevance_penalty = self._calculate_relevance_penalty(metrics["relevance_scores"])
base_score = 1.0
score = base_score - utilization_penalty - attention_penalty - relevance_penalty
return max(0, score)
def _interpret_score(self, score):
"""Interpret health score and return status."""
if score > 0.8:
return "healthy"
elif score > 0.6:
return "warning"
elif score > 0.4:
return "degraded"
else:
return "critical"Alert Thresholds
Configure appropriate alert thresholds:
CONTEXT_ALERTS = {
"utilization_warning": 0.7, # 70% of context limit
"utilization_critical": 0.9, # 90% of context limit
"attention_degraded_ratio": 0.3, # 30% in middle region
"relevance_threshold": 0.3, # Below 30% relevance
"consecutive_warnings": 3 # Three warnings triggers alert
}Recovery Procedures
Context Truncation Strategy
When context degrades beyond recovery, truncate strategically:
def truncate_context_for_recovery(context, preserved_elements, target_size):
"""
Truncate context while preserving critical elements.
Strategy:
1. Preserve system prompt and tool definitions
2. Preserve recent conversation turns
3. Preserve critical retrieved documents
4. Summarize older content if needed
5. Truncate from middle if still over target
"""
truncated = []
# Category 1: Critical system elements (preserve always)
system_elements = extract_system_elements(context)
truncated.extend(system_elements)
# Category 2: Recent conversation (preserve more)
recent_turns = extract_recent_turns(context, num_turns=10)
truncated.extend(recent_turns)
# Category 3: Critical documents (preserve key ones)
critical_docs = extract_critical_documents(context, preserved_elements)
truncated.extend(critical_docs)
# Check size and summarize if needed
while len(truncated) > target_size:
# Summarize oldest category 3 elements
truncated = summarize_oldest(truncated, category="documents")
# If still too large, truncate oldest turns
if len(truncated) > target_size:
truncated = truncate_oldest_turns(truncated, keep_recent=5)
return truncated"""
Context Degradation Detection
This module provides utilities for detecting and measuring context degradation patterns.
PRODUCTION NOTES:
- The attention estimation functions in this module simulate U-shaped attention curves
for demonstration purposes. Production systems should extract actual attention weights
from model internals when available.
- Token estimation uses simplified heuristics (~4 chars/token). Production systems
should use model-specific tokenizers for accurate counts.
- The poisoning and hallucination detection uses pattern matching as a proxy.
Production systems may benefit from fine-tuned classifiers or model-based detection.
"""
import numpy as np
from typing import List, Dict
import re
def measure_attention_distribution(context_tokens: List[str], query: str) -> List[Dict]:
"""
Measure how attention varies across context positions.
Returns distribution showing attention weight by position.
"""
n = len(context_tokens)
attention_by_position = []
for position in range(n):
is_beginning = position < n * 0.1
is_end = position > n * 0.9
# Simulated attention measurement
# In production, this would use actual model attention weights
attention = _estimate_attention(position, n, is_beginning, is_end)
attention_by_position.append({
"position": position,
"attention": attention,
"region": "attention_favored" if (is_beginning or is_end) else "attention_degraded",
"tokens": context_tokens[position][:50] if position < 5 or position > n - 5 else None
})
return attention_by_position
def _estimate_attention(position: int, total: int, is_beginning: bool, is_end: bool) -> float:
"""
Estimate attention weight for position.
Simulates U-shaped attention curve based on research findings.
IMPORTANT: This is a simulation for demonstration purposes.
Production systems should:
1. Extract actual attention weights from model forward passes
2. Use model-specific attention analysis tools
3. Consider using interpretability libraries (e.g., TransformerLens)
The simulated curve reflects research findings:
- Beginning tokens receive high attention (primacy effect)
- End tokens receive high attention (recency effect)
- Middle tokens receive degraded attention (lost-in-middle)
"""
if is_beginning:
return 0.8 + np.random.random() * 0.2
elif is_end:
return 0.7 + np.random.random() * 0.3
else:
# Middle positions get reduced attention
middle_progress = (position - total * 0.1) / (total * 0.8)
base_attention = 0.3 * (1 - middle_progress) + 0.1 * middle_progress
return base_attention + np.random.random() * 0.1
# Lost-in-Middle Detection
def detect_lost_in_middle(critical_positions: List[int],
attention_distribution: List[Dict]) -> Dict:
"""
Check if critical information is in attention-degraded positions.
Returns detection results and recommendations.
"""
results = {
"at_risk": [],
"safe": [],
"recommendations": [],
"degradation_score": 0.0
}
at_risk_count = 0
total_critical = len(critical_positions)
for pos in critical_positions:
if pos < len(attention_distribution):
region = attention_distribution[pos]["region"]
if region == "attention_degraded":
results["at_risk"].append(pos)
at_risk_count += 1
else:
results["safe"].append(pos)
# Calculate degradation score
if total_critical > 0:
results["degradation_score"] = at_risk_count / total_critical
# Generate recommendations
if results["at_risk"]:
results["recommendations"].extend([
"Move critical information to attention-favored positions",
"Use explicit markers to highlight critical information",
"Consider splitting context to reduce middle section",
f"{at_risk_count}/{total_critical} critical items are in degraded region"
])
return results
def analyze_context_structure(context: str) -> Dict:
"""
Analyze context structure for degradation risk factors.
"""
lines = context.split('\n')
sections = []
current_section = {"start": 0, "type": "unknown", "length": 0}
for i, line in enumerate(lines):
# Detect section headers
if line.startswith('#'):
if current_section["length"] > 0:
sections.append(current_section)
current_section = {
"start": i,
"type": "header",
"length": 1,
"header": line.lstrip('#').strip()
}
else:
current_section["length"] += 1
sections.append(current_section)
# Analyze section distribution
n = len(lines)
middle_start = int(n * 0.3)
middle_end = int(n * 0.7)
middle_content = sum(
s["length"] for s in sections
if s["start"] >= middle_start and s["start"] <= middle_end
)
return {
"total_lines": n,
"sections": sections,
"middle_content_ratio": middle_content / n if n > 0 else 0,
"degradation_risk": "high" if middle_content / n > 0.5 else "medium" if middle_content / n > 0.3 else "low"
}
# Context Poisoning Detection
class PoisoningDetector:
def __init__(self):
self.claims = []
self.error_patterns = [
r"error",
r"failed",
r"exception",
r"cannot",
r"unable",
r"invalid",
r"not found"
]
def extract_claims(self, text: str) -> List[Dict]:
"""Extract claims from text for verification tracking."""
# Simple claim extraction - in production use NER and fact extraction
sentences = text.split('.')
claims = []
for i, sentence in enumerate(sentences):
sentence = sentence.strip()
if len(sentence) < 10:
continue
claims.append({
"id": i,
"text": sentence,
"verified": None,
"has_error_indicator": any(
re.search(pattern, sentence, re.IGNORECASE)
for pattern in self.error_patterns
)
})
self.claims.extend(claims)
return claims
def detect_poisoning(self, context: str) -> Dict:
"""
Detect potential context poisoning indicators.
"""
indicators = []
# Check for error accumulation
error_count = sum(
1 for pattern in self.error_patterns
if re.search(pattern, context, re.IGNORECASE)
)
if error_count > 3:
indicators.append({
"type": "error_accumulation",
"count": error_count,
"severity": "high" if error_count > 5 else "medium",
"message": f"Found {error_count} error indicators in context"
})
# Check for contradiction patterns
contradictions = self._detect_contradictions(context)
if contradictions:
indicators.append({
"type": "contradictions",
"count": len(contradictions),
"examples": contradictions[:3],
"severity": "high",
"message": f"Found {len(contradictions)} potential contradictions"
})
# Check for hallucination markers
hallucination_markers = self._detect_hallucination_markers(context)
if hallucination_markers:
indicators.append({
"type": "hallucination_markers",
"count": len(hallucination_markers),
"severity": "medium",
"message": f"Found {len(hallucination_markers)} phrases associated with uncertain claims"
})
return {
"poisoning_risk": len(indicators) > 0,
"indicators": indicators,
"overall_risk": "high" if len(indicators) > 2 else "medium" if len(indicators) > 0 else "low"
}
def _detect_contradictions(self, text: str) -> List[str]:
"""Detect potential contradictions in text."""
contradictions = []
# Look for conflict markers
conflict_patterns = [
(r"however", r"but"),
(r"on the other hand", r"instead"),
(r"although", r"yet"),
(r"despite", r"nevertheless")
]
for pattern1, pattern2 in conflict_patterns:
if re.search(pattern1, text, re.IGNORECASE) and re.search(pattern2, text, re.IGNORECASE):
# Find sentences containing these patterns
sentences = text.split('.')
for sentence in sentences:
if re.search(pattern1, sentence, re.IGNORECASE) or \
re.search(pattern2, sentence, re.IGNORECASE):
if sentence.strip() and len(sentence.strip()) < 200:
contradictions.append(sentence.strip()[:100])
return contradictions[:5]
def _detect_hallucination_markers(self, text: str) -> List[str]:
"""Detect phrases associated with uncertain or hallucinated claims."""
markers = [
"may have been",
"might have",
"could potentially",
"possibly",
"apparently",
"reportedly",
"it is said that",
"sources suggest",
"believed to be",
"thought to be"
]
found = []
for marker in markers:
if marker in text.lower():
found.append(marker)
return found
# Context Health Score
class ContextHealthAnalyzer:
def __init__(self, context_limit: int = 100000):
self.context_limit = context_limit
self.metrics_history = []
def analyze(self, context: str, critical_positions: List[int] = None) -> Dict:
"""
Perform comprehensive context health analysis.
"""
tokens = context.split()
# Basic metrics
token_count = len(tokens)
utilization = token_count / self.context_limit
# Attention analysis
attention_dist = measure_attention_distribution(
tokens[:1000], # Sample for efficiency
"current_task"
)
degradation = detect_lost_in_middle(
critical_positions or list(range(10)),
attention_dist
)
# Poisoning check
poisoning = PoisoningDetector().detect_poisoning(context)
# Calculate health score
health_score = self._calculate_health_score(
utilization=utilization,
degradation=degradation["degradation_score"],
poisoning_risk=1.0 if poisoning["poisoning_risk"] else 0.0
)
result = {
"health_score": health_score,
"status": self._interpret_score(health_score),
"metrics": {
"token_count": token_count,
"utilization": utilization,
"degradation_score": degradation["degradation_score"],
"poisoning_risk": poisoning["overall_risk"]
},
"issues": {
"lost_in_middle": degradation,
"poisoning": poisoning
},
"recommendations": self._generate_recommendations(
utilization, degradation, poisoning
)
}
self.metrics_history.append(result)
return result
def _calculate_health_score(self, utilization: float,
degradation: float,
poisoning_risk: float) -> float:
"""Calculate composite health score."""
# Weighted combination
utilization_penalty = min(utilization * 0.5, 0.3)
degradation_penalty = degradation * 0.3
poisoning_penalty = poisoning_risk * 0.2
score = 1.0 - utilization_penalty - degradation_penalty - poisoning_penalty
return max(0.0, min(1.0, score))
def _interpret_score(self, score: float) -> str:
"""Interpret health score."""
if score > 0.8:
return "healthy"
elif score > 0.6:
return "warning"
elif score > 0.4:
return "degraded"
else:
return "critical"
def _generate_recommendations(self, utilization: float,
degradation: Dict,
poisoning: Dict) -> List[str]:
"""Generate recommendations based on analysis."""
recommendations = []
if utilization > 0.8:
recommendations.append("Context near limit - consider compaction")
recommendations.append("Implement observation masking for tool outputs")
if degradation.get("at_risk"):
recommendations.append("Critical information in degraded attention region")
recommendations.append("Move key information to beginning or end of context")
if poisoning["poisoning_risk"]:
recommendations.append("Context poisoning indicators detected")
recommendations.append("Review and remove potentially erroneous information")
if not recommendations:
recommendations.append("Context appears healthy - continue monitoring")
return recommendations
# Usage Example
def analyze_agent_context(context: str) -> Dict:
"""Analyze context for an agent session."""
analyzer = ContextHealthAnalyzer(context_limit=80000)
# Define critical positions (e.g., goals, constraints)
critical_positions = list(range(5)) # First 5 items are critical
result = analyzer.analyze(context, critical_positions)
print(f"Health Score: {result['health_score']:.2f}")
print(f"Status: {result['status']}")
print(f"Recommendations:")
for rec in result["recommendations"]:
print(f" - {rec}")
return result
#!/usr/bin/env python3
"""Verify skill structure and content."""
import sys
from pathlib import Path
def main():
skill_dir = Path(__file__).parent.parent
skill_md = skill_dir / "SKILL.md"
if not skill_md.exists():
print("✗ SKILL.md not found")
sys.exit(1)
content = skill_md.read_text()
# Check frontmatter
if not content.startswith("---"):
print("✗ Missing YAML frontmatter")
sys.exit(1)
# Check required sections
required = ["When to Activate", "Core Concepts", "Guidelines"]
missing = [s for s in required if s not in content]
if missing:
print(f"✗ Missing sections: {', '.join(missing)}")
sys.exit(1)
print(f"✓ {skill_dir.name} skill validated")
sys.exit(0)
if __name__ == "__main__":
main()