Skip to main content

obsess

A memory system for LLM multi-agent pipelines. Plug-and-play LLM providers (llama.cpp, Ollama, Anthropic, OpenAI-compatible, Gemini), plug-and-play storage (in-memory, SQLite, or your own), and a memory model that treats agent relationships as first-class: siblings share differently than peers, a master and a prodigy share differently than parent and child, a team's failure is not any individual's failure.

Standard multi-agent memory puts everything in one store and lets every agent read from it. obsess doesn't. Memory is utility-gated (only content that matches an active obsession is encoded), compressed into impressions (regenerated through the current frame at retrieval), and distinguishes trauma (verbatim, self-surfacing, failure-linked) from regular recall. When multiple agents are in play, relationships shape what flows between them: obsessions inherit through parent/child edges, warnings propagate across peers, team failures live in pools.


Install

pip install obsess

# Or with LLM providers you use:
pip install "obsess[anthropic]"           # Claude
pip install "obsess[llamacpp]"            # Local GGUF
pip install "obsess[openai]"              # OpenAI + compatible (DeepSeek, Mistral, Groq, ...)
pip install "obsess[all-providers]"       # Everything

# With semantic embeddings (optional; HashEmbedder works with no deps):
pip install "obsess[embeddings]"

From source:

git clone https://github.com/djwarf/obsess
cd obsess
pip install -e ".[all]"

Quickstart

from obsess import Population
from obsess.types import SeedType

pop = Population.new()                    # in-memory; swap storage with SQLiteStorage(path)
agent = pop.spawn("assistant")

# What this agent cares about — the encoding gate
agent.seed_obsession(
    domain="code_quality",
    description="write clean readable tested code",
    seed_types=[SeedType.NEED_FOR_SUCCESS],
    commitment=0.8,
)

# Ingest — only gate-clearing content is encoded
agent.ingest("I just fixed a null check in the auth handler.")    # stored
agent.ingest("Taylor Swift released a new album today.")          # dropped

# Retrieve — synthesized through the current frame
result = agent.query("What do I know about the auth handler?")
print(result.answer)

See examples/ for multi-agent scenarios, pools, persistence, and real-LLM integration.


Why obsess

Standard RAG obsess
Everything embeds, sorts at retrieval Gate at encode: most content is not stored
Chunks are stored verbatim Impressions are compressed through the current frame
Retrieval is playback Retrieval is regeneration through the current frame
Failure is just more text Trauma is a separate encoding class — verbatim, self-surfacing, immune to narrative rewriting
Multi-agent = shared store, everyone reads Multi-agent = typed relationships, sharing rules per kind, non-transitive
Memory is static Relationship topology shapes what flows across agents

Provider selection

The semantic layer (scoring, impression formation, regeneration) lives in one place; swapping LLM backends is a drop-in change.

from obsess import Population, ProviderSemantics

# Local GGUF via llama.cpp (Qwen3, Gemma, Llama, Mistral, ...)
from obsess.providers import LlamaCppProvider
llm = ProviderSemantics(LlamaCppProvider("/path/to/model.gguf"))

# Anthropic (Claude)
from obsess.providers import AnthropicProvider
llm = ProviderSemantics(AnthropicProvider(model="claude-sonnet-4-6"))

# OpenAI — and DeepSeek, Mistral, Groq, Together, xAI, Fireworks via the same class
from obsess.providers import OpenAICompatibleProvider
llm = ProviderSemantics(OpenAICompatibleProvider(
    model="deepseek-chat",
    base_url="https://api.deepseek.com/v1",
    api_key="...",
    strict_schema=False,  # DeepSeek doesn't do strict JSON schema yet
))

# Google Gemini
from obsess.providers import GeminiProvider
llm = ProviderSemantics(GeminiProvider(model="gemini-2.5-flash"))

# Ollama
from obsess.providers import OllamaProvider
llm = ProviderSemantics(OllamaProvider(model="qwen3:4b"))

pop = Population.new()
agent = pop.spawn("assistant", llm=llm)

Writing a new provider is ~50 lines implementing the Provider protocol. See obsess/providers/.


Storage selection

from obsess import Population
from obsess.storage.sqlite import SQLiteStorage

# In-memory (default; transient)
pop = Population.new()

# SQLite (persistent across sessions)
pop = Population.new(storage=SQLiteStorage("obsess.db"))

# Rehydrate agents from a prior session
for agent_id in pop.agent_ids_on_record():
    pop.rehydrate_agent(agent_id)          # pass llm= if needed

Custom backends (Postgres, Redis, DynamoDB, ...) implement the Storage protocol. See obsess/storage/.


Multi-agent: relationships and pools

from obsess import Population, ObsessionSpec, RelationshipKind
from obsess.types import SeedType

pop = Population.new()

# A shared obsession both agents can activate against
code_quality = pop.shared_obsessions.define(
    domain="code_quality",
    description="write clean readable tested code",
)

master = pop.creator.propose("master", [ObsessionSpec(
    shared_definition_id=code_quality.id,
    seed_types=[SeedType.DELIBERATE_STUDY],
    commitment=0.9,
)]).agent

prodigy = pop.spawn("prodigy")

# Prodigy inherits the master's obsession with bootstrapped commitment
pop.form_relationship(RelationshipKind.MASTER_PRODIGY, "master", "prodigy")
assert prodigy.obsessions.get(code_quality.id) is not None

# When master records a failure, prodigy sees it via trauma propagation
master.record_failure(
    context="missed a null check in review",
    failure="production bug shipped",
    attempted_solutions=["manual review"],
    cost="hotfix + postmortem",
    unsolvable_at_time=True,
    linked_obsession_id=code_quality.id,
)

# Prodigy encounters similar context — master's warning fires, rendered through
# prodigy's current frame
r = prodigy.ingest("About to review a PR for null safety.")
for surfaced in r.trauma_warnings:
    print(f"[{surfaced.access.value}] {surfaced.rendered_text}")

Four relationship kinds:

  • TEAM — pool formation, warning-share both directions.
  • PEER — visibility-granting, no-share by default.
  • PARENT_CHILD — directional, non-decaying, obsessions inherit attenuated.
  • MASTER_PRODIGY — directional, decaying, prodigy bootstraps to master's level.

See DESIGN-MULTI.md for the full relationship model.


Integrating with agent frameworks

obsess is framework-neutral — it provides memory state; your framework provides the reasoning loop. See docs/INTEGRATIONS.md for patterns with LangChain, the Claude Agent SDK, and raw tool-loop agents.

The core pattern is a sandwich around each LLM call:

# Before the LLM call
ingest_result = agent.ingest(observation)
warnings = [st.rendered_text for st in ingest_result.trauma_warnings]

# Augment the prompt
prompt = (
    f"{user_message}\n\n"
    f"Memory warnings: {warnings}" if warnings else user_message
)

# Your framework's call
response = my_framework.chat(prompt)

# After — flag failures explicitly if you detect one
if detected_failure:
    agent.record_failure(context=..., failure=..., ...)

Documentation

  • DESIGN.md — per-agent memory architecture (utility gate, impressions, trauma, obsessions).
  • DESIGN-MULTI.md — multi-agent model: ownership modes, relationship kinds, pools, propagation, render layer.
  • DESIGN-META.md — meta-layer: Creator, Evolution selection, Bonding.
  • docs/INTEGRATIONS.md — plugging obsess into common agent frameworks.
  • examples/ — runnable scenarios.

Status

Alpha. The architecture is complete and tested (61 tests). The API may evolve with real-world use. Feedback welcome.

Metadata

Release files for obsess 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for obsess 0.1.0
File Size Uploaded
obsess-0.1.0.tar.gz 56.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for obsess 0.1.0
File Interpreter ABI Platform
obsess-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 107.4 kB

Release files / obsess-0.1.0.tar.gz

Download URL obsess-0.1.0.tar.gz
Size 56.0 kB
Tags Source
SHA-256 checksum
How to use checksums
6eee34006244a9f62f114d10194f5238c198fc81c043efa2fcd3031b6fbef29f
BLAKE2b-256 checksum
How to use checksums
005ef5d5b6b8d34248a60c3a0cc512de1e52c67d96280ff8e44b9f59ec7ff84a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 17, 2026.

Transparency log

Release files / obsess-0.1.0-py3-none-any.whl

Download URL obsess-0.1.0-py3-none-any.whl
Size 51.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
97a161af721d99317079612b0ab3f04b423974e7d7072dde17ac18f29a37fee5
BLAKE2b-256 checksum
How to use checksums
e629d4853066cf75da49431a2d1cc4358e78446fda5652edf2cb5e890223232b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 17, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page