Stage 0: Environment and Source Code Map
Course: DeerFlow Source Code Class · Stage Exam Prerequisites: Able to read Python and TypeScript, familiar with HTTP and asynchronous tasks Corresponding Overview:
overview.mdGoal of This Stage: When seeing any file, be able to determine whether it belongs to the ‘reusable kernel,’ ‘product assembly layer,’ or ‘runtime assets.’
1. What this phase addresses
Section titled “1. What this phase addresses”DeerFlow has a considerable amount of code, but not many entry points. First, establish a three-layer map:
Reusable core: agent, tools, sandbox, models, runtimebackend/packages/extension-api/ Extension Contractbackend/app/ Product assembly: Gateway, channels, scheduling, MCP tasksfrontend/ + contracts/ + deploy/ Interface, cross-end contracts, deployed assetsThe most important hard boundary is:
app/* → deerflow/* alloweddeerflow/* → app/* forbiddenThis is not about being a pedant with the directory. deerflow It should be reusable by embedded clients, SDKs, and other hosts; once the core imports a certain Web route or IM table, it is no longer a general harness. backend/tests/test_harness_boundary.py Turn this rule into a CI failure.
2. First, remember a judgment
Section titled “2. First, remember a judgment”“Can this code exist independently of a specific product entry in DeerFlow?”
If yes, it usually belongs to the harness; if not, it usually belongs to the app. When you see from deerflow..., you are reading the core; when you see from app..., you are reading the host assembly. Dependencies like app appearing in the core are boundary degradation, not for “convenient reuse.”
3. Source Code Mainline
Section titled “3. Source Code Mainline”- The ASGI entry is at
backend/app/gateway/app.py, the routing is atbackend/app/gateway/routers/. - The unified admission function is
backend/app/gateway/services.py::start_run. - The Run control plane is at
runtime/runs/manager.py, and the execution plane is atruntime/runs/worker.py::run_agent. - The Agent factory is
agents/__init__.py::make_lead_agent, ultimately enteringagents/lead_agent/agent.pyandagents/factory.py. - Capability boundaries are handled respectively by
tools/,sandbox/,models/,mcp/,skills/. - State and evidence are handled by
runtime/checkpointer/,runtime/journal.py,runtime/events/. - Product extensions are at
backend/app/channels/,backend/app/scheduler/,backend/app/mcp_tasks/.
4. Key Objects and Contracts
Section titled “4. Key Objects and Contracts”| Object | Facts Owned | Should Not Be Forged By |
|---|---|---|
RunRecord |
run state, owner, lease, idempotency key | client, single middleware |
ThreadState.messages |
dialogue state of the current graph | any metadata in external requests |
| checkpoint | LangGraph recoverable state | business database records |
RunJournal |
run events, tool/delivery facts | SSE consumers |
| sandbox lease | usage rights of a particular isolated execution | path parameters generated by models |
5. An Observable Chain
Section titled “5. An Observable Chain”frontend / SDK → app.gateway.app → routers/thread_runs.py → services.start_run → RunManager → worker.run_agent → make_lead_agent → tools / sandbox / model → journal / checkpointObservation point: When a request returns, Run is often still pending; the real running appears after try_start() in the worker. Do not infer that the model has started executing based on the HTTP return time.
6. Experiment
Section titled “6. Experiment”Experiment A: Confirming boundaries
Section titled “Experiment A: Confirming boundaries”rg -n "from app" backend/packages/harness/deerflowReference acceptance: There should be no legitimate hits of kernel dependencies on the app; If they do, first determine whether it is a test or compatibility bridge.
Experiment B: Confirm the configuration entry
Section titled “Experiment B: Confirm the configuration entry”Open the root directory config.example.yaml and find the five types of configurations: model whitelist, sandbox provider, summarization, memory, and channel. Reference observation: The configuration is “what is allowed,” not “what the client wants to use.”
Experiment C: Draw Port Diagram
Section titled “Experiment C: Draw Port Diagram”Mark 3000, 8001, 8002, and 2026 respectively as frontend, Gateway, sandbox provisioner, and reverse proxy. The acceptance point is that each port only undertakes one clear role.
Experimental Reference Answers
Section titled “Experimental Reference Answers”- Valid results should only appear in tests, samples, or explicit compatibility bridges
from app; If harness production code depends on an app, it means the kernel boundary is inverted. - It should be able to locate the model whitelist, sandbox provider, summarization, memory, and channel configurations separately; These constraints restrict what the server allows, and client requests can only be selected within these constraints.
- Confirm the sole responsibility of each port according to the actual warehouse configuration: do not use frontend, Gateway/API, sandbox provisioner, or reverse proxy together; The value of port diagrams is to expose error coupling.
7. Failure and recovery
Section titled “7. Failure and recovery”| Phenomenon | Check first | What not to do |
|---|---|---|
| Import error at startup | Dependencies, Python version, working directory | Change business code to mask environment issues |
| Harness Reverse Dependency App | test_harness_boundary.py |
Delete the test |
| Frontend cannot connect | Gateway port, proxy, authentication | Directly bypassing start_run |
| sandbox cannot start | provisioner and provider configuration | Switch to the host shell to “run first” |
8. Pass through customs and self-test
Section titled “8. Pass through customs and self-test”deerflowWhy can’t I importapp?- What do
RunRecord, checkpoint, andRunJournaleach store? - Why can’t HTTP return to check that Run has been
running? - How do you distinguish the responsibilities of port
8001and8002?
Reference answers
Section titled “Reference answers”- Because
deerflowis a reusable kernel, andappis the assembly layer of a product host. Reverse dependencies bind the kernel to specific Web/IM/databases, losing the reusability of embedded clients, SDKs, and other hosts, and are blocked by boundary testing. RunRecordStores control surface status, owner, leases, and powers; Checkpoint stores the recoverable graph state of LangGraph;RunJournalStores process events, tokens, tools, and delivery facts. The former manages scheduling, the middle manages continuation, and the latter manages observation and auditing.- The routing returns the order result, so Run may still be
pending. Only after the worker completes state migration and acquires ownership throughtry_start()does it becomerunning; This delay is the window for queuing, cancellation, and concurrency competition. 8001is the FastAPI Gateway, responsible for admission, authentication, SSE, and product assembly;8002is the sandbox provisioner control service, responsible for preparing and reclaiming the isolated environment, and does not handle the Run lifecycle.
9. Source code coordinates
Section titled “9. Source code coordinates”backend/tests/test_harness_boundary.pybackend/app/gateway/app.pybackend/app/gateway/services.pybackend/packages/harness/deerflow/agents/__init__.pybackend/packages/harness/deerflow/runtime/runs/manager.py
10. Next
Section titled “10. Next”Entering Stage 1: Split “Acceptance” into verifiable status migration and explain why pending is not a decorative state.