How the C = A(c₁, c₂, ..., cₙ) Context Formalization Works in Practice

The C = A(c₁, c₂, ..., cₙ) formalization treats context assembly as a mathematical function where an assembly function A combines six canonical components—instructions, knowledge, tools, memory, state, and query—into the final context C that is fed to the LLM.

The davidkimai/context-engineering repository implements this rigorous mathematical approach to prompt engineering, transforming ad-hoc prompt construction into a structured, programmable pipeline. By treating context assembly as an objective function, the framework enables systematic optimization of relevance, completeness, and token efficiency.

Understanding the Mathematical Foundation

Breaking Down the Equation

The core formalization appears in 00_COURSE/00_mathematical_foundations/01_context_formalization.md and defines the relationship:

  • C: The final assembled context string that interacts directly with the LLM's input window
  • A: The assembly function—a deterministic or adaptive algorithm that combines components according to specific strategies
  • c₁ … cₙ: Individual context components that carry distinct semantic roles in the prompt

The Six Canonical Components

The framework defines six canonical variables in the foundational documentation (lines 42-50 of 01_context_formalization.md):

  • c₁ – Instructions: System prompts, role definitions, and behavioral constraints that establish the LLM's persona and operational boundaries
  • c₂ – Knowledge: External facts, documents, and retrieved passages providing factual grounding for the response
  • c₃ – Tools: Function-calling specifications, API descriptions, and tool schemas that enable external capabilities
  • c₄ – Memory: Recent conversation history and long-term user profiles that maintain dialogue continuity
  • c₅ – State: Current situational variables such as user location, time-of-day, or session metadata
  • c₆ – Query: The immediate user request that the LLM must process and answer

Implementing the Assembly Function A

The assembly function A is implemented in the ContextAssembler class as a family of strategies rather than a single algorithm. Each strategy optimizes for different latency, relevance, or complexity requirements while respecting the max_tokens constraint.

Linear Assembly Strategy

The linear strategy orders components by fixed priority (instructions → knowledge → tools → memory → state → query) and concatenates them until the token budget is reached. This method appears in lines 93-125 of 01_context_formalization.md:

def assemble_linear(self, components: List[ContextComponent]) -> str:
    # Order by priority, respect token budget, truncate if needed

    ordered = sorted(components, key=lambda c: c.priority)
    result = []
    current_tokens = 0
    
    for comp in ordered:
        if current_tokens + comp.token_count <= self.max_tokens:
            result.append(comp.content)
            current_tokens += comp.token_count
        else:
            break
            
    return "\n\n".join(result)

Weighted and Hierarchical Strategies

For knowledge-heavy scenarios, the weighted strategy scores each component by relevance × weight and selects the highest-scoring subset that fits within the token budget. Weights are configurable per use-case, allowing dynamic prioritization of critical components like c₂ (knowledge) over c₅ (state).

The hierarchical strategy groups components into semantic layers (foundation, integration, capabilities, request) and builds a nested structure that mirrors the logical flow of multi-step reasoning tasks.

Adaptive Protocol Selection

The adaptive strategy implemented in UnifiedContextEngineeringSystem (lines 860-940) selects the optimal assembly method based on historical performance data. The AdaptiveOptimizer evaluates recent quality metrics—relevance, completeness, consistency, and efficiency—stored by PerformanceMonitor, then dynamically chooses between linear, weighted, or hybrid approaches.

End-to-End Workflow in Practice

The complete implementation of C = A(c₁, c₂, ..., cₙ) follows a five-stage pipeline orchestrated by the UnifiedContextEngineeringSystem:

  1. Template selection – The TemplateLibrary chooses prompt templates for each component based on query type and domain requirements.

  2. Component analysis – The ComponentAnalyzer wraps raw inputs into ContextComponent data classes, scoring each for relevance, clarity, completeness, and token count (lines 53-85).

  3. Strategy optimization – The AdaptiveOptimizer determines whether to use linear, weighted, or hierarchical assembly based on performance history.

  4. Context assembly – The ContextAssembler executes the chosen strategy, producing the final string C while respecting token budgets.

  5. Quality assessment – The ContextQualityAssessor evaluates the assembled context against relevance, completeness, consistency, and efficiency metrics, feeding any deficits back to the optimizer for iterative refinement.

The system returns a structured JSON object containing the formalized context, quality scores, assembly metadata, and learning insights for subsequent optimizations.

Code Examples

Simple Linear Assembly

The following example demonstrates basic linear assembly using the core classes defined in 00_COURSE/00_mathematical_foundations/01_context_formalization.md:

from context_engineering import ComponentAnalyzer, ContextAssembler

# Raw components (normally gathered from templates, retrieval, etc.)

raw = {
    "instructions": "# You are a helpful assistant\nYou must answer concisely.",

    "knowledge": "The Eiffel Tower is 324 m tall.",
    "tools": "function call: get_weather(location)",
    "memory": "User asked about Paris last turn.",
    "state": "Current time: 2026-02-28 14:00 UTC",
    "query": "What is the height of the Eiffel Tower?"
}

# Analyze each component (adds relevance scores, token counts)

analyzer = ComponentAnalyzer()
components = [
    analyzer.analyze_instructions(raw["instructions"], raw["query"]),
    analyzer.analyze_knowledge([raw["knowledge"]], raw["query"]),
    analyzer.analyze_knowledge([raw["tools"]], raw["query"]),
    analyzer.analyze_knowledge([raw["memory"]], raw["query"]),
    analyzer.analyze_knowledge([raw["state"]], raw["query"]),
    analyzer.analyze_knowledge([raw["query"]], raw["query"])
]

# Assemble with linear strategy (A = linear)

assembler = ContextAssembler(max_tokens=8000)
final_context = assembler.assemble_linear(components)

print(final_context)  # This is the concrete C

Weighted Assembly with Custom Weights

For scenarios requiring component prioritization, use the weighted strategy with configurable weights:

weights = {
    "instructions": 1.5,
    "knowledge": 2.0,
    "tools": 1.0,
    "memory": 0.8,
    "state": 0.5,
    "query": 1.0
}

assembler = ContextAssembler(max_tokens=8000)
final_context = assembler.assemble_weighted(components, weights)

print(final_context)

The weights reflect relative importance for specific tasks—for example, knowledge-intensive research assigns higher values to c₂ while state-heavy applications prioritize c₅.

Adaptive Protocol Usage

The high-level API demonstrates the complete adaptive pipeline implemented in UnifiedContextEngineeringSystem (lines 860-940):

from unified_system import UnifiedContextEngineeringSystem

system = UnifiedContextEngineeringSystem()

user_query = "Give me a quick summary of the latest AI safety research."
resources = {
    "knowledge_sources": ["https://arxiv.org/abs/2305.12345", "OpenAI safety blog post ..."],
    "available_tools": ["search_api", "summarize_tool"],
    "conversation_history": [],
    "current_context": {}
}

result = system.formalize_context(user_query, resources)

print(result["formalized_context"])          # C

print(result["quality_assessment"]["overall"])  # quality score

Summary

  • The C = A(c₁, c₂, ..., cₙ) formalization provides a mathematical framework for context assembly, treating the process as a function where assembly function A combines six canonical components into final context C.
  • The six components—instructions (c₁), knowledge (c₂), tools (c₃), memory (c₄), state (c₅), and query (c₆)—are defined in 00_COURSE/00_mathematical_foundations/01_context_formalization.md.
  • The assembly function A supports multiple strategies—linear, weighted, hierarchical, and adaptive—implemented in the ContextAssembler class to optimize for token budgets, relevance, and task complexity.
  • The end-to-end pipeline involves ComponentAnalyzer, AdaptiveOptimizer, and ContextQualityAssessor classes, orchestrated by UnifiedContextEngineeringSystem (lines 860-940), enabling dynamic, learning-driven context construction.

Frequently Asked Questions

What does C represent in the C = A(c₁, c₂, ..., cₙ) formalization?

C represents the final assembled context—the concrete string or structured data that is actually fed to the LLM's input window at inference time. According to the source code in 00_COURSE/00_mathematical_foundations/01_context_formalization.md, this is the only variable in the equation that directly interacts with the language model, representing the complete synthesis of all individual components after processing by the assembly function A.

How does the assembly function A handle token budget constraints?

The assembly function A implements token-budget-aware strategies within the ContextAssembler class to ensure C never exceeds the model's context window. The linear strategy concatenates components by fixed priority until max_tokens is reached, explicitly checking current_tokens + comp.token_count <= self.max_tokens before inclusion. The weighted strategy selects the highest-scoring subset of components that fits within the budget, while the adaptive strategy dynamically adjusts selection based on historical token efficiency metrics.

Can I add custom components beyond the six canonical ones?

Yes, the formalization supports extending the component schema beyond the six canonical variables (c₁ through c₆). The repository provides a JSON schema in context-schemas/context_v6.0.json that formalizes component structures, while 40_reference/schema_cookbook.md demonstrates how to add custom components such as c₇ for privacy constraints or domain-specific metadata. The ComponentAnalyzer and ContextAssembler classes operate on generic ContextComponent objects, making the system agnostic to the specific number or semantic type of components processed by the assembly function A.

Where is the UnifiedContextEngineeringSystem implemented?

The UnifiedContextEngineeringSystem class is implemented in 00_COURSE/00_mathematical_foundations/01_context_formalization.md at lines 860-940. This high-level orchestration class integrates the complete pipeline: it coordinates the TemplateLibrary for component selection, the ComponentAnalyzer for scoring, the AdaptiveOptimizer for strategy selection, and the ContextQualityAssessor for iterative refinement. The class exposes the formalize_context() method, which returns a structured JSON object containing the assembled context C, quality metrics, and learning insights for subsequent optimizations.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →