Agent Skills Framework Extension
Claude Research Patterns Skill
When to Use This Skill
Use this skill when implementing claude research patterns patterns in your codebase.
How to Use This Skill
- Review the patterns and examples below
- Apply the relevant patterns to your implementation
- Follow the best practices outlined in this skill
Web research, documentation curation, source validation, and knowledge synthesis optimized for Claude Code.
Core Capabilities
- Web Research - Multi-source search and retrieval
- Documentation Curation - Official docs, guides, tutorials
- Source Validation - Authority, recency, accuracy verification
- Knowledge Synthesis - Multi-source consolidation
- Citation Management - Source tracking and attribution
Multi-Source Web Research
# scripts/web-research.py
import asyncio
import json
from datetime import datetime
from typing import List, Dict, Any
from dataclasses import dataclass, asdict
@dataclass
class SearchResult:
"""Structured search result"""
title: str
url: str
snippet: str
source_authority: float # 0.0-1.0
publication_date: str
relevance_score: float
citations: int = 0
@dataclass
class ResearchQuery:
"""Research query with strategy"""
query: str
sources: List[str] # Preferred domains
date_range: str # "1y", "6m", "1m"
required_keywords: List[str]
exclude_keywords: List[str]
class WebResearcher:
"""Orchestrate multi-source web research"""
def __init__(self):
self.search_engines = {
'google': self._google_search,
'github': self._github_search,
'stack_overflow': self._stackoverflow_search,
}
self.authority_scores = self._load_authority_database()
async def research(self, query: ResearchQuery) -> List[SearchResult]:
"""Execute multi-source research"""
tasks = []
for engine_name, search_func in self.search_engines.items():
tasks.append(search_func(query))
results = await asyncio.gather(*tasks, return_exceptions=True)
# Deduplicate and rank
all_results = []
seen_urls = set()
for engine_results in results:
if isinstance(engine_results, Exception):
continue
for result in engine_results:
if result.url not in seen_urls:
seen_urls.add(result.url)
all_results.append(result)
# Re-rank by authority and relevance
ranked = sorted(
all_results,
key=lambda r: (r.source_authority * r.relevance_score),
reverse=True
)
return ranked[:20] # Top 20
async def _google_search(self, query: ResearchQuery) -> List[SearchResult]:
"""Google search via WebSearch tool"""
# In practice: call Claude Code WebSearch
search_query = self._build_search_query(query)
# Simulate WebSearch call
results = []
# results = await web_search(search_query)
return [
SearchResult(
title=r['title'],
url=r['url'],
snippet=r['snippet'],
source_authority=self._get_authority_score(r['url']),
publication_date=r.get('date', 'unknown'),
relevance_score=self._calculate_relevance(r, query),
)
for r in results
]
async def _github_search(self, query: ResearchQuery) -> List[SearchResult]:
"""GitHub-specific search"""
# Search repos, issues, code
base_query = f"{query.query} language:python stars:>100"
results = []
# results = await github_api_search(base_query)
return results
async def _stackoverflow_search(self, query: ResearchQuery) -> List[SearchResult]:
"""Stack Overflow search"""
# Search questions with high votes/answers
base_query = f"{query.query} is:question score:5 answers:1"
results = []
# results = await stackoverflow_api_search(base_query)
return results
def _build_search_query(self, query: ResearchQuery) -> str:
"""Build optimized search query"""
parts = [query.query]
if query.sources:
parts.append(f"site:{' OR site:'.join(query.sources)}")
if query.required_keywords:
parts.extend([f'"{kw}"' for kw in query.required_keywords])
if query.exclude_keywords:
parts.extend([f'-{kw}' for kw in query.exclude_keywords])
if query.date_range:
parts.append(f"after:{query.date_range}")
return ' '.join(parts)
def _get_authority_score(self, url: str) -> float:
"""Get source authority score"""
domain = self._extract_domain(url)
return self.authority_scores.get(domain, 0.5)
def _calculate_relevance(self, result: Dict, query: ResearchQuery) -> float:
"""Calculate relevance score"""
# Simple keyword matching
text = f"{result['title']} {result['snippet']}".lower()
score = 0.0
for keyword in query.required_keywords:
if keyword.lower() in text:
score += 0.3
return min(score, 1.0)
def _load_authority_database(self) -> Dict[str, float]:
"""Load domain authority scores"""
return {
# Official documentation
'docs.python.org': 1.0,
'developer.mozilla.org': 1.0,
'docs.rust-lang.org': 1.0,
'go.dev': 1.0,
# High-authority tech sites
'github.com': 0.95,
'stackoverflow.com': 0.9,
'medium.com': 0.7,
'dev.to': 0.7,
# Academic
'arxiv.org': 0.95,
'papers.nips.cc': 0.95,
}
def _extract_domain(self, url: str) -> str:
"""Extract domain from URL"""
from urllib.parse import urlparse
return urlparse(url).netloc
# Usage example
async def main():
researcher = WebResearcher()
query = ResearchQuery(
query="Rust async/await best practices",
sources=['docs.rust-lang.org', 'github.com'],
date_range="1y",
required_keywords=['tokio', 'async'],
exclude_keywords=['deprecated']
)
results = await researcher.research(query)
print(f"Found {len(results)} results:")
for i, result in enumerate(results[:5], 1):
print(f"\n{i}. {result.title}")
print(f" URL: {result.url}")
print(f" Authority: {result.source_authority:.2f}")
print(f" Relevance: {result.relevance_score:.2f}")
if __name__ == '__main__':
asyncio.run(main())
Documentation Curation
# scripts/curate-documentation.py
from dataclasses import dataclass
from typing import List, Dict, Optional
import json
from pathlib import Path
@dataclass
class DocSource:
"""Documentation source"""
name: str
url: str
type: str # 'official', 'tutorial', 'guide', 'reference'
language: str
framework: Optional[str]
quality_score: float
last_updated: str
topics: List[str]
class DocumentationCurator:
"""Curate and organize technical documentation"""
def __init__(self, cache_dir: Path):
self.cache_dir = cache_dir
self.cache_dir.mkdir(exist_ok=True)
self.index: Dict[str, List[DocSource]] = {}
def add_source(self, source: DocSource):
"""Add documentation source to index"""
for topic in source.topics:
if topic not in self.index:
self.index[topic] = []
self.index[topic].append(source)
def find_docs(self, topic: str, min_quality: float = 0.7) -> List[DocSource]:
"""Find documentation for topic"""
if topic not in self.index:
return []
# Filter by quality and sort
docs = [
doc for doc in self.index[topic]
if doc.quality_score >= min_quality
]
# Prioritize: official > reference > guide > tutorial
type_priority = {
'official': 4,
'reference': 3,
'guide': 2,
'tutorial': 1,
}
return sorted(
docs,
key=lambda d: (type_priority.get(d.type, 0), d.quality_score),
reverse=True
)
def fetch_and_cache(self, source: DocSource) -> Path:
"""Fetch documentation and cache locally"""
cache_file = self.cache_dir / f"{source.name.replace('/', '_')}.md"
if cache_file.exists():
return cache_file
# Use WebFetch to retrieve
# content = web_fetch(source.url, "Extract main documentation content")
content = f"# {source.name}\n\nContent from {source.url}"
cache_file.write_text(content)
return cache_file
def create_reading_list(self, topic: str) -> str:
"""Generate curated reading list"""
docs = self.find_docs(topic)
md = f"# {topic} Documentation\n\n"
md += "## Official Documentation\n\n"
for doc in docs:
if doc.type == 'official':
md += f"- [{doc.name}](#)\n"
md += f" - Quality: {doc.quality_score:.1f}/1.0\n"
md += f" - Updated: {doc.last_updated}\n\n"
md += "## Guides & Tutorials\n\n"
for doc in docs:
if doc.type in ['guide', 'tutorial']:
md += f"- [{doc.name}](#) ({doc.type})\n"
return md
def save_index(self):
"""Save documentation index"""
index_file = self.cache_dir / 'doc-index.json'
serialized = {}
for topic, docs in self.index.items():
serialized[topic] = [
{
'name': d.name,
'url': d.url,
'type': d.type,
'quality_score': d.quality_score,
'topics': d.topics,
}
for d in docs
]
index_file.write_text(json.dumps(serialized, indent=2))
# Usage
curator = DocumentationCurator(Path('.coditect/doc-cache'))
# Add Rust documentation
curator.add_source(DocSource(
name="Rust Book",
url="https://doc.rust-lang.org/book/",
type="official",
language="rust",
framework=None,
quality_score=1.0,
last_updated="2024-01",
topics=["rust", "async", "ownership", "traits"]
))
curator.add_source(DocSource(
name="Tokio Tutorial",
url="https://tokio.rs/tokio/tutorial",
type="tutorial",
language="rust",
framework="tokio",
quality_score=0.95,
last_updated="2024-01",
topics=["rust", "async", "tokio", "networking"]
))
# Find and display
rust_docs = curator.find_docs("rust")
print(curator.create_reading_list("rust"))
Source Validation Framework
# scripts/validate-sources.py
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import List, Optional
import re
@dataclass
class ValidationResult:
"""Source validation result"""
is_valid: bool
authority_score: float
recency_score: float
accuracy_indicators: List[str]
warnings: List[str]
@property
def overall_score(self) -> float:
"""Combined validation score"""
return (self.authority_score * 0.5 +
self.recency_score * 0.3 +
(1.0 if self.is_valid else 0.0) * 0.2)
class SourceValidator:
"""Validate research sources"""
TRUSTED_DOMAINS = {
'docs.python.org', 'developer.mozilla.org',
'docs.rust-lang.org', 'go.dev', 'github.com',
'stackoverflow.com', 'arxiv.org'
}
def validate(self, url: str, content: str) -> ValidationResult:
"""Validate source comprehensively"""
domain = self._extract_domain(url)
authority = self._check_authority(domain)
recency = self._check_recency(content)
accuracy = self._check_accuracy_indicators(content)
warnings = self._detect_warnings(content, url)
is_valid = (
authority > 0.5 and
recency > 0.3 and
len(warnings) == 0
)
return ValidationResult(
is_valid=is_valid,
authority_score=authority,
recency_score=recency,
accuracy_indicators=accuracy,
warnings=warnings
)
def _check_authority(self, domain: str) -> float:
"""Check domain authority"""
if domain in self.TRUSTED_DOMAINS:
return 1.0
# Check for official keywords
if 'docs' in domain or 'documentation' in domain:
return 0.8
if 'github.com' in domain:
return 0.9
return 0.5 # Unknown domain
def _check_recency(self, content: str) -> float:
"""Check content recency"""
# Look for date indicators
year_pattern = r'20(1[0-9]|2[0-5])'
years = re.findall(year_pattern, content[:5000])
if not years:
return 0.5 # Unknown age
latest_year = max(int(y) for y in years)
current_year = datetime.now().year
age = current_year - latest_year
if age == 0:
return 1.0
elif age == 1:
return 0.9
elif age <= 2:
return 0.7
elif age <= 3:
return 0.5
else:
return 0.3
def _check_accuracy_indicators(self, content: str) -> List[str]:
"""Find accuracy indicators"""
indicators = []
if 'code example' in content.lower():
indicators.append('Has code examples')
if 'benchmark' in content.lower():
indicators.append('Includes benchmarks')
if re.search(r'v?\d+\.\d+\.\d+', content):
indicators.append('Version-specific')
if 'official' in content.lower():
indicators.append('Official source')
return indicators
def _detect_warnings(self, content: str, url: str) -> List[str]:
"""Detect warning signs"""
warnings = []
if 'deprecated' in content.lower():
warnings.append('Contains deprecated content')
if 'outdated' in content.lower():
warnings.append('Marked as outdated')
if 'beta' in url.lower() or 'preview' in url.lower():
warnings.append('Beta/preview documentation')
return warnings
def _extract_domain(self, url: str) -> str:
"""Extract domain from URL"""
from urllib.parse import urlparse
return urlparse(url).netloc
# Usage
validator = SourceValidator()
result = validator.validate(
"https://docs.rust-lang.org/book/ch15-00-smart-pointers.html",
"Smart Pointers in Rust (2024)"
)
print(f"Valid: {result.is_valid}")
print(f"Authority: {result.authority_score:.2f}")
print(f"Recency: {result.recency_score:.2f}")
print(f"Overall: {result.overall_score:.2f}")
Usage Examples
Multi-Source Research
Apply claude-research-patterns skill to research Rust async best practices from official docs and GitHub
Documentation Curation
Apply claude-research-patterns skill to curate Python asyncio documentation with quality scoring
Source Validation
Apply claude-research-patterns skill to validate technical sources and rank by authority
Integration Points
- research-patterns - Technical research depth
- memory-context-patterns - Research result caching
- content-marketing-patterns - Content creation from research
Success Output
When successful, this skill MUST output:
✅ SKILL COMPLETE: claude-research-patterns
Completed:
- [x] Multi-source web research executed
- [x] Documentation curated and indexed
- [x] Sources validated for authority and recency
- [x] Results ranked by relevance and quality
- [x] Research cached locally for reuse
- [x] Citations tracked with proper attribution
Research Summary:
- Query: "Rust async/await best practices"
- Sources searched: 3 (Google, GitHub, Stack Overflow)
- Results found: 47 total, 20 top-ranked
- Authority scores: 0.85-1.0 (high quality)
- Recency: 12 results from 2024-2025
- Cached: 15 documentation sources
Outputs:
- .coditect/doc-cache/doc-index.json (curated docs)
- .coditect/doc-cache/*.md (cached documentation)
- research-results.json (ranked search results)
- reading-list.md (curated reading list)
Completion Checklist
Before marking this skill as complete, verify:
- Multi-source research executed (Google, GitHub, Stack Overflow)
- Results deduplicated across sources
- Authority scores calculated for each source
- Recency scores based on publication dates
- Relevance scores based on keyword matching
- Results ranked by combined score
- Top 20 results returned
- Documentation sources cached locally
- Reading list generated with quality scores
- Source validation performed (authority, recency, accuracy)
- Citations tracked for all claims
Failure Indicators
This skill has FAILED if:
- ❌ No search results returned (all sources failed)
- ❌ Results not deduplicated (same URLs repeated)
- ❌ Authority scores missing or all default (0.5)
- ❌ No recency filtering (old/outdated results)
- ❌ Results not ranked (random order)
- ❌ Documentation not cached locally
- ❌ Source validation skipped
- ❌ Low-authority sources not flagged
- ❌ Deprecated content not detected
- ❌ Citations missing or incorrect
When NOT to Use
Do NOT use this skill when:
- Need real-time data (use live API calls instead)
- Searching internal/private documentation (use internal search)
- Looking for specific code examples in codebase (use Grep tool)
- Need structured data extraction (use web scraping patterns)
- Academic paper research (use academic-research skill)
- Patent/legal research (use specialized legal databases)
- Medical/health research (use peer-reviewed sources only)
Use alternative skills:
academic-research- Peer-reviewed paper researchcode-search-patterns- Internal codebase searchweb-scraping-patterns- Structured data extractionknowledge-synthesis- Multi-document consolidation
Anti-Patterns (Avoid)
| Anti-Pattern | Problem | Solution |
|---|---|---|
| Single source only | Incomplete or biased results | Always search multiple sources |
| No deduplication | Duplicate results clutter output | Deduplicate by URL |
| Ignoring authority | Low-quality sources pollute results | Calculate and filter by authority score |
| No recency check | Outdated information | Validate publication dates, filter old content |
| Missing citations | Unverifiable claims | Track source URL for every result |
| No caching | Repeated searches waste time | Cache documentation locally |
| Accepting all results | Include low-quality/deprecated content | Validate and rank by quality |
| No reading list | Results not organized | Generate curated reading list |
Principles
This skill embodies these CODITECT principles:
- #2 First Principles - Understand source authority and validation
- #5 Eliminate Ambiguity - Clear source rankings and quality scores
- #6 Clear, Understandable, Explainable - Citations track every claim
- #8 No Assumptions - Validate sources, don't trust blindly
- #9 Search Before Create - Research existing knowledge first
- #11 Research When in Doubt - Multi-source validation for accuracy
Full Principles: CODITECT-STANDARD-AUTOMATION.md