Skip to content

About

Distill-first backfill of AI coding-assistant history into a Cognee knowledge graph — local models, resumable, junk-free

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

9 Commits

Folders and files

Repository files navigation

cognee-backfill

Agent memory systems start empty. This gives them a past.

Backfill years of coding-assistant history into durable, local-first memory.
Keep the projects, tasks, investigations, decisions, fixes, workflows, and gotchas. Leave the junk behind.

Python Docker Cognee Local models License

Quick start · How it works · Technical wiki · Connector roadmap


The missing half of agent memory

Agent-memory systems are built to remember what happens next. Mainstream tools capture new conversations after installation, but do not ship a practical end-to-end mechanism for backfilling years of existing coding-assistant history. Your new memory layer starts empty while the decisions and fixes that matter remain trapped in old session databases.

cognee-backfill fills that gap. It converts existing assistant history into a compact Cognee knowledge graph, without blindly embedding every message.

Local first because session history is sensitive

Coding sessions routinely contain source code, filesystem paths, internal URLs, shell output, credentials, customer context, and unfinished ideas. Shipping a multi-gigabyte history through hosted AI APIs sends all of that into big-tech infrastructure with retention, logging, and downstream data practices you may not control.

This pipeline keeps the source database, distillation model, embedding model, graph, vectors, and metadata on your machine by default. Your history does not leave the machine unless you deliberately point the configuration at a remote endpoint.

Each session is distilled locally; only durable knowledge is passed to Cognee for graph extraction, embeddings, and recall.

Current connector: OpenCode SQLite history. The pipeline is designed for additional connectors, including Claude Code, Cursor, Cline, and generic JSONL exports.

How it works

flowchart TB
    subgraph prepare[1. Private source preparation]
        direction LR
        source[(Assistant<br/>history)]
        extract[Read-only<br/>connector]
        scrub[Normalize, bound<br/>and scrub secrets]
        source --> extract --> scrub
    end

    subgraph distill[2. Distill and checkpoint]
        direction LR
        llm[Local LLM<br/>distillation]
        gate{Worth<br/>keeping?}
        notes[(Persisted<br/>Markdown notes)]
        junk[Junk skipped]

        llm --> gate
        gate -->|Yes| notes
        gate -->|No| junk
    end

    subgraph remember[3. Build durable local memory]
        direction LR
        ingest[Idempotent<br/>batched add]
        cognify[One bounded<br/>Cognify run]
        entities[Entities and<br/>relationships]
        vectors[Local<br/>embeddings]
        stores[(Kuzu + LanceDB<br/>+ SQLite)]

        ingest --> cognify --> entities --> vectors --> stores
    end

    recall[Graph and<br/>hybrid recall]

    scrub --> llm
    notes --> ingest
    stores --> recall
Loading

Why distill first?

Cognee preserves chunks and extracts a graph, but extraction is chunk-local. A coding session often spreads its outcome across user prompts, tool calls, failures, retries, and a final response. Distillation creates one coherent session-level document before graph extraction.

An end-to-end comparison on four representative sessions found that direct conversation ingestion was 3.2x slower and answered only 3 of 8 factual checks fully correctly; distilled notes answered all 8. Preserving tool activity made direct ingestion roughly 38x slower. The normalized model input is therefore retained in var/transcripts/ for audit, while the compact note is indexed.

Naive transcript indexing cognee-backfill
Embeds greetings, false starts, and log dumps Keeps decisions, fixes, patterns, and project context
Lets tool output dominate retrieval Bounds every field and samples long sessions intelligently
Stores raw reasoning traces Produces concise, structured knowledge notes
Reprocesses everything after interruption Persists model inputs and notes for lossless resume
Launches one graph job per document Adds in idempotent batches, then runs one bounded Cognify job
Risks sending secrets downstream Scrubs common credentials before the LLM boundary

Quick start

1. Prerequisites

  • Python 3.10+
  • Docker with Compose
  • A local OpenAI-compatible inference server
  • One chat model and one embedding model loaded

Tested with oMLX. Ollama, LM Studio, and vLLM work when their OpenAI-compatible endpoints accept the configured model IDs and request extensions.

2. Start the local stack

git clone https://github.com/thomasmaerz/cognee-backfill.git
cd cognee-backfill

cp .env.example .env
# Edit .env: set LLM_API_KEY and confirm model IDs/endpoints.

docker compose up -d
curl -f http://localhost:8010/health
Service URL
Cognee UI http://localhost:3010
Cognee API http://localhost:8010
Swagger API docs http://localhost:8010/docs

The bundled UI uses the local-development credentials default_user@example.com / default_password. Keep this stack bound to localhost unless you replace that development posture.

3. Inspect and smoke-test the source

export LLM_BASE_URL=http://127.0.0.1:8000
export LLM_API_KEY='your-local-server-key'

python3 backfill.py --stats

# Test only three sessions in an isolated dataset.
python3 backfill.py \
  --limit 3 \
  --dataset kb_smoke \
  --recall "What durable decisions appear in these sessions?"

Review var/transcripts/ and var/distilled/, then delete the smoke dataset before starting the complete run. Cognee content hashes make later re-adds idempotent; local distillation state is not tied to one dataset.

4. Run the resumable backfill

On macOS, install it as a launchd user service. The service starts Cognee, resumes from persisted artifacts, restarts after failures, and exits permanently after a successful backfill:

chmod +x service/*.sh
./service/install-launchd.sh

launchctl print gui/$(id -u)/com.thomasmaerz.cognee-backfill
tail -f var/log/backfill.out.log

Manual and non-macOS execution remains available:

python3 backfill.py --dataset knowledge_base --improve

Stop and restart the service or manual command at any time. Normalized model inputs are persisted to var/transcripts/<session-id>.md; accepted notes are persisted to var/distilled/<session-id>.md; progress.json records only distillation state. Cognee owns content deduplication and processing status.

Every skipped source ID remains in progress.json and in the review-friendly var/skipped.json manifest. Re-evaluate them later with:

python3 backfill.py --dataset knowledge_base --reparse-skipped

5. Enrich and verify

After Cognee reports that all documents completed processing:

python3 backfill.py \
  --dataset knowledge_base \
  --improve \
  --recall \
    "Which authentication decisions were made?" \
    "Which recurring failures have known fixes?"

See the Operations guide for monitoring, backups, cleanup, and verification criteria.

Pipeline guarantees

Guarantee Implementation
Source isolation SQLite is opened with mode=ro; connectors never mutate history
Resume safety Model inputs and notes reach disk before their state becomes distilled
Deterministic chronology Sessions are prepared oldest-first with stable ID tie-breaking
Bounded backend load Batched add is followed by one Cognify run with explicit concurrency
Backend idempotency Cognee content hashes and per-item pipeline status make reruns safe
Conservative junk filtering Work history is retained even without a decision; only empty handshakes, pings, and sessions with no meaningful activity are discarded
Retryable failures Distillation and submission errors remain eligible for retry
Secret defense-in-depth Common keys, tokens, passwords, and private-key markers are redacted
Local-first execution LLM, embeddings, graph, vectors, and metadata can stay on one machine

Local models

The connector and Cognee use the same local OpenAI-compatible server by default, but route their requests independently:

flowchart TB
    connector[Python connector] -->|LLM_BASE_URL| distillModel[Distillation model]
    cognee[Cognee container] -->|LLM_DOCKER_ENDPOINT| graphModel[Structured extraction model]
    cognee -->|LLM_DOCKER_ENDPOINT| embedModel[Embedding model]

    distillModel --> server[Local inference server]
    graphModel --> server
    embedModel --> server
Loading

Reasoning-capable Qwen models require a hard thinking-mode switch for reliable schema output. The connector sends chat_template_kwargs.enable_thinking=false, while Cognee forwards the same setting through LLM_ARGS. Read the thinking-preamble guide before changing model families.

Core configuration

Variable / flag Default Purpose
LLM_BASE_URL http://127.0.0.1:8000 Inference server as seen by the connector
LLM_DOCKER_ENDPOINT http://host.docker.internal:8000/v1 Same server as seen by Cognee
LLM_API_KEY none Local server bearer token
DISTILL_MODEL / --model Qwen3.6-35B-A3B MLX alias Session distillation model
DISABLE_THINKING true Send the Qwen-compatible hard switch
COGNEE_API_URL http://localhost:8010 Cognee API endpoint
OPENCODE_DB ~/.local/share/opencode/opencode.db Read-only OpenCode source
--concurrency 4 Parallel distillation workers
--add-batch-size 100 Documents per idempotent Add request
--data-per-batch 4 Documents Cognee processes concurrently
--chunks-per-batch 12 Chunks per Cognee task batch
--limit, --offset unset Smoke testing and manual sharding
--reparse-skipped off Re-evaluate every session currently classified as junk
--reparse-all off Re-distill every retained session

--reparse-all changes document hashes. Use a new empty dataset, or delete the existing target dataset first, so old and replacement notes cannot coexist.

The complete model, embedding, and structured-output matrix lives in Configuration.

Technology stack

Technology Responsibility
Python Python 3.10+ Dependency-free connector, checkpoint state, and HTTP client
Docker Docker Compose Reproducible Cognee API and web UI
🧠 Cognee Knowledge extraction, enrichment, provenance, and recall
SQLite SQLite OpenCode history and Cognee relational metadata
🕸️ Kuzu Embedded knowledge graph
🧭 LanceDB Embedded vector index
OpenAI-compatible API OpenAI-compatible API Local model transport for chat and embeddings

Connector roadmap

Connector Status Source format
OpenCode ✅ Available session / message / part SQLite tables
Claude Code 🛠 Planned ~/.claude/projects/ JSONL
Cursor / Windsurf 🛠 Planned Agent transcript exports
Cline / Continue 🛠 Planned Extension storage / exports
Generic JSONL 🛠 Planned Normalized external ETL format

Every connector follows the same contract:

extract oldest-first -> normalize, scrub, and persist -> distill -> batched add -> one cognify

See Adding a connector for the interface, fixtures, invariants, and acceptance criteria.

Live capture after the backfill

Historical ingestion and ongoing memory are separate concerns. After the backfill, Cognee's OpenCode plugin can capture new sessions and bridge them into the same dataset:

{
  "plugin": [
    [
      "file:/path/to/cognee-opencode",
      {
        "baseUrl": "http://localhost:8010",
        "datasetName": "knowledge_base"
      }
    ]
  ]
}

Build the plugin from topoteretes/cognee-integrations, then restart OpenCode.

Documentation

Guide Covers
Architecture Data flow, state machine, storage, and failure boundaries
Configuration Models, embeddings, ports, concurrency, and persistence
Operations Smoke tests, launch, monitoring, pause/resume, backup, cleanup
OpenCode connector Source schema, transcript reconstruction, and known limits
Adding a connector Adapter contract and quality gates for future sources
Thinking preamble Safe structured extraction with reasoning-capable models
Security and privacy Source isolation, scrubbing, network boundaries, retention

Security

Session history is sensitive. Keep the inference server, Cognee API, and UI local unless you add authentication, TLS, explicit CORS origins, and firewall controls. Regex scrubbing is defense-in-depth, not a complete DLP system.

Read Security and privacy before processing regulated or organization-confidential data.

License

MIT. See LICENSE. Cognee is licensed separately under Apache-2.0.

About

Distill-first backfill of AI coding-assistant history into a Cognee knowledge graph — local models, resumable, junk-free

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages