DeerFlow
DeerFlow cost control: distinguish useful work from repeated tool traffic
Design a workload experiment around token use, tool bursts, stop reasons and accepted artifacts instead of claiming unmeasured agent speedups.
What you will learn
- Two loop windows measure different things
- Warnings and hard stops have different accounting effects
- Measure cost per accepted artifact, including failures
Before you start
- Basic Python, HTTP and container concepts
- An owned task with explicit acceptance criteria
Explain the chapter’s implementation boundary and apply its checklist or isolated helper exercise.
Key takeaways
- Call-set repetition and tool-frequency bursts use different windows.
- A hard limit must be reachable within its counting window.
- Include capped and failed attempts in accepted-artifact cost.
Two loop windows measure different things
The detector’s constructor defaults warn on three matching call sets and hard-stop on five within a history window of twenty. A second layer counts individual tool names even when arguments vary, with constructor defaults of thirty for warning and fifty for stopping. Effective configuration can override these values, including per-tool thresholds; they are not universal service limits.
The frequency window is sized to at least the largest hard limit in play. Otherwise a twenty-entry queue could never reach a fifty-call threshold and the protection would be unreachable. A deque and mirrored Counter let counts rise and decay without rescanning the entire frequency window on each call; a per-tool override can enlarge this shared window.
Warnings and hard stops have different accounting effects
A repeated-call warning is a candidate while the rest of the current batch is examined. Frequency accounting continues, and a later hard limit can supersede that warning. This detail prevents an early warning from hiding a more serious tool burst later in the same model response. It also means one model response and one tool invocation are not interchangeable accounting units.
A hard stop suppresses the proposed tool calls and records a reason, while a warning is queued for the next model request. Token budgets are installed through a separate enabled branch in the agent builder. Track token cost, tool execution cost, sandbox lifetime and output acceptance separately; a run with fewer calls can still be worse if it fails the actual assignment.
Measure cost per accepted artifact, including failures
Prepare a fixed set of owned tasks with expected outputs and record model identity, configuration, concurrency and source revision. Count failed and capped attempts in total spend, then divide by accepted artifacts. Report latency distributions only after collecting samples; leave them unknown when no workload has run instead of borrowing the upstream project’s promotional numbers.
The illustrative record below deliberately contains null measurements. Compare a baseline and one changed setting at a time, retaining the reason for every rejection. Increasing limits can rescue legitimate long investigations, but it also raises worst-case exposure and can conceal poor decomposition. Inspect false-positive examples before tuning thresholds upward.
Implementation steps
- 1
Freeze a task set, source revision and model configuration.
- 2
Record tokens, tool calls, sandbox time and stop reason per attempt.
- 3
Review accepted artifacts using the same rubric.
- 4
Change one limit only after examining false positives.
Copy-ready example
{"attempts":0,"acceptedArtifacts":0,"totalModelCost":null,"sandboxSeconds":null,"p95LatencyMs":null,"costPerAcceptedArtifact":null,"stopReasons":{},"benchmarkExecuted":false}Frequently asked questions
Are the 3/5 and 30/50 limits guaranteed for my instance?
No. They are inspected constructor defaults; configuration and per-tool overrides determine effective limits.
Is a lower tool count always cheaper overall?
Not necessarily. Rejected artifacts, retries, model choice and sandbox time also contribute to useful-work cost.
Sources
- README.mdSource checked 2026-09-08
- LICENSESource checked 2026-09-08
- backend/README.mdSource checked 2026-09-08
- backend/pyproject.tomlSource checked 2026-09-08
- backend/docs/middleware-execution-flow.mdSource checked 2026-09-08
- backend/packages/harness/deerflow/agents/lead_agent/agent.pySource checked 2026-09-08
- backend/packages/harness/deerflow/agents/middlewares/loop_detection_middleware.pySource checked 2026-09-08
- backend/packages/harness/deerflow/agents/middlewares/_bounded_dict.pySource checked 2026-09-08
- backend/packages/harness/deerflow/config/loop_detection_config.pySource checked 2026-09-08
- backend/packages/harness/deerflow/sandbox/local/local_sandbox_provider.pySource checked 2026-09-08
- backend/app/gateway/auth_middleware.pySource checked 2026-09-08
- backend/app/gateway/csrf_middleware.pySource checked 2026-09-08
- docker/docker-compose.yamlSource checked 2026-09-08