Skip to main content

CoMeT — Cognitive Memory Tree: Hierarchical memory system for LLM agents

Project description

☄️ CoMeT — Cognitive Memory Tree

Lossless structured memory for AI agents.

CoMeT compresses long conversations into a navigable tree of memory nodes.
Unlike naive summarization that loses details, CoMeT preserves raw data behind structured summaries — agents read summaries first, then drill into raw data only when needed.

Architecture

User Input
    │
    ▼
┌─────────┐    SLM (fast)     ┌───────────┐
│  Sensor  │ ───────────────▶ │ L1 Buffer │
└─────────┘   entity/intent   └─────┬─────┘
                                    │ cognitive load trigger
                                    ▼
                              ┌───────────┐
                              │ Compacter │  LLM (slow)
                              └─────┬─────┘
                                    │ summary + trigger + recall_mode + tags
                                    ▼
                         ┌──────────┴──────────┐
                         │                     │
                   ┌───────────┐        ┌─────────────┐
                   │   Store   │        │ VectorIndex │  ChromaDB
                   │  depth 0-2│        │ (dual-path) │  summary + trigger
                   └───────────┘        └──────┬──────┘
                                               │ semantic search
                                               ▼
                                         ┌───────────┐
                                         │ Retriever │  RRF fusion
                                         └───────────┘

Dual-Speed Layer

  • Fast (Sensor): SLM extracts entities/intent per turn, detects topic shifts via cognitive load assessment
  • Slow (Compacter): Main LLM structures accumulated L1 buffer into MemoryNode with summary, trigger, recall mode, and topic tags

Dynamic Resolution (depth 0 → 1 → 2)

Depth Content Use Case
0 Summary + Trigger Agent's initial context window
1 + Topic tags + Links Navigation / node selection
2 Full raw data + Links Fact retrieval

Recall Mode

Each memory node is classified by recall_mode at compaction time:

Mode Behavior Examples
passive Always included in context window User identity, persistent preferences
active Retrieved on-demand via semantic search Factual details, decisions, events
both Always in context + searchable via RAG Core constraints with retrievable details

Dual-Path RAG Retrieval

CoMeT embeds both summary (what the node contains) and trigger (when to recall it) into separate vector collections. At query time:

  1. QueryAnalyzer decomposes the query into semantic_query + search_intent
  2. Summary path: matches what the information is about
  3. Trigger path: matches when the information would be needed
  4. ScoreFusion (Reciprocal Rank Fusion): merges results from both paths

Triggers are written from the LLM's perspective ("내가 ~정보가 필요할 때") rather than user-centric, enabling broader semantic matching even without explicit user requests.

Topic-Aware Auto-Linking

Nodes share a global topic tag set. The compacter reuses existing tags when possible, enabling automatic bidirectional linking between related nodes across different conversation segments.

Benchmark (52 turns, 5 conversations, 10 questions)

Method Context Cost Accuracy
Full Context Injection 5,198 chars (100%) 10/10
CoMeT 1,397 chars (27%) 9/10
Naive Summary 1,179 chars (23%) 1/10
  • CoMeT uses 27% of the tokens while retaining 90% accuracy
  • 6/10 questions required link traversal (agent read 2-3 nodes)
  • Cross-topic questions: CoMeT 5/5 vs Naive 0/5

Quick Start

Session Memory (within a conversation)

from comet import CoMeT, scope

@scope
def main(config):
    memo = CoMeT(config)

    # Add conversation turns
    memo.add("B200 4대로 월드모델 학습 가능할까?")
    memo.add("2B면 충분하고 커봐야 8B")
    memo.add("DPO 데이터는 negative를 syntax error로 구성했어")

    # Force compact remaining buffer
    memo.force_compact()

    # Navigation
    for node in memo.list_memories():
        print(memo.read_memory(node['node_id'], depth=0))

    # Agent tools (LangChain compatible)
    tools = memo.get_tools()
    # → get_memory_index, read_memory_node, search_memory

main()

Cross-Session RAG Retrieval

from comet import CoMeT, scope

@scope
def main(config):
    config.retrieval.vector_db_path = './memory_store/vectors'

    memo = CoMeT(config)

    # Ingest turns (auto-indexed to VectorIndex on compaction)
    memo.add("JWT 액세스 토큰 만료는 15분, 리프레시는 7일로 설정")
    memo.force_compact()

    # Semantic retrieval across all sessions
    results = memo.retrieve("토큰 만료 설정이 어떻게 되어있어?")
    for r in results:
        print(f"[{r.node.node_id}] score={r.relevance_score:.4f}")
        print(f"  {r.node.summary}")

    # Agent tools include retrieve_memory when retrieval is configured
    tools = memo.get_tools()
    # → get_memory_index, read_memory_node, search_memory, retrieve_memory

main()

Configuration (ato)

# comet/config.py
@scope.observe(default=True)
def default(config):
    config.slm_model = 'gpt-4o-mini'
    config.main_model = 'gpt-4o'
    config.compacting.load_threshold = 3
    config.compacting.max_l1_buffer = 5

    # RAG retrieval (enabled when retrieval block exists)
    config.retrieval.embedding_model = 'text-embedding-3-small'
    config.retrieval.vector_backend = 'chroma'
    config.retrieval.vector_db_path = './memory_store/vectors'
    config.retrieval.top_k = 5

@scope.observe()
def local_slm(config):
    config.slm_model = 'ollama/gemma3:4b'

@scope.observe()
def aggressive(config):
    config.compacting.load_threshold = 2
    config.compacting.max_l1_buffer = 3
# Use default
python main.py

# Local SLM + aggressive compacting
python main.py local_slm aggressive

Project Structure

comet/
├── orchestrator.py    # CoMeT main class
├── sensor.py          # L1 extraction + cognitive load (SLM)
├── compacter.py       # L1→L2 structuring + auto-linking (LLM)
├── storage.py         # JSON key-value store + navigation
├── schemas.py         # MemoryNode, L1Memory, CognitiveLoad, RetrievalResult
├── config.py          # ato scope configuration
├── vector_index.py    # ChromaDB dual-collection vector store
├── retriever.py       # QueryAnalyzer + ScoreFusion + Retriever
└── templates/
    ├── compacting.txt      # Memory structuring prompt
    └── query_analysis.txt  # Query decomposition prompt

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

comet_memory-0.1.0.tar.gz (36.1 kB view details)

Uploaded Source

Built Distribution

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

comet_memory-0.1.0-py3-none-any.whl (31.6 kB view details)

Uploaded Python 3

File details

Details for the file comet_memory-0.1.0.tar.gz.

File metadata

  • Download URL: comet_memory-0.1.0.tar.gz
  • Upload date:
  • Size: 36.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.9

File hashes

Hashes for comet_memory-0.1.0.tar.gz
Algorithm Hash digest
SHA256 453c0e89ed50d5d85c5c502a0cd67c6ff9e82a0d475612f63b6115b5d10e78a6
MD5 6acedf6c8759b85a176d810e810c3d22
BLAKE2b-256 aa371d85b50a4445147302b8afd0f3cb1dd1179fa681e73b53f4db4b28d683b6

See more details on using hashes here.

File details

Details for the file comet_memory-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: comet_memory-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 31.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.9

File hashes

Hashes for comet_memory-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 75af61c6e82358abef2e85777491abe5e97d7eff5f8d2df239975b8d2e69f90f
MD5 20fc7263f7da8167396b3b0bdd16d093
BLAKE2b-256 53bd7f58ad953b558b46be974ce32a2b0737f0e90f5719e16f13fc4aa9454cba

See more details on using hashes here.

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