Skip to main content

Neurotransmitter-inspired adaptive learning layer for LLMs

Project description

Limbiq

Neurotransmitter-inspired adaptive memory layer for LLMs.

Limbiq sits between the user and any LLM, enriching context with learned memories, behavioral rules, and knowledge graph facts — all without modifying model weights. Five signal types inspired by human brain chemistry control what gets remembered, suppressed, clustered, or flagged.

User Message → Limbiq.process() → Enriched Context → Any LLM → Response → Limbiq.observe() → Loop

Installation

pip install limbiq                    # Core library
pip install limbiq[faiss]             # + FAISS vector search (recommended)
pip install limbiq[dev]               # + pytest
pip install limbiq[playground]        # + FastAPI web dashboard

Limbiq requires Python 3.10+ and downloads the all-MiniLM-L6-v2 sentence-transformer model (~80MB) on first run.

For entity extraction, install the spaCy model:

python -m spacy download en_core_web_sm

Quick Start

from limbiq import Limbiq

lq = Limbiq(
    store_path="./neuro_data",
    user_id="dimuthu",
    llm_fn=my_llm,  # Any callable(str) -> str, or None for heuristic mode
)

# Before sending to LLM — retrieve memories and build context
result = lq.process("What's my wife's name?")

# Inject result.context into your system prompt
messages = [
    {"role": "system", "content": f"You are a helpful assistant.\n\n{result.context}"},
    {"role": "user", "content": "What's my wife's name?"},
]
response = my_llm(messages)

# After getting response — let Limbiq observe and learn
lq.observe("What's my wife's name?", response)

# End session — graph inference, entity resolution, memory aging
lq.end_session()

llm_fn is optional. Without it, Limbiq runs in heuristic mode — spaCy + regex extraction, no LLM-powered compression or tie-breaking.

The Five Signals

Signals fire automatically in observe() based on conversation content.

Dopamine — "This matters, remember it"

Fires when the user shares personal info, corrections, or positive feedback. Tagged memories are always included in context. Detection uses the unified encoder (self-attention over sentence context) instead of keyword matching.

# Automatic — fires when the encoder detects personal info, corrections, or enthusiasm
# Manual:
lq.dopamine("User's wife is named Prabhashi")

GABA — "Suppress this, let it fade"

Fires on denials, contradictions, or stale data. Suppression is soft — memories can be restored.

lq.gaba(memory_id="abc123")
lq.restore_memory("abc123")  # Undo suppression

Serotonin — "This pattern is stable, make it a rule"

Watches for recurring patterns across sessions. After 3+ observations across 2+ sessions, crystallizes into a permanent behavioral rule injected into every future context.

rules = lq.get_active_rules()
lq.deactivate_rule(rule_id)
lq.reactivate_rule(rule_id)

Acetylcholine — "Go deep here, build expertise"

Detects sustained interest in a topic (3+ turns) and creates knowledge clusters — grouped memories loaded as a unit when the topic returns.

clusters = lq.get_clusters()
memories = lq.get_cluster_memories(cluster_id)

Norepinephrine — "Something changed, be careful"

Fires on topic shifts or frustration. Temporarily widens memory retrieval and adds caution flags. Effects reset after each process() call.

Unified Encoder

As of v0.5.2, signal detection is powered by a single self-attention encoder (LimbiqEncoder) that replaces 234+ hardcoded keyword patterns. The encoder classifies intent (correction, denial, enthusiasm, personal info, frustration, contradiction) from sentence context rather than keyword matching.

  • Architecture: token embeddings (384-dim) → project (64-dim) → 2-head self-attention + LayerNorm + FFN → task-specific heads
  • Bootstrap: trains on examples generated from the old keyword patterns
  • Incremental learning: retrains on user corrections as they happen
  • Requires PyTorch; falls back gracefully when unavailable

Entity State

Entities in the knowledge graph now carry per-entity state inspired by biological cellular memory:

  • Resting activation — how "awake" an entity is based on recent mentions
  • Receptor density — per-signal sensitivity that adapts over time (entities that get corrected often become more sensitive to corrections)
  • Signal history — cumulative record of which signals have hit each entity
  • Sentinel patterns — immune-system-style watchers that flag stale references to corrected facts
state = lq.get_entity_state(entity_id)   # Single entity state
top = lq.get_top_activated_entities(5)    # Most active entities
sentinels = lq.get_sentinels()            # Entities watching for stale facts

Knowledge Graph

Limbiq automatically builds a knowledge graph from conversations using a hybrid extraction pipeline:

  1. spaCy dependency parsing — possessive relations ("my wife Prabhashi"), copular patterns, chained predicates ("my wife's father")
  2. LLM tie-break — resolves ambiguous fragments when llm_fn is provided
  3. Regex fallback — 20+ patterns for common relationships
  4. Fuzzy predicate matching — catches typos (Levenshtein distance ≤ 1)

The graph supports transitive inference (in-laws, grandparents, co-parents) and self-heals on every observe() call — cleaning junk entities, bridging disconnected components, and re-running inference.

lq.query_graph("Who is Prabhashi?")    # Direct graph lookup
lq.get_world_summary()                  # Compact user profile from graph
lq.get_entities()                        # All known entities
lq.get_relations()                       # All relationships (including inferred)
lq.describe_entity("Prabhashi")          # Natural language description
lq.heal_graph()                          # Manual self-heal trigger

Graph Pipeline (5 Phases)

For advanced use, Limbiq includes a multi-phase graph intelligence pipeline:

# Phase 1: Rule-based propagation — suppress noise, merge duplicates, repair graph
result = lq.propagate()

# Phase 2: GNN propagation — Graph Attention Network learns activation scores
#   3-layer GAT, 4 heads, 128-dim, ~2-5M params, trains on Phase 1 labels
result = lq.propagate_gnn(train_first=True, epochs=200)

# Phase 3: Pattern completion — TransE entity resolution + link prediction
#   ~50K params, merges duplicate entities, predicts missing relations
result = lq.run_pattern_completion(train_transe=True, epochs=500)

# Phase 4: Activation retrieval — hybrid scoring
#   final_score = α·embedding_sim + β·gnn_activation + γ·graph_relevance
lq.enable_activation_retrieval()

# Phase 5: Graph reasoning — micro-transformer for graph QA
#   ~50K params, 3 modes: entity pointer, boolean, count
lq.train_reasoner(epochs=100)
answer = lq.reason("Who is Dimuthu's father-in-law?")

Phases 2-5 require PyTorch (pip install torch).

Vector Search

Memory retrieval uses FAISS (Facebook AI Similarity Search) when available, falling back to numpy brute-force.

  • FAISS IndexFlatIP on normalized embeddings = exact cosine similarity
  • Incremental adds/removes — no full rebuild on each memory change
  • Index persisted to disk ({user_id}.faiss) between sessions
  • Thread-safe via threading.Lock
pip install faiss-cpu  # ~15MB, no GPU needed

Corrections

Combines Dopamine + GABA — stores new info as priority, suppresses contradicting memories.

lq.correct("User works at Bitsmedia, not Google")

Playground

Interactive web dashboard for exploring the knowledge graph, chatting, and inspecting signals.

pip install limbiq[playground]

# Heuristic mode (no LLM needed)
python -m limbiq.playground

# With Ollama
python -m limbiq.playground --llm-url http://localhost:11434/v1 --llm-model llama3.1

# With OpenAI
python -m limbiq.playground --llm-url https://api.openai.com/v1 --llm-model gpt-4o --llm-api-key sk-...

Open http://localhost:8765 after starting. The dashboard includes:

  • Chat — talk to Limbiq and watch it learn in real time
  • Knowledge Graph — interactive D3 visualization of entities and relations
  • Entity Explorer — browse entities and their relationships
  • Query Builder — test graph queries and memory retrieval

Inspection

lq.get_stats()                        # Memory counts per tier
lq.get_signal_log()                   # Full history of signals fired
lq.get_priority_memories()            # All dopamine-tagged memories
lq.get_suppressed()                   # All GABA-suppressed memories
lq.get_full_profile()                 # Complete user profile across all signals
lq.export_state()                     # Full JSON export for debugging
lq.get_graph_stats()                  # Entity/relation counts
lq.get_graph_connectivity()           # Connected component analysis
lq.get_entity_state(entity_id)        # Per-entity activation + signal history
lq.get_top_activated_entities(limit)  # Most active entities by activation
lq.get_sentinels()                    # Entities with sentinel watchers
lq.get_all_entity_states()            # Full entity state dump

How It Works

  • LLM-agnostic — works with any LLM via a callable, or runs without one in heuristic mode
  • Zero weight modification — all adaptation through context enrichment
  • Unified encoder — single self-attention model classifies intent across all signals, replacing 234+ hardcoded patterns
  • Entity state — per-entity activation, receptor density, and signal history inspired by biological cellular memory
  • Knowledge graph — entities and relations extracted automatically, inferred transitively, self-healed continuously
  • FAISS vector search — fast approximate nearest neighbor retrieval with numpy fallback
  • 5-phase graph pipeline — GNN, TransE, and micro-transformer for deep graph intelligence (optional, requires PyTorch)
  • SQLite persistence — memories, graph, rules, clusters, and entity states survive across sessions
  • Semantic search — 384-dim sentence-transformer embeddings (all-MiniLM-L6-v2) with TF-IDF fallback
  • Transparent — every signal is logged with trigger, timestamp, and effect
  • Reversible — suppressed memories can be restored, rules deactivated
  • Thread-safe — per-thread SQLite connections, thread-safe FAISS index and embedding cache

Architecture

┌──────────────────────────────────────────────────────┐
│                 Limbiq Public API                      │
├──────────────────────────────────────────────────────┤
│                LimbiqCore (orchestrator)               │
│         process() → observe() → end_session()         │
├──────────┬──────────┬──────────┬─────────────────────┤
│  Store   │ Signals  │  Graph   │ Retrieval + Context  │
│  Layer   │  Layer   │  Layer   │       Layer          │
├──────────┤          ├──────────┤                      │
│          │ Unified  │  Entity  │                      │
│          │ Encoder  │  State   │                      │
├──────────┴──────────┴──────────┴─────────────────────┤
│        Shared SQLite DB + FAISS Vector Index          │
└──────────────────────────────────────────────────────┘

See docs/ARCHITECTURE.md for full system topology, data flow diagrams, and module reference.

Development

git clone https://github.com/deBilla/limbiq.git
cd limbiq
pip install -e ".[dev]"
python -m spacy download en_core_web_sm
python -m pytest tests/ -x -q

CI runs tests on Python 3.10–3.13 via GitHub Actions. Releases are published to PyPI automatically when a GitHub Release is created.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

limbiq-0.5.2.tar.gz (180.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

limbiq-0.5.2-py3-none-any.whl (166.9 kB view details)

Uploaded Python 3

File details

Details for the file limbiq-0.5.2.tar.gz.

File metadata

  • Download URL: limbiq-0.5.2.tar.gz
  • Upload date:
  • Size: 180.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for limbiq-0.5.2.tar.gz
Algorithm Hash digest
SHA256 31e89d742949c72f7493b99573307aae7345bb2b5361663856acfef7f635b2c0
MD5 c88fd41737842a430c44e22b518ea912
BLAKE2b-256 125eb798ef0c762199a6ba7f9be7d5813aaaf425fcc73dcb2eab2cac2e13831c

See more details on using hashes here.

Provenance

The following attestation bundles were made for limbiq-0.5.2.tar.gz:

Publisher: publish.yml on deBilla/limbiq

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file limbiq-0.5.2-py3-none-any.whl.

File metadata

  • Download URL: limbiq-0.5.2-py3-none-any.whl
  • Upload date:
  • Size: 166.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for limbiq-0.5.2-py3-none-any.whl
Algorithm Hash digest
SHA256 26a4ab50f0c1614603125e2d678f592729f407f3917435cfe42cc65951e11970
MD5 b1c30b6995b66e31f9fff6ec91249c4d
BLAKE2b-256 c7ed830eb4a707eae6ef7ef44bc0d4724fc458102a01b89064053c3064076a26

See more details on using hashes here.

Provenance

The following attestation bundles were made for limbiq-0.5.2-py3-none-any.whl:

Publisher: publish.yml on deBilla/limbiq

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page