Skip to content
ActiveInferenceInstitutePublic

About

Knowledge base and Python package for discrete and continuous Active Inference: generative models, expected free energy, POMDP simulation, and an executable manuscript with reproducible validation commands.

Topics

Resources

Stars

22 stars

Watchers

3 watching

Forks

Repository files navigation

title Cognitive Active Inference
type package
status stable

Cognitive Active Inference

quality

A tested Python package for Active Inference agents, and an Obsidian vault of more than 1,000 linked pages that explain the mathematics, biology, cognitive science and philosophy behind it. The package is the executable reference; the vault is the explanation. Each side points at the other.

I want to Go to
Run an agent in five minutes Quick start
Understand how an agent decides How one step works
Learn the theory in order Reading path
Find a concept page knowledge_base/catalog.md
See what code exists Package map and Agents
Reproduce the paper Manuscript
Contribute Contributing

Quick start

Python 3.10 or newer:

python -m pip install -e ".[dev]"

Build a two-state model, infer beliefs after an observation, and infer a distribution over actions:

import numpy as np

from cognitive import ActiveInferenceDispatcher, DiscreteGenerativeModel, InferenceConfig, ModelState

model = DiscreteGenerativeModel(
    A=np.array([[0.9, 0.1], [0.1, 0.9]]),                      # P(o | s)
    B=np.stack([np.eye(2), np.array([[0.1, 0.9], [0.9, 0.1]])], axis=2),  # P(s' | s, a)
    C=np.array([0.0, 1.0]),                                    # log-preference over o
    D=np.array([0.5, 0.5]),                                    # prior over s
    E=np.array([0.5, 0.5]),                                    # prior over a
)
dispatcher = ActiveInferenceDispatcher(
    InferenceConfig(
        method="variational",
        policy_type="discrete",
        temporal_horizon=2,
        learning_rate=0.5,
        precision_init=1.0,
        seed=7,
    ),
    model,
)
state = ModelState(model.D.copy(), model.E.copy(), 1.0, 0.0, 0.0)
beliefs = dispatcher.dispatch_belief_update(1, state)   # q(s) after observing o = 1
policies = dispatcher.dispatch_policy_inference(state)  # distribution over actions
assert np.isclose(beliefs.sum(), 1.0)
assert np.isclose(policies.sum(), 1.0)

The editable install also provides these commands:

Command Purpose
cognitive-benchmark Time the runtime components
cognitive-build-manuscript Build the executable manuscript
cognitive-validate-docs Run the documentation gate
cognitive-verify-links Check [[wiki links]]
cognitive-kb-index Check or regenerate the knowledge-base catalogs
cognitive-normalize-frontmatter Check or fix semantic_relations frontmatter
cognitive-create-node Create a knowledge-base page from a template

How one step works

An agent holds beliefs q(s) about hidden states. Each step it updates them from what it observed, scores every candidate policy by expected free energy G, and turns those scores into a distribution over actions.

flowchart LR
    O["observation o"] --> BU["dispatch_belief_update"]
    Q0["beliefs q(s)"] --> BU
    BU --> Q1["posterior q(s)"]
    Q1 --> EFE["expected free energy G per policy"]
    GM["generative model A, B, C, D, E"] --> BU
    GM --> EFE
    EFE --> SM["softmax of -G / temperature, times prior E"]
    SM --> PI["distribution over actions"]
    PI --> ACT["action a"]
    ACT -. "next step" .-> O
Loading

The generative model is five arrays, validated on construction:

Array Meaning Theory page
A[o, s] likelihood P(o | s) generative models
B[s', s, a] transitions P(s' | s, a) POMDP structure
C[o] log-preferences over observations expected free energy
D[s] prior over initial states belief updating
E[a] prior over actions policy selection

The dispatcher offers three inference methods and discrete policy sequences with explicit horizons, temperatures and seeds. All of its methods return finite, normalized distributions.

flowchart TB
    CFG["InferenceConfig"] --> D["ActiveInferenceDispatcher"]
    D --> V["variational"]
    D --> M["mean_field"]
    D --> S["sampling"]
    V --> OUT["normalized beliefs and policies"]
    M --> OUT
    S --> OUT
Loading

Method background: variational inference, variational free energy, message passing, precision.

Expected free energy

expected_free_energy returns the canonical objective and its parts:

G = D_KL(q(o) || p*(o))  +  E_q(s)[H(P(o | s))]
    \_____ risk _____/     \____ ambiguity ____/

Ambiguity equals H[q(o)] - I(s; o), so the expected information gain is already inside it. The package returns the gain as a fourth value for inspection and does not subtract it from the total a second time. InferenceConfig.exploration_weight adds an explicit information-seeking bias; it defaults to 0.0, and 1.0 reproduces the objective used before 1.1.0 (see CHANGELOG.md). Derivation and intuition: expected free energy, in the free energy principle, information gain, KL divergence.

Package map

flowchart TB
    subgraph pkg ["cognitive  (code/tools/src)"]
        MODELS["models/active_inference<br/>dispatcher, generative model,<br/>base model, homeostatic control"]
        MATS["models/matrices<br/>MatrixOps, MatrixLoader"]
        UTILS["utils<br/>matrix_utils, create_node,<br/>network visualization"]
        VIZ["visualization<br/>MatrixPlotter, StateSpacePlotter"]
        BENCH["benchmarks"]
    end
    subgraph things ["Things  (code/Things)"]
        SP["Simple_POMDP"]
        CG["Continuous_Generic"]
    end
    subgraph scripts ["scripts  (code/scripts)"]
        GATES["validate_docs, verify_links,<br/>check_markdown_links,<br/>kb_index, normalize_frontmatter"]
        MS["build_manuscript"]
        MUT["mutation_check"]
    end
    MODELS --> MATS
    MODELS --> UTILS
    SP --> UTILS
    CG --> UTILS
    VIZ --> UTILS
    GATES --> KB[("knowledge_base/")]
    MS --> MAN[("docs/manuscript/")]
Loading
Component Read
cognitive package code/tools/src/README.md, docs/api/README.md
Dispatcher and models code/tools/src/models/active_inference/README.md
Tests code/tests/README.md, docs/tools/mutation_testing.md
Configuration config.yaml, docs/config/README.md
Every folder project_structure.md

Agents

code/Things/ is installed as the Things package. Two of its folders contain code; the others are design notes with no importable Python.

Agent Kind What it is
Simple_POMDP code Discrete POMDP agent configured from a YAML path or dict; seeded, validated, with persistence, histories and expected-free-energy components
Continuous_Generic code Precision-weighted generalized-coordinate updates; multi-frame GIF animation through ContinuousVisualizer
Generic_POMDP design notes Matrix-configured discrete agent design
Generic_Thing design notes The abstract definition of an agent
Ant_Colony design notes Stigmergic foraging concept
BioFirm, KG_Multi_Agent, Path_Network design notes A firm as an agent; agents on a knowledge graph; agents on a dynamic network

Theory behind them: POMDP framework, generalized coordinates, continuous-time models, Markov blankets, swarm intelligence, ant colony organization.

The knowledge base

Start at knowledge_base/catalog.md. It lists every domain, and each domain's catalog.md lists every page with its opening line. The catalogs are generated by kb_index.py; do not edit them. The glossary defines the vocabulary, and linking standards say how pages connect.

flowchart TB
    FEP["free_energy_principle<br/>the unifying principle"]
    MATH["mathematics<br/>probability, information theory,<br/>inference, control"]
    COG["cognitive<br/>perception, action, memory,<br/>decision making, social cognition"]
    BIO["biology<br/>ecology, evolution,<br/>collective behaviour"]
    SYS["systems<br/>complexity, emergence,<br/>self-organization"]
    PHIL["philosophy<br/>epistemology, enactivism,<br/>mind"]
    AG["agents<br/>architectures and designs"]
    ONT["ontology<br/>shared vocabulary"]
    RES["research<br/>directions and applications"]
    CIT["citations<br/>references"]
    BF["BioFirm<br/>biological firm theory"]
    FEP --> MATH
    FEP --> COG
    FEP --> BIO
    MATH --> AG
    COG --> AG
    BIO --> SYS
    SYS --> COG
    PHIL --> FEP
    ONT -.-> MATH
    ONT -.-> COG
    RES -.-> AG
    CIT -.-> FEP
    BF --> BIO
Loading
Domain Scope Enter at
free_energy_principle The principle, its mathematics, applications across biology, cognition and systems README, catalog
mathematics Probability, information theory, variational inference, POMDPs, control README, catalog
cognitive Perception, attention, memory, decision making, social and collective cognition README, catalog
biology Ecology, evolution, colony organization, communication README, catalog
systems Complexity, emergence, self-organization, networks README, catalog
philosophy Epistemology, enactivism, philosophy of mind and science README, catalog
agents Agent architectures and the POMDP framework README, catalog
ontology Cross-domain vocabulary README, catalog
research Research directions and implementation notes README, catalog
citations Reference lists and sources README, catalog
BioFirm Biological firm theory in Active Inference terms README, catalog

The vault explains concepts; executable behavior is defined by the package and its tests. Pages may use pseudocode to illustrate an idea, and that code is not package API.

Reading path through the theory

flowchart LR
    A["Bayes' theorem"] --> B["Variational inference"]
    B --> C["Variational free energy"]
    C --> D["Free energy principle"]
    D --> E["Generative models"]
    E --> F["Expected free energy"]
    F --> G["Policy selection"]
    G --> H["Active inference as a POMDP"]
    H --> I["Run it: Quick start"]
Loading
  1. Bayes' theorem
  2. Variational inference
  3. Variational free energy
  4. Free energy principle
  5. Generative models
  6. Expected free energy
  7. Policy selection
  8. Active inference as a POMDP

Longer routes by background: learning roadmap, guides and learning paths. From the cognitive side: active inference, predictive coding, the Bayesian brain, hierarchical models.

Documentation

docs/README.md is the spine. It covers the implemented package and the process around it.

Folder Contents
docs/api/ Exports, signatures, executed examples, version policy
docs/guides/ Application notes and learning paths
docs/examples/ Example entry points
docs/tools/ One page per shipped tool or gate
docs/development/ Development loop and contribution rules
docs/repo_docs/ Setup, documentation standards, linking, naming, testing
docs/implementation/rxinfer/ Notes on RxInfer.jl, an external project
docs/policy/ The term policy the documentation gate enforces

Manuscript

docs/manuscript/ is a complete executable paper. Every number and figure is generated from the package, so the text cannot drift from the code.

flowchart LR
    CFG["config.yaml"] --> B["cognitive-build-manuscript"]
    SRC["numbered sections<br/>references.bib"] --> B
    PKG["cognitive and Things APIs"] --> B
    B --> FIG["figures and<br/>manuscript_variables.json"]
    FIG --> MD["combined.md"]
    MD --> H["manuscript.html"]
    MD --> P["manuscript.pdf"]
    B --> MAN["build_manifest.json"]
Loading
cognitive-build-manuscript --output build/manuscript              # HTML and PDF
cognitive-build-manuscript --no-render --output build/manuscript  # no Pandoc or XeLaTeX needed

Quality gates

python -m pytest -q --cov                           # tests; branch coverage against the floor
ruff check . && ruff format --check code            # lint and format
mypy code/tools/src code/Things code/scripts        # types
python code/scripts/validate_docs.py --json         # documentation gate
python -m scripts.mutation_check                    # would the tests notice a wrong line?

--cov measures every module in the configured source tree, so the number is the package's, not a chosen subset's (why). The documentation gate runs the whole checklist in one pass:

flowchart LR
    VD["validate_docs"] --> FM["frontmatter parses,<br/>relations are quoted links"]
    VD --> CAT["catalogs are current"]
    VD --> WL["wiki links resolve"]
    VD --> ML["Markdown links resolve"]
    VD --> FN["fences are closed,<br/>Python examples compile"]
    VD --> TP["term policy"]
Loading

CI (quality.yml, described in docs/tools/ci_tools.md) runs four jobs in parallel.

flowchart LR
    PUSH["push or pull request"] --> T["tests<br/>Python 3.10 and 3.12"]
    PUSH --> C["checks<br/>lint, types, docs,<br/>manuscript, benchmarks"]
    PUSH --> M["mutation-gate"]
    PUSH --> P["build-package<br/>wheel and console scripts"]
Loading

Tests write artifacts only to temporary directories, and generated output is excluded from version control. The term policy is in docs/policy/documentation_terms.yaml.

Contributing

License

Code is MIT (LICENSE). Documentation and the knowledge base are CC BY-NC-SA 4.0.

About

Knowledge base and Python package for discrete and continuous Active Inference: generative models, expected free energy, POMDP simulation, and an executable manuscript with reproducible validation commands.

Topics

Resources

Stars

22 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages