Decision Process (DP)

A DecisionProcess is a declarative, state-driven execution machine that continually matches a state against a collection of independent operators to determine the next step.

Agentic AI Equivalent

In agentic AI design patterns, orchestration serves as the control layer coordinating model invocations, tools, and system state across complex, multi-step reasoning cycles. Existing orchestration paradigms typically fall into one of the following two:

  • DAG-based workflows: Execute logic across structured nodes and fixed branches. They are highly controllable and explainable, but structurally rigid.

  • skills.md-based approaches: Rely on open-ended, prompt-driven instructions. They are highly context-aware and flexible, but challenging difficult to govern due to their non-determinism.

cognition’s provides an ideal middle ground: context-aware, flexible DecisionProcess that is programmatically enforced.

Key characteristics include:

  • Iterative Execution: Instead of executing code along a fixed, linear path, a decision process runs an iterative loop on every system tick.

  • Declarative Control: Rather than hardcoding an explicit, rigid sequence of steps in a workflow, developers define decision criteria declaratively.

  • State Mutation: They continually evaluate agent state to determine the next steps of reasoning or action. Each chosen action mutates the state, leading directly to the next decision.

  • Hierarchical Structure: Decision processes can be organized hierarchically to manage complex system architectures.

cognition uses DecisionProcess to continuously evaluate declarative decision criteria against a live state, dynamically computing, executing, and adjusting workflows in real-time. This conceptualization is similar in spirit to a combination of event-driven and data-driven programming paradigms, but they are purpose-built for agentic systems.

What are the scientific principles?

A Decision Process is a generalization of multiple approaches to specifying decision-making policies.

A Knowledge Augmented DecisionProcess (KADP) grounds its execution in formal decision theory and state-space search. While it shares the foundational concepts of states and actions with Markov Decision Processes (MDPs), it diverges from data-driven reinforcement learning by operationalizing the Problem Space Hypothesis by replacing trial-and-error optimization with explicitly programmed expert domain knowledge.

Rather than relying on environment simulators, reward functions, discount factors, or probabilistic state transitions, a KADP uses deterministic programmatic operators, preconditions, and termination checks. This design bypasses the cold-start problem of reinforcement learning, enabling predictable, auditable, and expert-driven decision-making from the very first step.

cognition directly mirrors Dual-Process Cognitive Theory in Thinking, Fast and Slow; while LLMs and other reasoners implement fast, automatic inferences (System 1), the KADP acts as a deliberate, logical controller (System 2) that explicitly directs reasoning trajectories.

See also

Further Reading & References

  • A Markovian Decision Process (Richard Bellman, 1957): Foundational paper introducing Markov Decision Processes (MDPs) in decision theory.

  • Human Problem Solving (Newell & Simon, 1972): Seminal text establishing the Problem Space Hypothesis for AI decision systems.

  • Thinking Fast and Slow: Video lecture breaking down the dual-process theory of the human cognitive architecture delivered by Prof. Daniel Kahneman.

Why use a decision process?

Using a decision process for orchestration provides an ideal middle ground between deterministic code and non-deterministic AI generation. It fundamentally balances the need for flexible process execution with the controllability of the process.

  • Context-Aware Flexibility: It behaves with the flexibility of an LLM-driven orchestration, using a live state to dynamically figure out what to do next.

  • Guaranteed Execution: Unlike LLMs (which can deviate from instructions), a decision process is written programmatically, guaranteeing exactly what steps and operators are executed in a given situation.

Implementation Details

The DecisionProcess operates on a continuous cycle of evaluating state and executing actions:

Decision Process Cycle

Core Components

  • state: Defines the mutable data needed to represent process progress. Upon initialization of the DP, you provide a function to supply its initial state.

  • IOContainer: Provides the process with access to non-state data and channels.

    • input (i): Read-only structured data (typically from external sensors).

    • output (o): Channels for execution (typically a function used to interact with external actuators).

    • elab (e): Key/computed value pairs (typically combining aspects of state + input + arguments).

    • args (a): Read-only key/value pairs used to parameterize an execution of the process.

Tip

The string value (e.g., str(my_dp) of a DP reveals highly useful information about this structure.

The DP Cycle (Phases)

The DP continually executes a cycle consisting of the following phases:

  1. Elaboration (via Elaborator): Computes value(s) based upon the current state and IO.

  2. Termination (via TerminationCheck): Detects state-based ending conditions.

  3. Propose (via ActionFactory): Indicates valid Action(s) that can be taken.

  4. Rank (via ActionEvaluator, producing ActionRank): Uses knowledge to evaluate and score candidate actions.

  5. Apply (commonly via operators): Executes the single selected action, typically to modify state and/or externally actuate.

Note

A DP can run individual phases/cycles, but commonly runs until a termination condition is detected.

Once terminated, a DP must be reinitialized before future runs, which restarts the cycle and resets the DP state to an initial value.

Tip

It is not uncommon for the state initialization function to return a reference to a (mutable) object…

my_state = CustomStateClass()
my_dp = DecisionProcess(lambda: my_state)

The effect of this pattern is that DP state persists across DP reinit.

Typical DP Usage (e.g., Isolated Testing)

  1. Design DP state: (e.g., author a custom state class).

  2. Instantiate a DP: Supply it with a function that outputs an initial state value.

  3. Add components: (e.g., attach operators, termination checks, etc., to the DP).

  4. Run: (e.g., via my_dp()).

  5. Access state & Repeat: Access the DP state, potentially run reinit -> re-run.