From Prompt to Run: A Working Model of Dify

Dify becomes easier to judge when its workflow, tenant-bound model capability, event stream, persistence, and trace are read as one request path. The focus here is the relationship among those already-established mechanisms: what crosses each boundary, which state belongs to the control plane or the context being processed, and how that distinction helps locate a failure. The result is a practical model for understanding why grounding is a separate design problem rather than a prompt-writing trick.

A request has more than one path

Imagine the support assistant receiving a question about a rejected expense. The employee's request first reaches a Dify app surface or API endpoint. The application mode determines which generation path is appropriate and what shape of input is accepted. A workflow request supplies workflow inputs rather than pretending to be a chat message. The API authenticates the caller, checks the app context, and exposes a streaming response for work that may continue beyond the initial request.

From there, the request enters the workflow graph. The graph establishes which decisions can occur and in what relationships: perhaps a classifier chooses a policy area, a retrieval node obtains relevant material, an LLM node writes an explanation, and a tool node opens a correction ticket only on the appropriate branch. The variable pool carries this run's question, system context, uploaded files, and earlier node outputs. The graph is the control path; it says what the application may attempt and how one result becomes another node's input.

When execution reaches the LLM node, the graph does not itself become a vendor SDK call. Tenant-scoped configuration resolves the provider, model, credentials, model schema, quota policy, and possibly a load-balancing candidate. The plugin runtime then transports the request to the provider-specific daemon. The model sees prompt content and model parameters, while the runtime carries identity and policy information needed for accounting and authorization. The same separation lets a retrieval path use an embedding model or reranker without pretending that those are simply alternate names for text generation.

The request has therefore crossed several boundaries before an answer exists:

flowchart LR A["Caller and app surface"] --> B["Mode dispatch"] B --> C["Workflow graph and variable pool"] C --> D["Tenant-bound model capability"] D --> E["Knowledge or context boundary"] E --> F["Tool or Agent action"] F --> G["Answer or external result"] C --> H["Run events and execution ledger"] D --> H E --> H F --> H H --> I["Stream, trace, and diagnosis"]

The diagram is not a claim that every application visits every box. A completion app may not use a graph. A workflow may generate an answer without retrieval or tools. An Agent can introduce an inner model-and-tool run rather than a direct tool node. The point is that Dify gives these possibilities distinct places and interfaces. The path can be shorter or longer, but each added capability creates a new boundary whose inputs, owner, and failure behavior matter.

This makes the phrase “the model answered” too coarse for a production diagnosis. If the classifier chose the wrong branch, the problem is in flow or interpretation. If the provider rejected a credential, the graph may be sound while capability resolution is not. If the model received weak context, the visible error may be an evidence problem even though generation completed normally. If a ticket was created but the client lost its connection, the answer and the side effect have different statuses. One final string cannot represent all of those facts.

Control plane and context plane are not the same thing

The control plane is the part of Dify that determines how execution is allowed to proceed. It includes app mode, graph topology, node selection, variable mappings, tenant and caller identity, model/provider configuration, execution limits, command channels, and lifecycle status.