Skip to main content
DeerFlow implements sophisticated context engineering to handle conversations of arbitrary length while staying within model token limits. This includes automatic summarization, intelligent context retention, memory injection, and isolated sub-agent contexts.

Overview

Context engineering addresses three core challenges:
  1. Token Limit Management - Prevent exceeding model’s maximum input tokens
  2. Relevant Context Retention - Keep recent, important information while discarding noise
  3. Context Isolation - Separate main agent and sub-agent conversation contexts

Automatic Summarization

Configuration

Defined in config.yaml under summarization key:

Trigger Types

Summarization activates when any trigger threshold is met:

1. Fraction Trigger

Behavior:
  • Calculates current token count via model’s tokenizer
  • Compares against model’s max_input_tokens config
  • Triggers at 0.8 * max_input_tokens
Use Case: Prevent approaching model’s hard limit (leaves 20% buffer for system prompt, tools, etc.)

2. Tokens Trigger

Behavior:
  • Counts tokens in message history
  • Triggers when count exceeds 4000
Use Case: Fixed budget regardless of model capabilities

3. Messages Trigger

Behavior:
  • Counts messages in conversation
  • Triggers at 50 messages
Use Case: Simple threshold for long conversations (UI performance, checkpoint size)

Keep Policies

After summarization triggers, the keep policy determines how much recent context to preserve.

Messages Keep

Behavior:
  • Keeps most recent 20 messages verbatim
  • Summarizes everything before that
  • Final history: [SystemMessage(summary), ...last 20 messages]

Tokens Keep

Behavior:
  • Calculates token count backwards from last message
  • Keeps messages until total reaches ~3000 tokens
  • Summarizes remainder

Fraction Keep

Behavior:
  • Calculates 0.3 * model.max_input_tokens
  • Keeps that many tokens from end of history

Model Selection

Options:
  • null (default): Uses lightweight model via create_chat_model(thinking_enabled=False)
  • Model name string: Uses specified model from config.yaml models list
Recommendation: Use cheap, fast model (summarization quality less critical than speed/cost)

Implementation

Summarization handled by LangChain’s SummarizationMiddleware, configured in backend/src/agents/lead_agent/agent.py:41-80:

Summarization Process

  1. Trigger Check (before_model):
    • Count current tokens/messages
    • Compare against all trigger thresholds
    • If any threshold met, proceed to step 2
  2. Message Preparation:
    • Split history into to_summarize and to_keep
    • Trim to_summarize to trim_tokens_to_summarize tokens (default 4000)
    • This prevents overwhelming summarization model
  3. Summary Generation:
    • Invoke model with to_summarize messages
    • Default prompt: “Summarize the following conversation concisely”
    • Custom prompt via summary_prompt config
  4. History Reconstruction:
    • Create SystemMessage with summary
    • Append to_keep messages (recent context)
    • Replace state’s message history
Example:

Memory Injection

DeerFlow’s memory system complements summarization by injecting persistent facts into every turn.

Memory Structure

Stored in backend/.deer-flow/memory.json:

Injection Process

Location: System prompt template in backend/src/agents/lead_agent/prompt.py
Memory Formatting (backend/src/agents/memory/updater.py):

Memory Configuration

Token Budget:
  • max_injection_tokens: 2000 ensures memory doesn’t dominate prompt
  • Priority: User context > Recent history > Top 15 facts (by confidence)
  • If exceeds budget, truncates oldest/lowest-confidence facts first

Memory Update Flow

  1. Queue (MemoryMiddleware.after_agent):
  2. Debounce (MemoryQueue):
    • Waits debounce_seconds (default 30s)
    • Batches multiple turns if conversation continues
    • Deduplicates per-thread updates
  3. Extract (MemoryUpdater):
    • Invokes LLM with conversation history
    • Extracts new facts, updates context summaries
    • Assigns confidence scores (0-1)
  4. Persist (Atomic file I/O):
  5. Inject (Next turn):
    • Load memory from storage_path
    • Format for injection (trim to max_injection_tokens)
    • Insert into system prompt <memory> tags

Context Isolation for Sub-Agents

Sub-agents run in completely isolated contexts to prevent pollution of main conversation.

Motivation

Problem: Without isolation, sub-agent’s exploration pollutes main context:
Solution: Sub-agent runs in isolated thread:

Implementation

Task Tool (backend/src/tools/builtins/task_tool.py:28-78):
Subagent Executor (backend/src/subagents/executor.py:200-250):

Context Sharing

While conversation context is isolated, file system access is shared: Shared:
  • File system (via thread_id from parent)
  • Sandbox environment
  • Physical directories: backend/.deer-flow/threads/{parent_thread_id}/
Isolated:
  • Message history
  • State (artifacts, todos, viewed_images)
  • LLM context window
  • Checkpoints (separate thread IDs)
Example:

Artifact Transfer

Sub-agent artifacts can be inherited by main agent:

Token Accounting

Counting Tokens

DeerFlow uses model-specific tokenizers:

Token Budget Breakdown

Typical token distribution for 8K context model:
Configuration Strategy:
  • Set summarization.trigger.value: 0.6 (60% threshold)
  • Set summarization.keep.value: 0.4 (keep 40% = 3,200 tokens)
  • Set memory.max_injection_tokens: 500 (6% of total)

Performance Impact

Summarization:
  • Additional LLM call: ~1-2s latency
  • Cost: ~$0.01 per summarization (with GPT-4o-mini)
  • Frequency: Every 50 messages or 80% token limit
Memory Injection:
  • Negligible latency (cached, loaded from disk)
  • Adds ~500 tokens to every request
  • Cost: ~0.005perrequest(at0.005 per request (at 2/M tokens)
Sub-Agent Isolation:
  • No additional token cost (separate contexts)
  • Storage cost: Separate checkpoint per sub-agent thread
  • Cleanup: Periodic pruning of old sub-agent threads

Best Practices

1. Choose Appropriate Triggers

2. Balance Keep Policy

3. Memory Token Budget

4. Sub-Agent Usage

Use sub-agents when:
  • Task requires extensive exploration (e.g., “analyze this codebase”)
  • Output is verbose (e.g., “run linter on all files”)
  • Want to isolate errors (e.g., “try multiple approaches until one works”)
Avoid sub-agents when:
  • Task is simple (e.g., “read this file”)
  • Need tight coordination (e.g., “implement feature and write tests together”)
  • Context sharing critical (e.g., “continue from where we left off”)

Monitoring & Debugging

Enable Debug Logging

Summarization Events

Memory Events

Sub-Agent Events

See Also