Compare commits

...

1 Commits

Author SHA1 Message Date
HAL9000 16362adb76 docs: add context management deep dive 2026-04-19 14:56:28 +00:00
3 changed files with 2508 additions and 0 deletions
+998
View File
@@ -0,0 +1,998 @@
# Context Management Deep Dive
This comprehensive guide explores the Adaptive Context Management System (ACMS) architecture, strategies, and best practices for managing context in cleveragents-core.
## Table of Contents
1. [Context Management Architecture Overview](#context-management-architecture-overview)
2. [ACMS Pipeline Components](#acms-pipeline-components)
3. [Context Strategy Patterns](#context-strategy-patterns)
4. [Context Inheritance and Scope Resolution](#context-inheritance-and-scope-resolution)
5. [Budget Allocation and Utilization Metrics](#budget-allocation-and-utilization-metrics)
6. [Implementation Guide for Custom Strategies](#implementation-guide-for-custom-strategies)
7. [Best Practices and Performance Considerations](#best-practices-and-performance-considerations)
8. [Integration with Plan Execution](#integration-with-plan-execution)
9. [Real-world Examples](#real-world-examples)
## Context Management Architecture Overview
### What is Context Management?
Context management is the process of selecting, prioritizing, and packaging relevant information from a project's knowledge base to provide to language models (LMs) during plan execution. The ACMS ensures that:
- **Relevance**: Only the most pertinent information is included
- **Budget Compliance**: Token limits are strictly respected
- **Efficiency**: Context assembly is fast and deterministic
- **Traceability**: All context is provenance-tracked back to its source
### The Three-Tier Context Model
ACMS organizes context into three priority tiers:
| Tier | Purpose | Inclusion Strategy |
|------|---------|-------------------|
| **hot** | Critical context that must be included | Always included first; highest priority |
| **warm** | Standard context included when budget allows | Included after hot tier; default tier |
| **cold** | Low-priority context included only if space remains | Included last; only if budget permits |
> **Note:** In v1, tiers are sort-priority labels for ranking during assembly. Full storage-tier semantics with retention policies and promotion/demotion will be implemented in future milestones.
### Core Concepts
#### Context Fragments
A **ContextFragment** is the atomic unit of context. Each fragment represents a single piece of information:
```python
ContextFragment(
uko_node="project://myapp/src/main.py", # UKO URI of source
content="def main(): ...", # Rendered text content
detail_depth=3, # Depth level (0-9)
token_count=100, # Actual token count
relevance_score=0.9, # Relevance (0.0-1.0)
tier="hot", # Priority tier
provenance=FragmentProvenance( # Source tracking
resource_uri="project://myapp/src/main.py",
location="line 1-10",
resource_type="source_file"
)
)
```
**Key Properties:**
- `fragment_id`: Unique ULID identifier (auto-generated)
- `content`: Max 1,000,000 characters
- `detail_depth`: Resolved depth from 0 (MODULE_LISTING) to 9 (FULL_SOURCE)
- `token_count`: Must be >= 0; used for budget calculations
- `relevance_score`: 0.0 (irrelevant) to 1.0 (highly relevant)
- `metadata`: Arbitrary key-value pairs (max 64 entries)
- `created_at`: UTC timestamp for recency-based sorting
#### Context Budget
The **ContextBudget** defines token constraints:
```python
budget = ContextBudget(
max_tokens=4096, # Total available tokens
reserved_tokens=512 # Tokens reserved for system prompt
)
# Available tokens = max_tokens - reserved_tokens = 3584
```
**Budget Rules:**
- `available_tokens = max_tokens - reserved_tokens`
- `reserved_tokens` must be < `max_tokens`
- Pipeline never exceeds `available_tokens`
- Fragments exceeding budget are skipped
#### Context Payload
The assembled **ContextPayload** is the final output:
```python
payload = ContextPayload(
payload_id="01ARZ3NDEKTSV4RRFFQ69G5FAV", # ULID
plan_id="plan-1", # Associated plan
fragments=(fragment1, fragment2, ...), # Selected fragments
total_tokens=2048, # Sum of fragment tokens
budget=budget, # Budget used
budget_used=0.57, # Fraction consumed
strategies_used=("simple-keyword",), # Contributing strategies
context_hash="abc123...", # SHA-256 hash
preamble="Context includes 2 files...", # Optional summary
provenance_map={...}, # Fragment ID -> provenance
assembled_at=datetime.now(timezone.utc) # Assembly timestamp
)
```
**Key Properties:**
- `is_within_budget`: True if total_tokens <= available_tokens
- `remaining_tokens`: available_tokens - total_tokens
### Context Request Protocol (CRP)
The **ContextRequest** specifies what context is needed:
```python
request = ContextRequest(
focus_nodes=["project://myapp/src/main.py"], # Primary focus
breadth=2, # Graph traversal breadth
depth=3, # Graph traversal depth
keywords=["async", "io"], # Search keywords
resource_types=["source_file", "decision"], # Filter by type
detail_level=3, # Desired detail depth
temporal_window="7d", # Historical window
strategy_hints=["semantic-embedding"], # Preferred strategies
)
```
## ACMS Pipeline Components
The ACMS pipeline implements a 10-component architecture across three phases:
### Phase 1: Strategy Orchestration
#### 1. StrategySelector
**Purpose**: Determine which strategies can handle the request.
**Process**:
1. Poll all registered strategies with `can_handle(request)`
2. Each strategy returns confidence (0.0-1.0)
3. Select strategies above confidence threshold
4. Rank by confidence score
#### 2. BudgetAllocator
**Purpose**: Distribute token budget among selected strategies.
**Allocation Strategies**:
- **Proportional**: Allocate based on confidence scores
- **Equal**: Divide equally among strategies
- **Priority**: Allocate to highest-confidence first
#### 3. StrategyExecutor
**Purpose**: Execute strategies in parallel with timeout and circuit breaker.
**Features**:
- Parallel execution with configurable workers
- Per-strategy timeout (default 30s)
- Circuit breaker after N failures
- Graceful degradation on timeout
### Phase 2: Fragment Fusion
#### 4. FragmentDeduplicator
**Purpose**: Remove duplicate fragments based on UKO node and content hash.
**Deduplication Rules**:
- Same `uko_node` + same content hash = duplicate
- Keep fragment with highest relevance score
- Preserve provenance from all duplicates
#### 5. DetailDepthResolver
**Purpose**: Resolve appropriate detail depth for each fragment.
**Resolution Logic**:
- Start with requested detail level
- Adjust based on token budget
- Respect fragment's max depth
- Prefer higher depth for hot tier
#### 6. FragmentScorer
**Purpose**: Score fragments based on multiple factors.
**Scoring Factors**:
- Relevance score (from strategy)
- Tier priority (hot > warm > cold)
- Recency (created_at)
- Plan context alignment
- Resource type affinity
#### 7. BudgetPacker
**Purpose**: Select fragments to fit within token budget.
**Packing Algorithm**:
1. Sort fragments by score (descending)
2. Greedily add fragments until budget exhausted
3. Respect tier ordering (hot → warm → cold)
4. Early termination when budget full
#### 8. FragmentOrderer
**Purpose**: Determine final fragment order in payload.
**Ordering Strategies**:
- **Relevance**: By relevance_score (descending)
- **Recency**: By created_at (descending)
- **Tier-Relevance**: By tier, then relevance
- **Custom**: User-defined ordering
### Phase 3: Context Finalization
#### 9. PreambleGenerator
**Purpose**: Generate optional summary of assembled context.
**Preamble Contents**:
- Number of fragments and sources
- Token usage and budget utilization
- Strategies used
- Key topics covered
- Temporal range
#### 10. SkeletonCompressor
**Purpose**: Compress context for child plans while preserving critical information.
**Compression Strategy**:
- Identify critical fragments for child focus
- Remove redundant details
- Preserve decision context
- Maintain provenance
## Context Strategy Patterns
### Strategy Architecture
All strategies implement the `ContextStrategy` protocol:
```python
class ContextStrategy(Protocol):
@property
def name(self) -> str:
"""Unique strategy identifier"""
...
@property
def capabilities(self) -> StrategyCapabilities:
"""Declare backend requirements and quality"""
...
def can_handle(
self,
request: ContextRequest,
backends: BackendSet
) -> float:
"""Return confidence (0.0-1.0) for handling request"""
...
def assemble(
self,
request: ContextRequest,
backends: BackendSet,
budget: ContextBudget,
plan_context: PlanContext
) -> list[ContextFragment]:
"""Execute strategy and return fragments"""
...
def explain(self) -> str:
"""Human-readable description"""
...
```
### Built-in Strategies
#### 1. Simple Keyword Strategy
**Quality Score**: 0.3 (baseline)
**Backend Requirements**: TextBackend
**How It Works**:
1. Extract keywords from request
2. Search TextBackend using keywords
3. Rank results by match frequency
4. Pack greedily into budget
**Best For**:
- Quick searches with clear keywords
- Projects with good text indexing
- Fallback when other backends unavailable
#### 2. Semantic Embedding Strategy
**Quality Score**: 0.6 (good)
**Backend Requirements**: VectorBackend
**How It Works**:
1. Embed request using character-frequency model (v1)
2. Search VectorBackend for similar embeddings
3. Rank by cosine similarity
4. Pack budget-aware results
**Best For**:
- Semantic similarity searches
- Conceptual relationships
- Cross-domain context discovery
#### 3. Breadth-Depth Navigator Strategy
**Quality Score**: 0.85 (excellent)
**Backend Requirements**: GraphBackend
**How It Works**:
1. Start from focus nodes in request
2. Traverse graph outward by breadth hops
3. Traverse downward by depth hops
4. Collect all reachable nodes
5. Rank by distance and relevance
6. Pack into budget
**Best For**:
- Exploring related code and decisions
- Understanding dependencies
- Comprehensive context assembly
#### 4. ARCE Strategy (Advanced Retrieval with Context Enrichment)
**Quality Score**: 0.95 (highest)
**Backend Requirements**: TextBackend, VectorBackend, GraphBackend
**How It Works**:
1. **Phase 1 (40% budget)**: Text search using keywords
2. **Phase 2 (40% budget)**: Vector similarity search
3. **Phase 3 (20% budget)**: Graph traversal from results
4. Merge and deduplicate results
5. Rank by combined score
6. Pack into budget
**Best For**:
- Comprehensive context assembly
- Multi-modal queries
- Production use cases
#### 5. Temporal Archaeology Strategy
**Quality Score**: 0.5 (moderate)
**Backend Requirements**: GraphBackend, TemporalBackend (cold tier)
**How It Works**:
1. Query TemporalBackend for historical nodes
2. Filter by temporal window
3. Traverse graph from historical nodes
4. Collect related current nodes
5. Rank by recency and relevance
6. Pack into budget
**Best For**:
- Understanding historical context
- Decision archaeology
- Long-term project evolution
#### 6. Plan-Decision Context Strategy
**Quality Score**: 0.7 (good)
**Backend Requirements**: TemporalBackend (warm/cold), GraphBackend
**How It Works**:
1. Walk parent and ancestor plan hierarchy
2. Retrieve decision records from warm/cold tiers
3. Traverse graph from decisions
4. Collect related context
5. Rank by plan proximity and relevance
6. Pack into budget
**Best For**:
- Understanding plan context
- Decision inheritance
- Multi-level plan coordination
### Strategy Comparison Matrix
| Strategy | Quality | Speed | Coverage | Best For |
|----------|---------|-------|----------|----------|
| Simple Keyword | 0.3 | ⚡⚡⚡ | Narrow | Quick searches |
| Semantic Embedding | 0.6 | ⚡⚡ | Broad | Semantic similarity |
| Breadth-Depth Navigator | 0.85 | ⚡ | Very Broad | Comprehensive context |
| ARCE | 0.95 | 🐢 | Comprehensive | Production use |
| Temporal Archaeology | 0.5 | 🐢 | Historical | Historical context |
| Plan-Decision Context | 0.7 | ⚡ | Hierarchical | Plan coordination |
## Context Inheritance and Scope Resolution
### Scope Hierarchy
Context is organized in a hierarchy of scopes:
```
Global Scope
├── Project Scope
│ ├── Module Scope
│ │ ├── Class Scope
│ │ │ └── Method Scope
│ │ └── Function Scope
│ └── Decision Scope
└── Temporal Scope
├── Current
├── Recent (7d)
└── Historical (30d+)
```
### Scope Resolution Rules
When assembling context for a request:
1. **Start at Request Focus**: Begin with explicitly requested nodes
2. **Expand Upward**: Include parent scopes (module → project → global)
3. **Expand Downward**: Include child scopes (class → methods)
4. **Expand Sideways**: Include sibling scopes (related classes)
5. **Apply Filters**: Remove out-of-scope items based on resource types
6. **Respect Budget**: Stop expansion when budget exhausted
### Context Inheritance
Child plans inherit context from parent plans:
```python
# Parent plan context
parent_payload = ContextPayload(
fragments=[
ContextFragment(uko_node="project://myapp/src/main.py", ...),
ContextFragment(uko_node="project://myapp/src/utils.py", ...),
ContextFragment(uko_node="project://myapp/decisions/001", ...),
]
)
# Child plan inherits and specializes
child_request = ContextRequest(
focus_nodes=["project://myapp/src/main.py"],
parent_context=parent_payload,
inherit_strategy="skeleton" # Compress parent context
)
# Result: Child gets focused context + compressed parent context
child_payload = pipeline.assemble(child_request)
```
**Inheritance Strategies**:
- **Full**: Include all parent context (if budget allows)
- **Skeleton**: Compress parent context to essentials
- **None**: Start fresh (no parent context)
## Budget Allocation and Utilization Metrics
### Budget Planning
Effective budget allocation requires understanding token costs:
```python
# Typical token costs
costs = {
"system_prompt": 512, # Reserved
"user_request": 200, # Typical request
"model_response": 1024, # Expected response
"context": 2048, # Available for context
}
total_budget = 4096
reserved = 512
available = total_budget - reserved # 3584 tokens
```
### Budget Allocation Strategies
#### Proportional Allocation
Allocate based on strategy confidence scores:
```python
candidates = [
(semantic_embedding, 0.95),
(breadth_depth, 0.85),
(simple_keyword, 0.3)
]
total_confidence = 0.95 + 0.85 + 0.3 # 2.1
allocations = {
semantic_embedding: int(3584 * 0.95 / 2.1), # 1621
breadth_depth: int(3584 * 0.85 / 2.1), # 1450
simple_keyword: int(3584 * 0.3 / 2.1), # 513
}
```
#### Priority Allocation
Allocate to highest-confidence strategies first:
```python
allocations = {}
remaining = 3584
for strategy, confidence in sorted(candidates, key=lambda x: x[1], reverse=True):
# Allocate 50% of remaining budget
allocation = remaining // 2
allocations[strategy] = allocation
remaining -= allocation
```
#### Tier-Based Allocation
Allocate based on tier requirements:
```python
allocations = {
"hot_tier": 1000, # 28% - Critical context
"warm_tier": 2000, # 56% - Standard context
"cold_tier": 584, # 16% - Low-priority context
}
```
### Utilization Metrics
Track context assembly efficiency:
```python
metrics = {
"budget_used": payload.budget_used, # 0.57 (57%)
"remaining_tokens": payload.remaining_tokens, # 1536
"fragments_selected": len(payload.fragments), # 12
"fragments_total": 45, # Total available
"coverage": 12 / 45, # 26.7%
"strategies_used": payload.strategies_used, # ("semantic-embedding",)
"assembly_time_ms": 234, # Execution time
"avg_fragment_tokens": 2048 / 12, # 170.7
"avg_relevance": 0.82, # Mean relevance score
}
```
### Budget Optimization
Techniques to improve budget utilization:
1. **Increase Reserved Tokens**: Allocate more for system prompt
2. **Reduce Detail Depth**: Lower detail_depth for less critical fragments
3. **Increase Relevance Threshold**: Filter low-relevance fragments
4. **Use Skeleton Compression**: Compress parent context for child plans
5. **Tier-Based Filtering**: Exclude cold tier if budget tight
## Implementation Guide for Custom Strategies
### Creating a Custom Strategy
#### Step 1: Define Strategy Class
```python
from cleveragents.application.services.acms_service import (
ContextStrategy,
StrategyCapabilities,
)
from cleveragents.domain.models.core.context_fragment import (
ContextBudget,
ContextFragment,
)
from typing import Sequence, Any
class MyCustomStrategy:
"""Custom context strategy for specialized retrieval."""
@property
def name(self) -> str:
"""Unique strategy identifier."""
return "my-custom-strategy"
@property
def capabilities(self) -> StrategyCapabilities:
"""Declare backend requirements and quality."""
return StrategyCapabilities(
uses_text=True,
uses_vector=False,
uses_graph=True,
uses_temporal=False,
resource_types=("source_file", "decision"),
quality_score=0.75,
supports_depth_breadth=True,
supports_plan_hierarchy=False,
supports_temporal=False,
)
def can_handle(self, request: dict[str, Any]) -> float:
"""Return confidence (0.0-1.0) for handling request."""
# Check if request has required fields
if "focus_nodes" not in request:
return 0.0
# Check for specific keywords
keywords = request.get("keywords", [])
if any(kw in ["async", "io", "performance"] for kw in keywords):
return 0.9 # High confidence for performance-related queries
return 0.6 # Moderate confidence for general queries
def assemble(
self,
fragments: Sequence[ContextFragment],
budget: ContextBudget,
) -> Sequence[ContextFragment]:
"""Execute strategy and return fragments."""
# Custom ranking logic
ranked = sorted(
fragments,
key=lambda f: (
f.tier == "hot", # Hot tier first
f.relevance_score, # Then by relevance
f.created_at, # Then by recency
),
reverse=True
)
# Pack into budget
selected = []
total_tokens = 0
for fragment in ranked:
if total_tokens + fragment.token_count <= budget.available_tokens:
selected.append(fragment)
total_tokens += fragment.token_count
else:
break # Budget exhausted
return selected
def explain(self) -> str:
"""Human-readable description."""
return (
"Custom strategy that prioritizes hot-tier fragments "
"and performance-related keywords."
)
```
#### Step 2: Register Strategy
```python
from cleveragents.application.services.acms_service import ACMSPipeline
# Create pipeline
pipeline = ACMSPipeline()
# Register custom strategy
strategy = MyCustomStrategy()
pipeline.register_strategy(strategy.name, strategy)
# Use in assembly
payload = pipeline.assemble(
plan_id="plan-1",
fragments=fragments,
budget=budget,
strategy="my-custom-strategy"
)
```
#### Step 3: Configure in TOML
```toml
[context.strategies]
enabled = ["simple-keyword", "my-custom-strategy"]
[context.strategies.custom]
"my-custom-strategy" = "my_package.strategies:MyCustomStrategy"
[context.strategies."my-custom-strategy"]
enabled = true
timeout_seconds = 30
max_fragments = 100
```
## Best Practices and Performance Considerations
### Performance Optimization
#### 1. Strategy Selection
**Best Practice**: Use strategy confidence scores to avoid unnecessary execution.
#### 2. Budget Allocation
**Best Practice**: Allocate more budget to higher-confidence strategies.
#### 3. Timeout Management
**Best Practice**: Set appropriate timeouts based on strategy complexity.
#### 4. Fragment Deduplication
**Best Practice**: Deduplicate early to reduce downstream processing.
#### 5. Detail Depth Resolution
**Best Practice**: Reduce detail depth for less critical fragments.
### Memory Efficiency
#### 1. Fragment Streaming
**Best Practice**: Stream fragments instead of loading all at once.
#### 2. Lazy Evaluation
**Best Practice**: Defer expensive operations until needed.
### Reliability and Robustness
#### 1. Circuit Breaker Pattern
**Best Practice**: Implement circuit breaker for failing strategies.
#### 2. Graceful Degradation
**Best Practice**: Fall back to simpler strategies when complex ones fail.
#### 3. Timeout Handling
**Best Practice**: Set reasonable timeouts with fallback.
### Monitoring and Observability
#### 1. Metrics Collection
**Best Practice**: Collect comprehensive metrics for monitoring.
#### 2. Logging
**Best Practice**: Log key decisions and failures.
## Integration with Plan Execution
### Context Assembly in Plan Execution
Context is assembled at key points in plan execution:
```
Plan Execution Flow
├── Plan Created
│ └── Initial Context Assembly
│ ├── StrategySelector: Choose strategies
│ ├── BudgetAllocator: Allocate tokens
│ └── StrategyExecutor: Execute strategies
├── Plan Step Execution
│ └── Context Refresh (optional)
│ └── Incremental context updates
├── Subplan Creation
│ └── Context Inheritance
│ ├── Inherit parent context
│ └── Specialize for subplan focus
└── Plan Completion
└── Context Archive
└── Store for historical reference
```
### Context Request from Plan
Plans generate context requests based on their focus.
### Context Injection into Plan
Assembled context is injected into plan execution.
### Subplan Context Inheritance
Child plans inherit and specialize context.
## Real-world Examples
### Example 1: Implementing a New Feature
**Scenario**: Implement async I/O support in a Python project.
**Context Assembly**:
```python
# 1. Create context request
request = ContextRequest(
focus_nodes=[
"project://myapp/src/main.py",
"project://myapp/src/io.py"
],
keywords=["async", "io", "performance"],
breadth=2,
depth=3,
resource_types=["source_file", "decision"],
detail_level=4
)
# 2. Assemble context
payload = pipeline.assemble(
plan_id="plan-async-io",
fragments=fetch_fragments(backends, request),
budget=ContextBudget(max_tokens=4096, reserved_tokens=512),
strategy="arce" # Use comprehensive strategy
)
# 3. Inspect assembled context
print(f"Fragments: {len(payload.fragments)}")
print(f"Tokens: {payload.total_tokens} / {payload.budget.available_tokens}")
print(f"Budget used: {payload.budget_used:.1%}")
print(f"Strategies: {payload.strategies_used}")
# 4. Use context in plan execution
plan = Plan(
title="Implement async I/O",
context_payload=payload,
context_hash=payload.context_hash
)
```
**Result**: LM receives focused context on async I/O patterns, related decisions, and performance considerations.
### Example 2: Debugging a Performance Issue
**Scenario**: Investigate slow database queries.
**Context Assembly**:
```python
# 1. Create context request focused on database code
request = ContextRequest(
focus_nodes=["project://myapp/src/database.py"],
keywords=["query", "performance", "slow", "index"],
breadth=3, # Broader search for related code
depth=2, # Less deep (focus on structure)
resource_types=["source_file", "decision", "test"],
detail_level=2, # Less detail to fit more context
temporal_window="30d" # Include recent changes
)
# 2. Assemble with temporal strategy
payload = pipeline.assemble(
plan_id="plan-debug-perf",
fragments=fetch_fragments(backends, request),
budget=ContextBudget(max_tokens=4096, reserved_tokens=512),
strategy="temporal-archaeology" # Include historical context
)
# 3. Analyze context
hot_fragments = [f for f in payload.fragments if f.tier == "hot"]
recent_fragments = sorted(
payload.fragments,
key=lambda f: f.created_at,
reverse=True
)[:5]
print(f"Hot tier fragments: {len(hot_fragments)}")
print(f"Recent changes: {[f.uko_node for f in recent_fragments]}")
```
**Result**: LM receives context on database code, recent changes, and historical decisions about performance.
### Example 3: Code Review with Context
**Scenario**: Review a pull request with full context.
**Context Assembly**:
```python
# 1. Get changed files from PR
changed_files = [
"project://myapp/src/auth.py",
"project://myapp/src/security.py",
"project://myapp/tests/test_auth.py"
]
# 2. Create context request
request = ContextRequest(
focus_nodes=changed_files,
breadth=1, # Narrow search (focus on changed files)
depth=4, # Deeper (understand full context)
resource_types=["source_file", "decision", "test"],
detail_level=5, # Higher detail for review
strategy_hints=["breadth-depth-navigator"] # Use graph traversal
)
# 3. Assemble context
payload = pipeline.assemble(
plan_id="plan-review-pr",
fragments=fetch_fragments(backends, request),
budget=ContextBudget(max_tokens=8192, reserved_tokens=512),
strategy="breadth-depth-navigator"
)
# 4. Generate review context
review_context = {
"changed_files": changed_files,
"context_fragments": len(payload.fragments),
"context_tokens": payload.total_tokens,
"related_decisions": [
f for f in payload.fragments
if "decision" in f.metadata.get("resource_type", "")
],
"related_tests": [
f for f in payload.fragments
if "test" in f.uko_node
]
}
```
**Result**: LM receives comprehensive context on changed files, related code, decisions, and tests for thorough review.
### Example 4: Multi-level Plan Hierarchy
**Scenario**: Execute a complex plan with multiple subplans.
**Context Assembly**:
```python
# Parent plan context
parent_request = ContextRequest(
focus_nodes=["project://myapp"],
breadth=2,
depth=2,
detail_level=2
)
parent_payload = pipeline.assemble(
plan_id="plan-refactor",
fragments=fetch_fragments(backends, parent_request),
budget=ContextBudget(max_tokens=4096, reserved_tokens=512),
strategy="arce"
)
# Subplan 1: Refactor auth module
subplan1_request = ContextRequest(
focus_nodes=["project://myapp/src/auth.py"],
parent_context=parent_payload,
inherit_strategy="skeleton", # Compress parent
breadth=2,
depth=3,
detail_level=4
)
subplan1_payload = pipeline.assemble(
plan_id="plan-refactor-auth",
fragments=fetch_fragments(backends, subplan1_request),
budget=ContextBudget(max_tokens=3584, reserved_tokens=512),
strategy="breadth-depth-navigator"
)
# Subplan 2: Refactor database module
subplan2_request = ContextRequest(
focus_nodes=["project://myapp/src/database.py"],
parent_context=parent_payload,
inherit_strategy="skeleton",
breadth=2,
depth=3,
detail_level=4
)
subplan2_payload = pipeline.assemble(
plan_id="plan-refactor-db",
fragments=fetch_fragments(backends, subplan2_request),
budget=ContextBudget(max_tokens=3584, reserved_tokens=512),
strategy="breadth-depth-navigator"
)
# Execute hierarchy
execute_plan(parent_plan, parent_payload)
execute_plan(subplan1, subplan1_payload)
execute_plan(subplan2, subplan2_payload)
```
**Result**: Parent plan gets broad context; subplans get specialized context with parent context compressed for efficiency.
## Conclusion
The ACMS provides a powerful, flexible system for managing context in cleveragents-core. By understanding the architecture, strategies, and best practices, you can:
- **Assemble relevant context** efficiently and deterministically
- **Respect token budgets** while maximizing information density
- **Implement custom strategies** for specialized use cases
- **Optimize performance** through careful budget allocation
- **Integrate seamlessly** with plan execution
For more information, see:
- [Context Strategies Reference](../reference/context_strategies_reference.md)
- [ACMS Pipeline Reference](../reference/acms_pipeline_reference.md)
- [ACMS v1 Context Assembly Pipeline](../reference/acms.md)
- [Context Strategy Registry](../reference/context_strategies.md)
+760
View File
@@ -0,0 +1,760 @@
# ACMS Pipeline Reference
Complete reference for the ACMS Pipeline components, their interactions, data flow, configuration, and monitoring.
## Pipeline Architecture
The ACMS pipeline implements a 10-component architecture across three phases:
```
Phase 1: Strategy Orchestration
├── StrategySelector
├── BudgetAllocator
└── StrategyExecutor
Phase 2: Fragment Fusion
├── FragmentDeduplicator
├── DetailDepthResolver
├── FragmentScorer
├── BudgetPacker
└── FragmentOrderer
Phase 3: Context Finalization
├── PreambleGenerator
└── SkeletonCompressor
```
## Component Reference
### Phase 1: Strategy Orchestration
#### StrategySelector
**Purpose**: Determine which strategies can handle the request.
**Input**:
- `strategies`: List of registered strategies
- `request`: ContextRequest with focus nodes, keywords, etc.
- `backends`: Available backends (TextBackend, VectorBackend, etc.)
**Output**:
- `candidates`: List of (strategy, confidence) tuples, sorted by confidence descending
**Process**:
1. Poll each strategy with `can_handle(request, backends)`
2. Collect confidence scores (0.0-1.0)
3. Filter strategies with confidence >= threshold (default 0.0)
4. Sort by confidence descending
5. Return top candidates
**Configuration**:
```toml
[context.strategies]
selector_threshold = 0.0
max_candidates = 10
```
**Example**:
```python
selector = StrategySelector()
candidates = selector.select(
strategies=[simple_keyword, semantic_embedding, breadth_depth],
request=context_request,
backends=backend_set
)
# Returns: [(semantic_embedding, 0.95), (breadth_depth, 0.85), ...]
```
#### BudgetAllocator
**Purpose**: Distribute token budget among selected strategies.
**Input**:
- `candidates`: List of (strategy, confidence) tuples
- `total_budget`: Available tokens for context
- `request`: ContextRequest with budget hints
**Output**:
- `allocations`: Dict mapping strategy -> allocated tokens
**Allocation Strategies**:
1. **Proportional** (default):
```
allocation[s] = total_budget * confidence[s] / sum(confidences)
```
2. **Equal**:
```
allocation[s] = total_budget / len(candidates)
```
3. **Priority**:
```
Sort by confidence, allocate 50% of remaining to each
```
**Configuration**:
```toml
[context.strategies]
allocator_strategy = "proportional"
allocator_min_budget = 100
```
**Example**:
```python
allocator = BudgetAllocator()
allocations = allocator.allocate(
candidates=[(semantic_embedding, 0.95), (breadth_depth, 0.85)],
total_budget=3584,
request=context_request
)
# Returns: {semantic_embedding: 1900, breadth_depth: 1684}
```
#### StrategyExecutor
**Purpose**: Execute strategies in parallel with timeout and circuit breaker.
**Input**:
- `allocations`: Dict mapping strategy -> allocated tokens
- `request`: ContextRequest
- `backends`: Available backends
- `plan_context`: Current plan context
**Output**:
- `results`: List of StrategyResult objects
**Features**:
- Parallel execution with configurable workers
- Per-strategy timeout (default 30s)
- Circuit breaker after N failures
- Graceful degradation on timeout
**Configuration**:
```toml
[context.strategies]
executor_max_workers = 4
executor_timeout_seconds = 30
executor_circuit_breaker_threshold = 3
executor_circuit_breaker_reset_timeout = 60
```
**Example**:
```python
executor = StrategyExecutor(max_workers=4, timeout_seconds=30)
results = executor.execute(
allocations={semantic_embedding: 1900, breadth_depth: 1684},
request=context_request,
backends=backend_set,
plan_context=plan_context
)
# Returns: [StrategyResult(...), StrategyResult(...)]
```
**StrategyResult**:
```python
@dataclass
class StrategyResult:
strategy_name: str
fragments: tuple[ContextFragment, ...]
total_fragments: int
tokens_used: int
execution_time_ms: float
errors: tuple[str, ...]
stats: dict[str, Any]
```
### Phase 2: Fragment Fusion
#### FragmentDeduplicator
**Purpose**: Remove duplicate fragments based on UKO node and content hash.
**Input**:
- `fragments`: List of ContextFragment objects
- `strategy`: Deduplication strategy ("highest_relevance", "first_seen", "most_recent")
**Output**:
- `deduplicated`: List of unique fragments
**Deduplication Rules**:
- Same `uko_node` + same content hash = duplicate
- Keep fragment with highest relevance score (default)
- Merge provenance from all duplicates
**Configuration**:
```toml
[context.strategies]
deduplicator_strategy = "highest_relevance"
deduplicator_merge_provenance = true
```
**Example**:
```python
deduplicator = FragmentDeduplicator()
deduplicated = deduplicator.deduplicate(
fragments=[frag1, frag2, frag1_duplicate],
strategy="highest_relevance"
)
# Returns: [frag1 (with merged provenance), frag2]
```
#### DetailDepthResolver
**Purpose**: Resolve appropriate detail depth for each fragment.
**Input**:
- `fragments`: List of ContextFragment objects
- `budget`: ContextBudget
- `request`: ContextRequest with desired detail level
**Output**:
- `resolved`: List of fragments with adjusted detail_depth
**Resolution Logic**:
1. Start with requested detail level
2. Adjust based on token budget
3. Respect fragment's max depth
4. Prefer higher depth for hot tier
**Configuration**:
```toml
[context.strategies]
resolver_default_depth = 3
resolver_hot_tier_boost = 2
resolver_budget_aware = true
```
**Example**:
```python
resolver = DetailDepthResolver()
resolved = resolver.resolve(
fragments=[frag1, frag2],
budget=budget,
request=context_request
)
# Returns: fragments with adjusted detail_depth
```
#### FragmentScorer
**Purpose**: Score fragments based on multiple factors.
**Input**:
- `fragments`: List of ContextFragment objects
- `plan_context`: Current plan context
- `request`: ContextRequest
**Output**:
- `scored`: List of (fragment, score) tuples
**Scoring Factors**:
- Relevance score (from strategy): 40%
- Tier priority (hot > warm > cold): 30%
- Recency (created_at): 20%
- Plan context alignment: 10%
**Configuration**:
```toml
[context.strategies]
scorer_relevance_weight = 0.4
scorer_tier_weight = 0.3
scorer_recency_weight = 0.2
scorer_plan_weight = 0.1
```
**Example**:
```python
scorer = FragmentScorer()
scored = scorer.score(
fragments=[frag1, frag2],
plan_context=plan_context,
request=context_request
)
# Returns: [(frag1, 0.92), (frag2, 0.78)]
```
#### BudgetPacker
**Purpose**: Select fragments to fit within token budget.
**Input**:
- `scored_fragments`: List of (fragment, score) tuples
- `budget`: ContextBudget
**Output**:
- `packed`: List of selected fragments
**Packing Algorithm**:
1. Sort fragments by score (descending)
2. Respect tier ordering (hot → warm → cold)
3. Greedily add fragments until budget exhausted
4. Early termination when budget full
**Configuration**:
```toml
[context.strategies]
packer_tier_priority = ["hot", "warm", "cold"]
packer_greedy = true
```
**Example**:
```python
packer = BudgetPacker()
packed = packer.pack(
scored_fragments=[(frag1, 0.92), (frag2, 0.78)],
budget=budget
)
# Returns: [frag1, frag2] (total tokens <= budget.available_tokens)
```
#### FragmentOrderer
**Purpose**: Determine final fragment order in payload.
**Input**:
- `fragments`: List of ContextFragment objects
- `strategy`: Ordering strategy ("relevance", "recency", "tier-relevance", "custom")
**Output**:
- `ordered`: List of fragments in final order
**Ordering Strategies**:
- **Relevance**: By relevance_score (descending)
- **Recency**: By created_at (descending)
- **Tier-Relevance**: By tier (hot > warm > cold), then relevance
- **Custom**: User-defined ordering
**Configuration**:
```toml
[context.strategies]
orderer_strategy = "tier-relevance"
```
**Example**:
```python
orderer = FragmentOrderer()
ordered = orderer.order(
fragments=[frag1, frag2],
strategy="tier-relevance"
)
# Returns: [hot_frag, warm_frag1, warm_frag2, cold_frag]
```
### Phase 3: Context Finalization
#### PreambleGenerator
**Purpose**: Generate optional summary of assembled context.
**Input**:
- `payload`: ContextPayload (before finalization)
- `strategies_used`: Tuple of strategy names
- `budget_used`: Fraction of budget consumed
**Output**:
- `preamble`: String summary of context
**Preamble Contents**:
- Number of fragments and sources
- Token usage and budget utilization
- Strategies used
- Key topics covered
- Temporal range
**Configuration**:
```toml
[context.strategies]
preamble_enabled = true
preamble_include_stats = true
preamble_max_length = 500
```
**Example**:
```python
generator = PreambleGenerator()
preamble = generator.generate(
payload=payload,
strategies_used=["semantic-embedding"],
budget_used=0.57
)
# Returns: "Context includes 5 fragments from 3 sources..."
```
#### SkeletonCompressor
**Purpose**: Compress context for child plans while preserving critical information.
**Input**:
- `parent_context`: Parent ContextPayload
- `child_focus`: List of focus nodes for child plan
- `skeleton_budget`: Token budget for compressed context
**Output**:
- `compressed`: Compressed ContextPayload for child plan
**Compression Strategy**:
1. Identify critical fragments for child focus
2. Remove redundant details
3. Preserve decision context
4. Maintain provenance
**Configuration**:
```toml
[context.strategies]
compressor_enabled = true
compressor_preserve_decisions = true
compressor_preserve_hot_tier = true
```
**Example**:
```python
compressor = SkeletonCompressor()
compressed = compressor.compress(
parent_context=parent_payload,
child_focus=["project://myapp/src/main.py"],
skeleton_budget=1024
)
# Returns: compressed ContextPayload for child plan
```
## Data Flow
### Complete Pipeline Flow
```
ContextRequest
StrategySelector
↓ (candidates: [(strategy, confidence), ...])
BudgetAllocator
↓ (allocations: {strategy: budget, ...})
StrategyExecutor
↓ (results: [StrategyResult, ...])
Merge Results
↓ (fragments: [ContextFragment, ...])
FragmentDeduplicator
↓ (deduplicated: [ContextFragment, ...])
DetailDepthResolver
↓ (resolved: [ContextFragment, ...])
FragmentScorer
↓ (scored: [(ContextFragment, score), ...])
BudgetPacker
↓ (packed: [ContextFragment, ...])
FragmentOrderer
↓ (ordered: [ContextFragment, ...])
PreambleGenerator
↓ (preamble: str)
SkeletonCompressor (optional)
↓ (compressed: ContextPayload)
ContextPayload
```
### Example Data Structures
**ContextRequest**:
```python
{
"focus_nodes": ["project://myapp/src/main.py"],
"breadth": 2,
"depth": 3,
"keywords": ["async", "io"],
"resource_types": ["source_file", "decision"],
"detail_level": 3,
"temporal_window": "7d",
"strategy_hints": ["semantic-embedding"]
}
```
**StrategyResult**:
```python
{
"strategy_name": "semantic-embedding",
"fragments": [
ContextFragment(...),
ContextFragment(...),
...
],
"total_fragments": 45,
"tokens_used": 2048,
"execution_time_ms": 234,
"errors": [],
"stats": {
"similarity_scores": [0.95, 0.87, ...],
"backend_queries": 3,
"cache_hits": 2
}
}
```
**ContextPayload**:
```python
{
"payload_id": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
"plan_id": "plan-1",
"fragments": [
ContextFragment(...),
ContextFragment(...),
...
],
"total_tokens": 2048,
"budget": {
"max_tokens": 4096,
"reserved_tokens": 512,
"available_tokens": 3584
},
"budget_used": 0.57,
"strategies_used": ["semantic-embedding"],
"context_hash": "abc123...",
"preamble": "Context includes 5 fragments...",
"provenance_map": {
"fragment-id-1": {...},
"fragment-id-2": {...},
...
},
"assembled_at": "2024-04-19T14:30:00Z"
}
```
## Configuration and Tuning
### Global Configuration
```toml
[context]
max_tokens = 4096
reserved_tokens = 512
[context.strategies]
enabled = ["simple-keyword", "semantic-embedding", "breadth-depth-navigator"]
default_strategy = "arce"
[context.strategies.simple-keyword]
enabled = true
timeout_seconds = 10
max_fragments = 50
[context.strategies.semantic-embedding]
enabled = true
timeout_seconds = 20
max_fragments = 100
[context.strategies.breadth-depth-navigator]
enabled = true
timeout_seconds = 30
max_fragments = 150
[context.strategies.arce]
enabled = true
timeout_seconds = 45
max_fragments = 200
text_budget_fraction = 0.4
vector_budget_fraction = 0.4
graph_budget_fraction = 0.2
```
### Per-Component Tuning
#### StrategySelector Tuning
```toml
[context.strategies]
selector_threshold = 0.0 # Minimum confidence to select
max_candidates = 10 # Maximum strategies to execute
```
**Tuning Tips**:
- Increase `selector_threshold` to filter low-confidence strategies
- Decrease `max_candidates` to reduce execution time
#### BudgetAllocator Tuning
```toml
[context.strategies]
allocator_strategy = "proportional" # "proportional", "equal", "priority"
allocator_min_budget = 100
```
**Tuning Tips**:
- Use "proportional" for quality-aware allocation
- Use "equal" for fair distribution
- Use "priority" for greedy allocation
#### StrategyExecutor Tuning
```toml
[context.strategies]
executor_max_workers = 4
executor_timeout_seconds = 30
executor_circuit_breaker_threshold = 3
executor_circuit_breaker_reset_timeout = 60
```
**Tuning Tips**:
- Increase `max_workers` for parallel execution (up to CPU cores)
- Increase `timeout_seconds` for complex strategies
- Adjust `circuit_breaker_threshold` for fault tolerance
#### FragmentScorer Tuning
```toml
[context.strategies]
scorer_relevance_weight = 0.4
scorer_tier_weight = 0.3
scorer_recency_weight = 0.2
scorer_plan_weight = 0.1
```
**Tuning Tips**:
- Increase `relevance_weight` for quality-focused assembly
- Increase `tier_weight` for tier-aware assembly
- Increase `recency_weight` for recent-focused assembly
## Monitoring and Metrics
### Key Metrics
| Metric | Description | Target |
|--------|-------------|--------|
| `assembly_time_ms` | Total pipeline execution time | < 1000ms |
| `fragments_selected` | Number of fragments in payload | 5-50 |
| `tokens_used` | Total tokens in payload | < available_tokens |
| `budget_used` | Fraction of budget consumed | 0.5-0.9 |
| `avg_relevance` | Average relevance score | > 0.7 |
| `strategy_success_rate` | Fraction of successful strategies | > 0.8 |
| `dedup_ratio` | Fraction of duplicates removed | 0.0-0.3 |
### Logging
Enable debug logging:
```python
import logging
logging.getLogger("cleveragents.acms").setLevel(logging.DEBUG)
```
### Metrics Collection
```python
from cleveragents.application.services.acms_service import ACMSPipeline
pipeline = ACMSPipeline()
payload = pipeline.assemble(plan_id, fragments, budget)
# Collect metrics
metrics = {
"payload_id": payload.payload_id,
"plan_id": payload.plan_id,
"total_tokens": payload.total_tokens,
"budget_used": payload.budget_used,
"fragments_count": len(payload.fragments),
"strategies_used": payload.strategies_used,
"avg_relevance": sum(f.relevance_score for f in payload.fragments) / len(payload.fragments),
"tier_distribution": {
"hot": sum(1 for f in payload.fragments if f.tier == "hot"),
"warm": sum(1 for f in payload.fragments if f.tier == "warm"),
"cold": sum(1 for f in payload.fragments if f.tier == "cold"),
}
}
```
## Performance Optimization
### Strategy Selection Optimization
```python
# Good: Filter low-confidence strategies
candidates = [
(s, conf) for s, conf in candidates if conf >= 0.7
]
# Avoid: Execute all strategies
candidates = all_strategies
```
### Budget Allocation Optimization
```python
# Good: Proportional allocation
allocations = allocator.allocate(
candidates=high_confidence,
total_budget=3584,
strategy="proportional"
)
# Avoid: Equal allocation
allocations = {s: 3584 // len(strategies) for s in strategies}
```
### Execution Optimization
```python
# Good: Parallel execution with reasonable timeout
executor = StrategyExecutor(max_workers=4, timeout_seconds=30)
# Avoid: Sequential execution or excessive timeout
executor = StrategyExecutor(max_workers=1, timeout_seconds=300)
```
### Fragment Deduplication Optimization
```python
# Good: Deduplicate early
deduplicated = deduplicator.deduplicate(fragments)
scored = scorer.score(deduplicated, plan_context)
# Avoid: Deduplicate after scoring
scored = scorer.score(fragments, plan_context)
deduplicated = deduplicator.deduplicate(scored)
```
## Troubleshooting
### Slow Pipeline Execution
**Problem**: Pipeline takes > 1 second.
**Solution**:
1. Check `executor_timeout_seconds` - reduce if too high
2. Check `executor_max_workers` - increase if too low
3. Check strategy complexity - use simpler strategies
4. Check fragment count - reduce `max_fragments`
### Low Quality Context
**Problem**: Assembled context is not relevant.
**Solution**:
1. Increase `selector_threshold` to filter low-confidence strategies
2. Use higher-quality strategy (e.g., ARCE)
3. Increase `scorer_relevance_weight` for quality focus
4. Adjust strategy-specific parameters
### Out of Memory
**Problem**: Pipeline consumes too much memory.
**Solution**:
1. Reduce `max_fragments` limit
2. Reduce `executor_max_workers` for parallel execution
3. Enable fragment streaming
4. Use simpler strategies
### Budget Exceeded
**Problem**: Assembled context exceeds budget.
**Solution**:
1. Check `BudgetPacker` implementation
2. Reduce `max_fragments` limit
3. Increase `reserved_tokens` to reduce available budget
4. Enable detail depth reduction
## See Also
- [Context Management Deep Dive](../guides/context_management_deep_dive.md)
- [Context Strategies Reference](./context_strategies_reference.md)
- [ACMS v1 Context Assembly Pipeline](./acms.md)
- [Context Strategy Registry](./context_strategies.md)
@@ -0,0 +1,750 @@
# Context Strategies Reference
Complete reference for all context strategies in the ACMS, including configuration options, performance characteristics, and use case recommendations.
## Strategy Overview
| Strategy | Quality | Speed | Coverage | Backends | Best For |
|----------|---------|-------|----------|----------|----------|
| Simple Keyword | 0.3 | ⚡⚡⚡ | Narrow | Text | Quick searches, fallback |
| Semantic Embedding | 0.6 | ⚡⚡ | Broad | Vector | Semantic similarity |
| Breadth-Depth Navigator | 0.85 | ⚡ | Very Broad | Graph | Comprehensive context |
| ARCE | 0.95 | 🐢 | Comprehensive | All | Production use |
| Temporal Archaeology | 0.5 | 🐢 | Historical | Graph + Temporal | Historical context |
| Plan-Decision Context | 0.7 | ⚡ | Hierarchical | Temporal + Graph | Plan coordination |
## Simple Keyword Strategy
### Overview
The Simple Keyword Strategy performs text-based keyword search using the TextBackend. It's the fastest strategy and serves as a fallback when other backends are unavailable.
### Quality Score
**0.3** (baseline)
### Backend Requirements
- **Required**: TextBackend
- **Optional**: None
### How It Works
1. Extract keywords from the ContextRequest
2. Query TextBackend using keyword search
3. Rank results by match frequency and relevance
4. Pack greedily into token budget
### Configuration
```toml
[context.strategies.simple-keyword]
enabled = true
timeout_seconds = 10
max_fragments = 50
keyword_boost_factor = 1.5
```
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `enabled` | bool | true | Enable this strategy |
| `timeout_seconds` | int | 10 | Per-strategy timeout |
| `max_fragments` | int | 50 | Maximum fragments returned |
| `keyword_boost_factor` | float | 1.5 | Boost for exact keyword matches |
### Performance Characteristics
- **Execution Time**: 50-200ms (typical)
- **Memory Usage**: Low (streaming results)
- **Scalability**: Excellent (linear with keyword count)
- **Parallelization**: Not applicable (single-threaded)
### Use Cases
- Quick searches with clear keywords
- Projects with good text indexing
- Fallback when other backends unavailable
- Real-time context assembly with tight latency budgets
### Example Usage
```python
from cleveragents.application.services.acms_service import ACMSPipeline
pipeline = ACMSPipeline()
payload = pipeline.assemble(
plan_id="plan-1",
fragments=fragments,
budget=ContextBudget(max_tokens=4096, reserved_tokens=512),
strategy="simple-keyword"
)
```
### Limitations
- Limited to exact keyword matches
- No semantic understanding
- Cannot traverse relationships
- Requires good text indexing
## Semantic Embedding Strategy
### Overview
The Semantic Embedding Strategy uses vector similarity search to find semantically related context. It uses character-frequency embeddings as a v1 approximation.
### Quality Score
**0.6** (good)
### Backend Requirements
- **Required**: VectorBackend
- **Optional**: None
### How It Works
1. Embed the ContextRequest using character-frequency model
2. Query VectorBackend for similar embeddings
3. Rank by cosine similarity
4. Pack budget-aware results
### Configuration
```toml
[context.strategies.semantic-embedding]
enabled = true
timeout_seconds = 20
max_fragments = 100
similarity_threshold = 0.5
embedding_model = "character-frequency-v1"
```
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `enabled` | bool | true | Enable this strategy |
| `timeout_seconds` | int | 20 | Per-strategy timeout |
| `max_fragments` | int | 100 | Maximum fragments returned |
| `similarity_threshold` | float | 0.5 | Minimum similarity score (0.0-1.0) |
| `embedding_model` | str | "character-frequency-v1" | Embedding model to use |
### Performance Characteristics
- **Execution Time**: 100-500ms (typical)
- **Memory Usage**: Medium (embedding cache)
- **Scalability**: Good (logarithmic with vector index size)
- **Parallelization**: Supported (multiple similarity searches)
### Use Cases
- Semantic similarity searches
- Conceptual relationships
- Cross-domain context discovery
- Finding related code patterns
### Example Usage
```python
from cleveragents.domain.models.core.context_fragment import ContextRequest
request = ContextRequest(
focus_nodes=["project://myapp/src/main.py"],
keywords=["async", "io"]
)
payload = pipeline.assemble(
plan_id="plan-1",
fragments=fragments,
budget=ContextBudget(max_tokens=4096, reserved_tokens=512),
strategy="semantic-embedding"
)
```
### Limitations
- v1 uses character-frequency embeddings (not true semantic)
- Requires VectorBackend
- Cannot traverse relationships
- Sensitive to embedding quality
### Future Improvements
- Integration with real embedding models (e.g., OpenAI, Anthropic)
- Fine-tuned embeddings for code
- Hybrid semantic-keyword search
## Breadth-Depth Navigator Strategy
### Overview
The Breadth-Depth Navigator Strategy traverses the knowledge graph to find related context. It explores outward (breadth) and downward (depth) from focus nodes.
### Quality Score
**0.85** (excellent)
### Backend Requirements
- **Required**: GraphBackend
- **Optional**: None
### How It Works
1. Start from focus nodes in ContextRequest
2. Traverse graph outward by breadth hops
3. Traverse downward by depth hops
4. Collect all reachable nodes
5. Rank by distance and relevance
6. Pack into budget
### Configuration
```toml
[context.strategies.breadth-depth-navigator]
enabled = true
timeout_seconds = 30
max_fragments = 150
default_breadth = 2
default_depth = 3
distance_decay = 0.8
```
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `enabled` | bool | true | Enable this strategy |
| `timeout_seconds` | int | 30 | Per-strategy timeout |
| `max_fragments` | int | 150 | Maximum fragments returned |
| `default_breadth` | int | 2 | Default breadth hops |
| `default_depth` | int | 3 | Default depth hops |
| `distance_decay` | float | 0.8 | Decay factor per hop |
### Performance Characteristics
- **Execution Time**: 200-1000ms (typical)
- **Memory Usage**: Medium (graph traversal state)
- **Scalability**: Good (exponential with breadth/depth)
- **Parallelization**: Supported (parallel hop traversal)
### Use Cases
- Exploring related code and decisions
- Understanding dependencies
- Comprehensive context assembly
- Finding transitive relationships
### Example Usage
```python
request = ContextRequest(
focus_nodes=["project://myapp/src/main.py"],
breadth=2,
depth=3
)
payload = pipeline.assemble(
plan_id="plan-1",
fragments=fragments,
budget=ContextBudget(max_tokens=4096, reserved_tokens=512),
strategy="breadth-depth-navigator"
)
```
### Limitations
- Requires GraphBackend
- Can be slow with large graphs
- Exponential complexity with breadth/depth
- May include irrelevant distant nodes
### Optimization Tips
- Reduce breadth/depth for faster execution
- Use distance decay to prioritize nearby nodes
- Filter by resource type to reduce graph size
- Increase timeout for large graphs
## ARCE Strategy (Advanced Retrieval with Context Enrichment)
### Overview
ARCE is the most comprehensive strategy, combining text search, vector similarity, and graph traversal. It's the recommended strategy for production use cases.
### Quality Score
**0.95** (highest)
### Backend Requirements
- **Required**: TextBackend, VectorBackend, GraphBackend
- **Optional**: None
### How It Works
1. **Phase 1 (40% budget)**: Text search using keywords
2. **Phase 2 (40% budget)**: Vector similarity search
3. **Phase 3 (20% budget)**: Graph traversal from results
4. Merge and deduplicate results
5. Rank by combined score
6. Pack into budget
### Configuration
```toml
[context.strategies.arce]
enabled = true
timeout_seconds = 45
max_fragments = 200
text_budget_fraction = 0.4
vector_budget_fraction = 0.4
graph_budget_fraction = 0.2
dedup_strategy = "highest_relevance"
```
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `enabled` | bool | true | Enable this strategy |
| `timeout_seconds` | int | 45 | Per-strategy timeout |
| `max_fragments` | int | 200 | Maximum fragments returned |
| `text_budget_fraction` | float | 0.4 | Budget for text search |
| `vector_budget_fraction` | float | 0.4 | Budget for vector search |
| `graph_budget_fraction` | float | 0.2 | Budget for graph traversal |
| `dedup_strategy` | str | "highest_relevance" | Deduplication strategy |
### Performance Characteristics
- **Execution Time**: 500-2000ms (typical)
- **Memory Usage**: High (multiple result sets)
- **Scalability**: Good (parallel phases)
- **Parallelization**: Excellent (3 phases in parallel)
### Use Cases
- Comprehensive context assembly
- Multi-modal queries
- Production use cases
- High-quality context requirements
### Example Usage
```python
request = ContextRequest(
focus_nodes=["project://myapp/src/main.py"],
keywords=["async", "io"],
breadth=2
)
payload = pipeline.assemble(
plan_id="plan-1",
fragments=fragments,
budget=ContextBudget(max_tokens=4096, reserved_tokens=512),
strategy="arce"
)
```
### Limitations
- Requires all three backends
- Slower than single-backend strategies
- Higher memory usage
- May return too many fragments
### Optimization Tips
- Adjust budget fractions based on query type
- Increase timeout for complex queries
- Use deduplication to reduce redundancy
- Filter by resource type to reduce results
## Temporal Archaeology Strategy
### Overview
The Temporal Archaeology Strategy retrieves historical context from the cold tier and traverses relationships from historical nodes.
### Quality Score
**0.5** (moderate)
### Backend Requirements
- **Required**: GraphBackend, TemporalBackend (cold tier)
- **Optional**: None
### How It Works
1. Query TemporalBackend for historical nodes
2. Filter by temporal window
3. Traverse graph from historical nodes
4. Collect related current nodes
5. Rank by recency and relevance
6. Pack into budget
### Configuration
```toml
[context.strategies.temporal-archaeology]
enabled = false
timeout_seconds = 60
max_fragments = 100
default_temporal_window = "7d"
include_current_context = true
```
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `enabled` | bool | false | Enable this strategy |
| `timeout_seconds` | int | 60 | Per-strategy timeout |
| `max_fragments` | int | 100 | Maximum fragments returned |
| `default_temporal_window` | str | "7d" | Default time window |
| `include_current_context` | bool | true | Include current context |
### Performance Characteristics
- **Execution Time**: 1000-5000ms (typical)
- **Memory Usage**: High (temporal queries)
- **Scalability**: Fair (depends on cold tier size)
- **Parallelization**: Limited (sequential phases)
### Use Cases
- Understanding historical context
- Decision archaeology
- Long-term project evolution
- Regression analysis
### Example Usage
```python
request = ContextRequest(
focus_nodes=["project://myapp/src/main.py"],
temporal_window="30d"
)
payload = pipeline.assemble(
plan_id="plan-1",
fragments=fragments,
budget=ContextBudget(max_tokens=4096, reserved_tokens=512),
strategy="temporal-archaeology"
)
```
### Limitations
- Requires cold tier (not always available)
- Slow execution
- May include outdated information
- Limited to historical data
### Temporal Window Format
- `"1d"` - Last 1 day
- `"7d"` - Last 7 days
- `"30d"` - Last 30 days
- `"90d"` - Last 90 days
- `"1y"` - Last 1 year
- `"all"` - All history
## Plan-Decision Context Strategy
### Overview
The Plan-Decision Context Strategy walks the plan hierarchy to retrieve decision records and related context.
### Quality Score
**0.7** (good)
### Backend Requirements
- **Required**: TemporalBackend (warm/cold), GraphBackend
- **Optional**: None
### How It Works
1. Walk parent and ancestor plan hierarchy
2. Retrieve decision records from warm/cold tiers
3. Traverse graph from decisions
4. Collect related context
5. Rank by plan proximity and relevance
6. Pack into budget
### Configuration
```toml
[context.strategies.plan-decision-context]
enabled = true
timeout_seconds = 30
max_fragments = 100
include_ancestor_decisions = true
max_ancestor_depth = 5
```
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `enabled` | bool | true | Enable this strategy |
| `timeout_seconds` | int | 30 | Per-strategy timeout |
| `max_fragments` | int | 100 | Maximum fragments returned |
| `include_ancestor_decisions` | bool | true | Include ancestor decisions |
| `max_ancestor_depth` | int | 5 | Maximum ancestor levels |
### Performance Characteristics
- **Execution Time**: 200-800ms (typical)
- **Memory Usage**: Medium (plan hierarchy)
- **Scalability**: Good (linear with plan depth)
- **Parallelization**: Supported (parallel ancestor traversal)
### Use Cases
- Understanding plan context
- Decision inheritance
- Multi-level plan coordination
- Plan dependency analysis
### Example Usage
```python
request = ContextRequest(
focus_nodes=["project://myapp/src/main.py"]
)
payload = pipeline.assemble(
plan_id="plan-1",
fragments=fragments,
budget=ContextBudget(max_tokens=4096, reserved_tokens=512),
strategy="plan-decision-context"
)
```
### Limitations
- Requires plan hierarchy
- Limited to decision context
- May miss non-decision context
- Depends on plan structure
## Strategy Selection Guide
### When to Use Each Strategy
#### Simple Keyword
- ✅ Quick searches with clear keywords
- ✅ Fallback when other backends unavailable
- ✅ Real-time context with tight latency budgets
- ❌ Semantic understanding needed
- ❌ Relationship traversal needed
#### Semantic Embedding
- ✅ Semantic similarity searches
- ✅ Conceptual relationships
- ✅ Cross-domain discovery
- ❌ Exact keyword matching needed
- ❌ Relationship traversal needed
#### Breadth-Depth Navigator
- ✅ Exploring related code
- ✅ Understanding dependencies
- ✅ Comprehensive context
- ❌ Quick searches needed
- ❌ Historical context needed
#### ARCE
- ✅ Comprehensive context assembly
- ✅ Multi-modal queries
- ✅ Production use cases
- ❌ Quick searches needed
- ❌ Limited backends available
#### Temporal Archaeology
- ✅ Historical context
- ✅ Decision archaeology
- ✅ Long-term evolution
- ❌ Current context needed
- ❌ Quick searches needed
#### Plan-Decision Context
- ✅ Plan coordination
- ✅ Decision inheritance
- ✅ Multi-level plans
- ❌ Non-decision context needed
- ❌ No plan hierarchy
### Fallback Chain
When a strategy fails, the system falls back to simpler strategies:
```
ARCE (0.95)
↓ (if unavailable)
Breadth-Depth Navigator (0.85)
↓ (if unavailable)
Semantic Embedding (0.6)
↓ (if unavailable)
Simple Keyword (0.3)
```
## Performance Comparison
### Execution Time
```
Simple Keyword: ████ 50-200ms
Semantic Embedding: ██████████ 100-500ms
Breadth-Depth: ███████████████ 200-1000ms
Plan-Decision: ██████████ 200-800ms
ARCE: ████████████████████ 500-2000ms
Temporal Archaeology: ████████████████████████ 1000-5000ms
```
### Memory Usage
```
Simple Keyword: ██ Low
Semantic Embedding: ████ Medium
Breadth-Depth: ████ Medium
Plan-Decision: ████ Medium
ARCE: ██████ High
Temporal Archaeology: ██████ High
```
### Coverage
```
Simple Keyword: ██ Narrow
Temporal Archaeology: ███ Moderate
Semantic Embedding: ████ Broad
Plan-Decision: ████ Hierarchical
Breadth-Depth: █████ Very Broad
ARCE: ██████ Comprehensive
```
## Configuration Best Practices
### Global Configuration
```toml
[context.strategies]
enabled = ["simple-keyword", "semantic-embedding", "breadth-depth-navigator"]
default_strategy = "arce"
fallback_chain = ["arce", "breadth-depth-navigator", "semantic-embedding", "simple-keyword"]
[context.strategies.simple-keyword]
enabled = true
timeout_seconds = 10
max_fragments = 50
[context.strategies.semantic-embedding]
enabled = true
timeout_seconds = 20
max_fragments = 100
[context.strategies.breadth-depth-navigator]
enabled = true
timeout_seconds = 30
max_fragments = 150
[context.strategies.arce]
enabled = true
timeout_seconds = 45
max_fragments = 200
[context.strategies.plan-decision-context]
enabled = true
timeout_seconds = 30
max_fragments = 100
```
### Per-Project Overrides
```bash
# Set strategies for a project
agents project context set \
--strategy simple-keyword \
--strategy semantic-embedding \
--strategy breadth-depth-navigator
# View current strategies
agents project context list
```
## Monitoring and Metrics
### Key Metrics
- **Execution Time**: Strategy execution wall-clock time
- **Fragment Count**: Number of fragments returned
- **Token Usage**: Total tokens in assembled context
- **Budget Utilization**: Percentage of budget used
- **Relevance Score**: Average relevance of fragments
- **Tier Distribution**: Hot/warm/cold fragment counts
### Logging
Enable debug logging to monitor strategy execution:
```python
import logging
logging.getLogger("cleveragents.acms").setLevel(logging.DEBUG)
```
### Example Metrics Output
```
Strategy: semantic-embedding
Execution Time: 234ms
Fragments: 12
Tokens: 2048
Budget Used: 57%
Avg Relevance: 0.82
Tier Distribution: hot=2, warm=8, cold=2
```
## Troubleshooting
### Strategy Not Selected
**Problem**: Expected strategy not selected.
**Solution**:
1. Check strategy is enabled in configuration
2. Verify `can_handle()` returns confidence > 0
3. Check required backends are available
4. Review strategy selection logs
### Slow Execution
**Problem**: Strategy takes too long.
**Solution**:
1. Reduce `max_fragments` limit
2. Decrease `breadth` and `depth` parameters
3. Increase `timeout_seconds` if appropriate
4. Switch to faster strategy
### Low Quality Results
**Problem**: Assembled context is not relevant.
**Solution**:
1. Try higher-quality strategy (e.g., ARCE)
2. Adjust `similarity_threshold` for semantic strategy
3. Increase `breadth` and `depth` for navigator
4. Provide better keywords in request
### Out of Memory
**Problem**: Strategy consumes too much memory.
**Solution**:
1. Reduce `max_fragments` limit
2. Switch to lower-memory strategy
3. Reduce `breadth` and `depth` parameters
4. Enable fragment streaming
## See Also
- [Context Management Deep Dive](../guides/context_management_deep_dive.md)
- [ACMS Pipeline Reference](./acms_pipeline_reference.md)
- [ACMS v1 Context Assembly Pipeline](./acms.md)
- [Context Strategy Registry](./context_strategies.md)