# https://github.com/rishimeka/genesys 项目说明书

生成时间：2026-05-15 07:11:52 UTC

## 目录

- [Getting Started with Genesys](#getting-started)
- [System Architecture](#architecture)
- [Memory Scoring Engine](#memory-scoring)
- [Memory Lifecycle Management](#memory-lifecycle)
- [Nodes and Edges Data Models](#nodes-edges)
- [Graph Traversal and Causal Reasoning](#graph-traversal)
- [Storage Backend Comparison](#backends-overview)
- [Storage Provider Implementation](#storage-implementation)
- [MCP Tools Reference](#mcp-tools)
- [Configuration Guide](#configuration)

<a id='getting-started'></a>

## Getting Started with Genesys

### 相关页面

相关主题：[Configuration Guide](#configuration), [Storage Backend Comparison](#backends-overview)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)
- [CONTRIBUTING.md](https://github.com/rishimeka/genesys/blob/main/CONTRIBUTING.md)
- [src/genesys_memory/server.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/server.py)
- [src/genesys_memory/models/node.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/node.py)
- [src/genesys_memory/mcp/tools.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/mcp/tools.py)
- [server.json](https://github.com/rishimeka/genesys/blob/main/server.json)
</details>

# Getting Started with Genesys

## Overview

Genesys is an **intelligence layer for AI memory** — a scoring engine, causal graph, and lifecycle manager for AI agent memory. It provides persistent memory capabilities with intelligent forgetting, ensuring AI systems maintain context across sessions without unbounded memory growth.

The system speaks MCP (Model Context Protocol) natively, making it compatible with Claude Code, Claude Desktop, and any MCP-compatible AI client.

**Key capabilities:**

- Multi-force memory scoring (relevance × connectivity × reactivation)
- Causal graph relationships between memories
- Intelligent forgetting — memories decay and are pruned when irrelevant
- Core memory promotion for structurally important information
- Multiple storage backends (in-memory, Postgres, Obsidian, FalkorDB)
- Hybrid retrieval (vector + keyword + graph spreading activation)

资料来源：[README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

---

## Architecture Overview

Genesys Memory is organized into several core modules:

```
src/genesys_memory/
├── engine/             # Scoring, transitions, forgetting, reactivation
│   ├── config.py       # All tunable thresholds (env-configurable)
│   ├── scoring.py      # Three-force multiplicative decay scoring
│   ├── transitions.py  # Status FSM (ACTIVE -> DORMANT -> FADING -> PRUNED)
│   ├── forgetting.py   # Conjunctive active forgetting
│   └── reactivation.py # BFS cascade reactivation
├── core_memory/        # Core promotion logic (graph-derived)
├── storage/            # Storage provider abstractions + implementations
│   ├── base.py         # Abstract interfaces (GraphStorageProvider, etc.)
│   └── memory.py       # In-memory implementation
└── mcp/                # MCP protocol tools and server
    └── tools.py        # MCP tool implementations
```

资料来源：[CONTRIBUTING.md](https://github.com/rishimeka/genesys/blob/main/CONTRIBUTING.md)

### Memory Lifecycle State Machine

Memories progress through defined states with configurable transitions:

```mermaid
graph LR
    STORE[STORE] --> ACTIVE[ACTIVE]
    ACTIVE --> DORMANT[DORMANT]
    DORMANT --> FADING[FADING]
    FADING --> PRUNED[PRUNED]
    ACTIVE -->|reactivation| ACTIVE
    DORMANT -->|reactivation| ACTIVE
    FADING -->|reactivation| DORMANT
    
    style PRUNED fill:#ff6b6b
    style ACTIVE fill:#51cf66
    style DORMANT fill:#fcc419
```

### Memory Scoring Formula

Every memory is scored by three forces multiplied together:

```
decay_score = relevance × connectivity × reactivation
```

| Force | Description |
|-------|-------------|
| **Relevance** | Decays over time. Old memories fade unless reinforced. |
| **Connectivity** | Rewards memories with many causal links. Hub memories survive. |
| **Reactivation** | Boosts memories that keep getting recalled. Frequency matters. |

Because the formula is multiplicative, a memory must score on **all three axes** to survive. A highly connected but never-accessed memory still decays.

资料来源：[README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

---

## Installation

### Prerequisites

- Python 3.11+
- pip or uv package manager

### Package Installation

Genesys Memory is published as `genesys-memory` on PyPI:

```bash
pip install genesys-memory
```

### Backend-Specific Installation

Depending on your chosen storage backend, install with additional dependencies:

| Backend | Install Command |
|---------|-----------------|
| In-memory (default) | `pip install genesys-memory` |
| Postgres + pgvector | `pip install 'genesys-memory[postgres]'` |
| Obsidian Vault | `pip install 'genesys-memory[obsidian]'` |
| FalkorDB | `pip install 'genesys-memory[falkordb]'` |
| Local embeddings (no API key) | `pip install 'genesys-memory[local]'` |

### Full Installation with All Backends

```bash
pip install 'genesys-memory[postgres,obsidian,local]'
```

### Development Installation

```bash
git clone https://github.com/rishimeka/genesys.git
cd genesys
pip install -e '.[dev]'
```

资料来源：[README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

---

## Configuration

### Environment Variables

Copy the example configuration:

```bash
cp .env.example .env
```

Configure the following variables based on your setup:

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `OPENAI_API_KEY` | Unless `GENESYS_EMBEDDER=local` | — | OpenAI API key for embeddings |
| `ANTHROPIC_API_KEY` | No | — | Anthropic API key for LLM memory processing |
| `GENESYS_BACKEND` | No | `memory` | Storage backend: `memory`, `postgres`, `obsidian`, `falkordb` |
| `GENESYS_EMBEDDER` | No | `openai` | Embedding provider: `openai` or `local` |
| `DATABASE_URL` | If postgres | — | Postgres connection string |
| `OBSIDIAN_VAULT_PATH` | If obsidian | — | Path to your Obsidian vault |
| `FALKORDB_HOST` | If falkordb | `localhost` | FalkorDB host |
| `GENESYS_USER_ID` | No | — | Default user ID for single-tenant mode |
| `GENESYS_PERSIST_PATH` | No | — | Path for state persistence (e.g., `.genesys_state.json`) |

资料来源：[README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

### Storage Backends

| Backend | Use Case | Dependencies |
|---------|----------|--------------|
| `memory` | Zero deps, try it out | Built-in |
| `postgres` + pgvector | Persistent, scalable | Postgres + Docker |
| `obsidian` | Local-first knowledge base | Obsidian vault |
| `falkordb` | Graph-native traversal | FalkorDB (Redis-based) |

---

## Quick Start: In-Memory Backend

The in-memory backend requires no external services — ideal for testing and development.

### 1. Create Configuration

```bash
cp .env.example .env
```

Edit `.env`:

```env
OPENAI_API_KEY=sk-...
GENESYS_BACKEND=memory
```

### 2. Start the Server

```bash
uvicorn genesys.api:app --port 8000
```

### 3. Persist State (Optional)

To persist memory across restarts:

```env
GENESYS_PERSIST_PATH=.genesys_state.json
```

资料来源：[README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

---

## Option 1: Postgres + pgvector (Production)

For persistent, scalable storage with vector search capabilities.

### 1. Install Dependencies

```bash
pip install 'genesys-memory[postgres]'
```

### 2. Configure Environment

```env
OPENAI_API_KEY=sk-...
GENESYS_BACKEND=postgres
DATABASE_URL=postgresql://genesys:genesys@localhost:5432/genesys
```

### 3. Start Infrastructure

```bash
docker compose up -d postgres
alembic upgrade head
```

### 4. Start the Server

```bash
GENESYS_BACKEND=postgres uvicorn genesys.api:app --port 8000
```

> **Give this to Claude to set it up for you:**
> *"Install genesys-memory[postgres], start a Postgres container with pgvector using docker compose, run alembic migrations, create a .env with my OpenAI key and DATABASE_URL, start the server with GENESYS_BACKEND=postgres, and connect it as an MCP server."*

资料来源：[README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

---

## Option 2: Obsidian Vault (Local-First)

Turn your Obsidian vault into a Genesys memory store. Markdown files become memory nodes, `[[wikilinks]]` become causal edges.

### 1. Install Dependencies

```bash
pip install 'genesys-memory[obsidian]'
```

### 2. Configure Environment

```env
OPENAI_API_KEY=sk-...
GENESYS_BACKEND=obsidian
OBSIDIAN_VAULT_PATH=/path/to/your/vault
```

> If `OBSIDIAN_VAULT_PATH` is not set, Genesys auto-detects by looking for `.obsidian/` in `~/Documents/personal`, `~/Documents/Obsidian`, and `~/obsidian`.

### 3. Start the Server

```bash
uvicorn genesys.api:app --port 8000
```

On first start, Genesys indexes all `.md` files in the vault and generates embeddings. A file watcher re-indexes incrementally when you edit notes.

### 4. Fully Local (No API Keys)

For zero external dependencies, use local embeddings:

```bash
pip install 'genesys-memory[obsidian,local]'
```

```env
GENESYS_BACKEND=obsidian
GENESYS_EMBEDDER=local
OBSIDIAN_VAULT_PATH=/path/to/your/vault
# No OPENAI_API_KEY needed
```

This uses `all-MiniLM-L6-v2` (384-dim) via `sentence-transformers` for embeddings. The model is downloaded on first use (~80 MB).

> **Give this to Claude to set it up for you:**
> *"Install genesys-memory[obsidian,local], create a .env with GENESYS_BACKEND=obsidian, GENESYS_EMBEDDER=local, and OBSIDIAN_VAULT_PATH to my vault at [YOUR_VAULT_PATH], start the server on port 8000, and connect it as an MCP server. No API keys needed."*

资料来源：[README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

---

## Option 3: FalkorDB (Graph-Native)

Uses FalkorDB (Redis-based graph database) for native graph traversal.

### 1. Install Dependencies

```bash
pip install 'genesys-memory[falkordb]'
```

### 2. Configure Environment

```env
OPENAI_API_KEY=sk-...
GENESYS_BACKEND=falkordb
FALKORDB_HOST=localhost
```

### 3. Start Infrastructure

```bash
docker compose up -d falkordb
```

### 4. Start the Server

```bash
uvicorn genesys.api:app --port 8000
```

> **Give this to Claude to set it up for you:**
> *"Install genesys-memory[falkordb], start a FalkorDB container using docker compose, create a .env with my OpenAI key and GENESYS_BACKEND=falkordb, start the server on port 8000, and connect it as an MCP server."*

资料来源：[README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

---

## Connecting to AI Clients

### Claude Code

```bash
claude mcp add --transport http genesys http://localhost:8000/mcp
```

### Claude Desktop

Add to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "genesys": {
      "url": "http://localhost:8000/mcp"
    }
  }
}
```

### Any MCP Client

Point your client at the MCP endpoint:

```
http://localhost:8000/mcp
```

资料来源：[README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

---

## MCP Tools Reference

Genesys provides the following MCP tools for memory operations:

| Tool | Description |
|------|-------------|
| `memory_store` | Store a new memory, optionally linking to related memories |
| `memory_recall` | Recall memories by natural language query (vector + graph) |
| `memory_search` | Search memories with filters (status, date range, keyword) |
| `memory_traverse` | Walk the causal graph from a given memory node |
| `memory_explain` | Explain why a memory exists and its causal chain |
| `memory_stats` | Get memory system statistics |
| `pin_memory` | Pin a memory so it's never forgotten |
| `unpin_memory` | Unpin a previously pinned memory |
| `delete_memory` | Permanently delete a memory |
| `list_core_memories` | List core memories, optionally filtered by category |
| `set_core_preferences` | Set user preferences for core memory categories |

### Tool Schemas

#### memory_store

```json
{
  "name": "memory_store",
  "description": "Store a new memory node",
  "inputSchema": {
    "type": "object",
    "required": ["content"],
    "properties": {
      "content": {"type": "string"},
      "related_to": {"type": "array", "items": {"type": "string"}},
      "category": {"type": "string"}
    }
  }
}
```

#### memory_recall

```json
{
  "name": "memory_recall",
  "description": "Recall memories using hybrid search (vector + keyword + graph spreading activation)",
  "inputSchema": {
    "type": "object",
    "required": ["query"],
    "properties": {
      "query": {"type": "string"},
      "k": {"type": "integer", "default": 10},
      "max_results": {"type": "integer"}
    }
  }
}
```

#### memory_search

```json
{
  "name": "memory_search",
  "description": "Filtered vector search by status, category, date, or entity",
  "inputSchema": {
    "type": "object",
    "required": ["query"],
    "properties": {
      "query": {"type": "string"},
      "filters": {"type": "object"},
      "k": {"type": "integer", "default": 10}
    }
  }
}
```

#### memory_traverse

```json
{
  "name": "memory_traverse",
  "description": "Traverse the memory graph from a starting node",
  "inputSchema": {
    "type": "object",
    "required": ["node_id"],
    "properties": {
      "node_id": {"type": "string"},
      "depth": {"type": "integer", "default": 2},
      "edge_types": {"type": "array", "items": {"type": "string"}}
    }
  }
}
```

#### memory_explain

```json
{
  "name": "memory_explain",
  "description": "Explain a memory's score breakdown",
  "inputSchema": {
    "type": "object",
    "required": ["node_id"],
    "properties": {
      "node_id": {"type": "string"}
    }
  }
}
```

资料来源：[src/genesys_memory/server.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/server.py)

---

## Memory Node Data Model

Each memory is represented as a `MemoryNode` with the following structure:

```python
class MemoryNode(BaseModel):
    id: uuid.UUID = Field(default_factory=uuid.uuid4)
    status: MemoryStatus = MemoryStatus.ACTIVE
    
    # Content
    content_summary: str = Field(max_length=200)
    content_full: str | None = None
    content_ref: str | None = None
    embedding: list[float] | None = None
    
    # Timestamps
    created_at: datetime
    last_accessed_at: datetime
    last_reactivated_at: datetime
    
    # Lifecycle scores
    decay_score: float = 1.0
    causal_weight: int = 0
    reactivation_count: int = 0
    reactivation_pattern: ReactivationPattern
    irrelevance_counter: int = 0
    
    # Provenance
    source_agent: str = "claude"
    source_session: str = ""
    
    # Classification
    entity_refs: list[str] = Field(default_factory=list)
    category: str | None = None
    
    # Stability
    stability: float = 1.0
    
    # Core memory
    pinned: bool = False
    promotion_reason: str | None = None
    
    # Reactivation history
    reactivation_timestamps: list[datetime] = Field(default_factory=list)
```

资料来源：[src/genesys_memory/models/node.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/node.py)

---

## Memory Retrieval Flow

The recall operation uses a hybrid approach combining vector similarity, keyword matching, and graph spreading activation:

```mermaid
graph TD
    Query[User Query] --> Embed[Generate Embedding]
    Embed --> VectorSearch[Vector Similarity Search]
    Query --> KeywordSearch[Keyword Search]
    VectorSearch --> Combine[Hybrid Ranking]
    KeywordSearch --> Combine
    Combine --> GraphSpread[Graph Spreading Activation]
    GraphSpread --> Results[Ranked Memories]
```

资料来源：[src/genesys_memory/server.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/server.py)

---

## Development and Testing

### Code Style

- **Python 3.11+**, async-first
- **Linting**: `ruff check src/` (config in `pyproject.toml`, line length 120)
- **Type checking**: `mypy src/genesys_memory --ignore-missing-imports`
- **Formatting**: Type hints throughout, minimal comments

### Running Tests

```bash
# Run all unit tests
pytest tests/ -v

# With coverage
pytest tests/ -v --cov=src/genesys_memory --cov-report=term-missing
```

Tests are in `tests/` and use `pytest-asyncio` (auto mode).

资料来源：[CONTRIBUTING.md](https://github.com/rishimeka/genesys/blob/main/CONTRIBUTING.md)

---

## Security

Genesys follows a responsible disclosure policy for security vulnerabilities:

| Version | Supported |
|---------|-----------|
| 0.3.x   | Yes       |
| < 0.3   | No        |

To report a security vulnerability, use [GitHub's security advisory feature](https://github.com/rishimeka/genesys/security/advisories/new). **Do not open a public issue.**

资料来源：[SECURITY.md](https://github.com/rishimeka/genesys/blob/main/SECURITY.md)

---

## License

Genesys is open source under the [GNU Affero General Public License v3.0](LICENSE).

> **Note:** Genesys releases prior to v0.3.6 were documented as Apache 2.0 in error. The LICENSE file has always contained the AGPLv3 text. From v0.3.6 onward, all documentation correctly references AGPL-3.0-or-later with a Contributor License Agreement.

资料来源：[README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

---

## Contributing

Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. Look for issues labeled `good first issue` for scoped, well-defined tasks suitable for new contributors.

All contributors must agree to the [Contributor License Agreement](CLA.md) before their code can be merged.

资料来源：[CONTRIBUTING.md](https://github.com/rishimeka/genesys/blob/main/CONTRIBUTING.md)

---

<a id='architecture'></a>

## System Architecture

### 相关页面

相关主题：[Memory Scoring Engine](#memory-scoring), [Memory Lifecycle Management](#memory-lifecycle), [Nodes and Edges Data Models](#nodes-edges)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/genesys_memory/__init__.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/__init__.py)
- [src/genesys_memory/server.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/server.py)
- [src/genesys_memory/engine/__init__.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/__init__.py)
- [src/genesys_memory/storage/__init__.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/storage/__init__.py)
- [src/genesys_memory/engine/llm_provider.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/llm_provider.py)
- [src/genesys_memory/models/node.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/node.py)
- [src/genesys_memory/mcp/tools.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/mcp/tools.py)
- [server.json](https://github.com/rishimeka/genesys/blob/main/server.json)
</details>

# System Architecture

## Overview

Genesys is a scoring engine, causal graph, and lifecycle manager for AI agent memory. It implements a sophisticated memory management system that enables AI agents to store, retrieve, and intelligently forget information over time. The system speaks MCP (Model Context Protocol) natively, allowing seamless integration with Claude Desktop and Claude Code.

**资料来源：** [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

## High-Level Architecture

The Genesys system is organized into several interconnected layers:

```mermaid
graph TB
    subgraph "Client Layer"
        ClaudeDesktop["Claude Desktop"]
        ClaudeCode["Claude Code"]
        MCPSDK["MCP SDK"]
    end
    
    subgraph "API Layer"
        Server["MCP Server (stdio)"]
        Tools["MCP Tools"]
    end
    
    subgraph "Core Engine"
        Scoring["Scoring Engine"]
        Lifecycle["Lifecycle Manager"]
        LLMProvider["LLM Provider"]
    end
    
    subgraph "Storage Layer"
        MemoryBackend["In-Memory"]
        Postgres["Postgres + pgvector"]
        Obsidian["Obsidian Vault"]
        FalkorDB["FalkorDB"]
    end
    
    ClaudeDesktop & ClaudeCode --> MCPSDK
    MCPSDK --> Server
    Server --> Tools
    Tools --> Scoring
    Scoring --> Lifecycle
    Scoring --> LLMProvider
    Lifecycle --> MemoryBackend & Postgres & Obsidian & FalkorDB
```

**资料来源：** [server.json:1-30](https://github.com/rishimeka/genesys/blob/main/server.json) | [src/genesys_memory/server.py:1-20](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/server.py)

## Component Architecture

### MCP Server Layer

The MCP Server is the primary interface for client applications. It uses stdio transport for communication, making it suitable for desktop integration.

| Component | Description | Source |
|-----------|-------------|--------|
| `app` | Main MCP Server instance | [server.py:20](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/server.py) |
| `providers` | Storage and tool providers | [server.py:24](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/server.py) |
| `_TOOL_DISPATCH` | Tool method routing table | [server.py:30-45](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/server.py) |

The server initializes providers and tools via `get_providers()`:

```python
providers = get_providers()
tools = providers.tools
```

**资料来源：** [src/genesys_memory/server.py:23-27](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/server.py)

### MCP Tools Interface

The MCP protocol exposes a set of tools that provide the primary interface for memory operations:

| Tool | Description | Required Args |
|------|-------------|---------------|
| `memory_store` | Store a new memory with optional causal links | `content` |
| `memory_recall` | Hybrid search using vector + keyword + graph | `query` |
| `memory_search` | Filtered search by status, category, date | `query` |
| `memory_traverse` | Graph traversal from a starting node | `node_id` |
| `memory_explain` | Explain memory score breakdown | `node_id` |
| `memory_stats` | Get graph statistics | none |
| `pin_memory` | Pin memory to core status | `node_id` |
| `unpin_memory` | Unpin and re-evaluate | `node_id` |
| `delete_memory` | Permanently delete memory | `node_id` |
| `list_core_memories` | List core memories by category | `category` (optional) |
| `set_core_preferences` | Configure core memory categories | `auto`, `approval`, `excluded` |

**资料来源：** [src/genesys_memory/server.py:7-80](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/server.py) | [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

### Storage Layer

Genesys supports multiple storage backends through a provider abstraction:

```mermaid
graph LR
    subgraph "Storage Providers"
        Memory["MemoryProvider"]
        Postgres["PostgresProvider"]
        Obsidian["ObsidianProvider"]
        FalkorDB["FalkorDBProvider"]
    end
    
    subgraph "Capabilities"
        Cache["CacheProvider"]
        Embedding["EmbeddingProvider"]
        EventBus["EventBusProvider"]
        Graph["GraphStorageProvider"]
    end
    
    Memory & Postgres & Obsidian & FalkorDB --> Cache
    Memory & Postgres & Obsidian & FalkorDB --> Embedding
    Memory & Postgres & Obsidian & FalkorDB --> Graph
    Memory & Postgres & Obsidian & FalkorDB --> EventBus
```

#### Backend Comparison

| Backend | Install | Use Case | Scalability |
|---------|---------|----------|-------------|
| `memory` | Built-in | Zero deps, try it out | Low |
| `postgres` + pgvector | `genesys-memory[postgres]` | Persistent, scalable | High |
| Obsidian vault | `genesys-memory[obsidian]` | Local-first knowledge base | Medium |
| FalkorDB | `genesys-memory[falkordb]` | Graph-native traversal | High |

#### Configuration Options

| Variable | Required | Description |
|----------|----------|-------------|
| `OPENAI_API_KEY` | Unless `GENESYS_EMBEDDER=local` | Embeddings provider |
| `ANTHROPIC_API_KEY` | No | LLM memory processing |
| `GENESYS_BACKEND` | No | `memory`, `postgres`, `obsidian`, `falkordb` |
| `GENESYS_EMBEDDER` | No | `openai` or `local` (sentence-transformers) |
| `DATABASE_URL` | If postgres | Postgres connection string |
| `OBSIDIAN_VAULT_PATH` | If obsidian | Path to Obsidian vault |
| `FALKORDB_HOST` | If falkordb | FalkorDB host (default: `localhost`) |

**资料来源：** [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

## Data Models

### MemoryNode

The `MemoryNode` is the core data structure representing a single memory:

```python
class MemoryNode(BaseModel):
    id: uuid.UUID = Field(default_factory=uuid.uuid4)
    status: MemoryStatus = MemoryStatus.ACTIVE
    content_summary: str = Field(max_length=200)
    content_full: str | None = None
    content_ref: str | None = None
    embedding: list[float] | None = None
    
    # Timestamps
    created_at: datetime
    last_accessed_at: datetime
    last_reactivated_at: datetime
    
    # Lifecycle scores
    decay_score: float = 1.0
    causal_weight: int = 0
    reactivation_count: int = 0
    reactivation_pattern: ReactivationPattern
    irrelevance_counter: int = 0
    
    # Stability (spaced repetition)
    stability: float = 1.0
    
    # Core memory
    pinned: bool = False
    promotion_reason: str | None = None
```

**资料来源：** [src/genesys_memory/models/node.py:6-40](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/node.py)

### MemoryEdge

Relationships between memories are represented as edges with metadata:

| Field | Type | Description |
|-------|------|-------------|
| `edge_type` | `EdgeType` | `caused_by`, `supports`, `derived_from` |
| `confidence` | `float` | 0.0 to 1.0 |
| `reason` | `str` | Explanation of relationship |

**资料来源：** [src/genesys_memory/engine/llm_provider.py:1-30](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/llm_provider.py)

## Scoring Engine

### Memory Scoring Formula

Every memory is scored by three forces multiplied together:

```
decay_score = relevance × connectivity × reactivation
```

- **Relevance**: Decays over time. Old memories fade unless reinforced
- **Connectivity**: Rewards memories with many causal links (hub memories survive)
- **Reactivation**: Boosts frequently accessed memories

Because the formula is multiplicative, a memory must score on **all three axes** to survive. A highly connected but never-accessed memory still decays.

**资料来源：** [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

### LLM Provider for Causal Relationships

The LLM Provider identifies causal relationships between new memories and existing ones:

```mermaid
graph LR
    NewMemory["New Memory"] --> LLMPrompt["LLM Prompt"]
    ExistingMemories["Existing Memories"] --> LLMPrompt
    LLMPrompt --> LLM["LLM API"]
    LLM --> Relationships["Causal Edges<br/>confidence > 0.6"]
```

The LLM processes:
- `target_id`: ID of the existing memory
- `edge_type`: `caused_by`, `supports`, or `derived_from`
- `confidence`: 0.0 to 1.0
- `reason`: Brief explanation

**资料来源：** [src/genesys_memory/engine/llm_provider.py:10-30](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/llm_provider.py)

## Memory Lifecycle

### State Machine

```mermaid
graph LR
    STORE["STORE"] --> ACTIVE["ACTIVE"]
    ACTIVE --> DORMANT["DORMANT"]
    DORMANT --> FADING["FADING"]
    FADING --> PRUNED["PRUNED"]
    
    ACTIVE -.->|reactivation| ACTIVE
    DORMANT -.->|reactivation| ACTIVE
    FADING -.->|reactivation| ACTIVE
    
    PRUNED -.->|never| REAPPEAR["REAPPEAR"]
```

### Lifecycle Rules

| State | Description | Transition Condition |
|-------|-------------|---------------------|
| `STORE` | Newly created memory | Initial state |
| `ACTIVE` | Frequently accessed, high score | Score > threshold |
| `DORMANT` | Low access, moderate decay | Score declining |
| `FADING` | Near-zero score | Score approaching 0 |
| `PRUNED` | Permanently deleted | Score = 0, orphan, not pinned |

### Core Memory Promotion

Memories can be promoted to **core** status — structurally important memories that are:
- Auto-pinned on promotion
- Never pruned automatically
- Assigned a `promotion_reason`

**资料来源：** [src/genesys_memory/models/node.py:35-38](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/node.py) | [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

## Authentication & Authorization

### Multi-User Mode

The system supports multi-user operation with organization-level access control:

```python
def _caller_owns_node(node: MemoryNode) -> bool:
    uid = _caller_uid()
    if uid is None:
        raise PermissionError("current_user_id not set")
    role = current_user_role.get(None)
    if role == "admin" and node.org_id in current_org_ids.get([]):
        return True
    return node.original_user_id == uid
```

**资料来源：** [src/genesys_memory/mcp/tools.py:20-35](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/mcp/tools.py)

### Visibility Levels

| Level | Description | Access |
|-------|-------------|--------|
| `private` | User-only | Owner only |
| `org` | Organization-wide | Org members |
| `public` | All users | Read access |

**资料来源：** [src/genesys_memory/models/enums.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/enums.py)

## Tool Dispatch Architecture

The tool dispatch system maps MCP tool names to internal methods:

```python
_TOOL_DISPATCH: dict[str, tuple[Any, ...]] = {
    "memory_store": (tools.memory_store, ["content"], {"source_session": "", "related_to": None, "visibility": "private", "org_id": None}),
    "memory_recall": (tools.memory_recall, ["query"], {"k": 10, "max_results": None}),
    "memory_search": (tools.memory_search, ["query"], {"filters": None, "k": 10}),
    "memory_traverse": (tools.memory_traverse, ["node_id"], {"depth": 2, "edge_types": None}),
    "memory_explain": (tools.memory_explain, ["node_id"], {}),
    "pin_memory": (tools.pin_memory, ["node_id"], {}),
    "unpin_memory": (tools.unpin_memory, ["node_id"], {}),
    "list_core_memories": (tools.list_core_memories, [], {"category": None}),
    "delete_memory": (tools.delete_memory, ["node_id"], {}),
    "memory_stats": (tools.memory_stats, [], {}),
    "set_core_preferences": (tools.set_core_preferences, [], {}),
}
```

Each entry contains:
1. The method to call
2. Required argument names
3. Optional arguments with default values

**资料来源：** [src/genesys_memory/server.py:30-45](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/server.py)

## Deployment Topologies

### Development Mode (In-Memory)

```bash
pip install genesys-memory
cp .env.example .env
uvicorn genesys.api:app --port 8000
```

Suitable for local development with zero infrastructure.

### Production Mode (Postgres)

```bash
pip install 'genesys-memory[postgres]'
docker compose up -d postgres
alembic upgrade head
GENESYS_BACKEND=postgres uvicorn genesys.api:app --port 8000
```

### Claude Desktop Integration

```json
{
  "mcpServers": {
    "genesys": {
      "url": "http://localhost:8000/mcp"
    }
  }
}
```

**资料来源：** [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

## Performance Characteristics

### Benchmark Results (LoCoMo Benchmark)

| Category | J-Score |
|----------|---------|
| Single-hop | 94.3% |
| Temporal | 87.5% |
| Multi-hop | 69.8% |
| Open-domain | 91.7% |
| **Overall** | **89.9%** |

Compared to alternatives:
- Mem0: 67.1%
- Zep: 75.1%

**资料来源：** [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

## Dependencies

### Core Requirements

| Package | Purpose |
|---------|---------|
| `mcp` | Model Context Protocol server |
| `pydantic` | Data validation |
| `fastapi` | API framework |
| `uvicorn` | ASGI server |

### Optional Dependencies

| Extra | Packages |
|-------|----------|
| `postgres` | `psycopg2-binary`, `alembic`, `asyncpg` |
| `obsidian` | `python-dotenv` |
| `local` | `sentence-transformers` |

**资料来源：** [CONTRIBUTING.md](https://github.com/rishimeka/genesys/blob/main/CONTRIBUTING.md) | [server.json](https://github.com/rishimeka/genesys/blob/main/server.json)

---

<a id='memory-scoring'></a>

## Memory Scoring Engine

### 相关页面

相关主题：[Memory Lifecycle Management](#memory-lifecycle)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/genesys_memory/models/node.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/node.py)
- [src/genesys_memory/engine/transitions.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/transitions.py)
- [src/genesys_memory/engine/llm_provider.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/llm_provider.py)
- [src/genesys_memory/engine/config.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/config.py)
- [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)
</details>

# Memory Scoring Engine

## Overview

The Memory Scoring Engine is the core intelligence layer of Genesys that determines which memories survive, decay, or get promoted to core status. It implements a multiplicative scoring formula that evaluates memories across three dimensions: relevance, connectivity, and reactivation frequency.

```
decay_score = relevance × connectivity × reactivation
```

资料来源：[README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

## Architecture

### Core Components

The scoring engine consists of several interconnected modules:

| Component | File | Purpose |
|-----------|------|---------|
| Scoring Calculator | `engine/scoring.py` | Computes the decay score for each memory node |
| Configuration | `engine/config.py` | Defines thresholds and env-configurable parameters |
| Reactivation Handler | `engine/reactivation.py` | Tracks and updates memory access patterns |
| Transition Engine | `engine/transitions.py` | Evaluates and executes state transitions |
| LLM Provider | `engine/llm_provider.py` | LLM-based consolidation and contradiction detection |

资料来源：[engine/transitions.py:1-15](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/transitions.py)

### Scoring Formula

The decay score is calculated as the product of three independent factors:

```mermaid
graph TD
    A[Memory Node] --> B[Relevance Score]
    A --> C[Connectivity Score]
    A --> D[Reactivation Score]
    B --> E[decay_score]
    C --> E
    D --> E
    E --> F{decay_score > threshold?}
```

1. **Relevance**: Decays over time. Old memories fade unless reinforced through recall or context reactivation.
2. **Connectivity**: Rewards memories with many causal links. Hub memories (highly connected nodes) survive longer.
3. **Reactivation**: Boosts memories that are repeatedly accessed. Frequency of recall matters.

资料来源：[README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

### Multiplicative Nature

Because the formula is multiplicative, a memory must score on **all three** axes to survive:

| Scenario | Relevance | Connectivity | Reactivation | Result |
|----------|-----------|--------------|--------------|--------|
| High connections, never accessed | ✓ | ✓ | ✗ | Memory decays |
| Frequently recalled, no links | ✓ | ✗ | ✓ | Memory fades |
| Old but connected and active | ✗ | ✓ | ✓ | May survive |

资料来源：[README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

## Memory Node Data Model

Each memory node stores scoring-related metrics:

```python
class MemoryNode(BaseModel):
    # Lifecycle scores
    decay_score: float = 1.0
    causal_weight: int = 0
    reactivation_count: int = 0
    reactivation_pattern: ReactivationPattern = ReactivationPattern.SINGLE
    irrelevance_counter: int = 0
    
    # Stability (increases on successful retrieval, per spaced repetition)
    stability: float = 1.0
    
    # Timestamps
    created_at: datetime
    last_accessed_at: datetime
    last_reactivated_at: datetime
    
    # Core memory flags
    pinned: bool = False
    promotion_reason: str | None = None
```

资料来源：[src/genesys_memory/models/node.py:20-40](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/node.py)

### Scoring Fields

| Field | Type | Description |
|-------|------|-------------|
| `decay_score` | `float` | Combined score (0.0 to 1.0), product of all factors |
| `causal_weight` | `int` | Number of incoming/outgoing causal edges |
| `reactivation_count` | `int` | Total times memory was successfully recalled |
| `reactivation_pattern` | `ReactivationPattern` | Pattern type: SINGLE, SPIKE, or CONSOLIDATED |
| `irrelevance_counter` | `int` | Consecutive failed relevance matches |
| `stability` | `float` | Retrieval success rate (spaced repetition factor) |
| `pinned` | `bool` | If True, memory is exempt from pruning |

资料来源：[src/genesys_memory/models/node.py:25-45](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/node.py)

## State Transitions

### Lifecycle States

```mermaid
stateDiagram-v2
    [*] --> STORE: Store new memory
    STORE --> ACTIVE: Edge formed (consolidation)
    ACTIVE --> DORMANT: Low reactivation
    DORMANT --> ACTIVE: Reactivation
    DORMANT --> FADING: Extended inactivity
    FADING --> ACTIVE: Reactivation
    FADING --> PRUNED: Score reaches 0 OR orphaned
    ACTIVE --> CORE: Promotion evaluation
    CORE --> [*]: Manual unpin
```

### Transition Evaluation

The transition engine evaluates all non-core, non-pruned nodes:

```python
async def evaluate_transitions(
    graph: GraphStorageProvider,
    embeddings: EmbeddingProvider,
    llm: LLMProvider,
    context_embedding: list[float] | None = None,
    context_entities: list[str] | None = None,
) -> list[dict[str, Any]]:
```

资料来源：[src/genesys_memory/engine/transitions.py:15-23](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/transitions.py)

### Transition Rules

| From State | To State | Trigger Condition |
|------------|----------|-------------------|
| TAGGED | ACTIVE | Node has edges (consolidation signal) |
| ACTIVE | DORMANT | Low reactivation + relevance drops |
| DORMANT | ACTIVE | Successful reactivation recall |
| DORMANT | FADING | Extended inactivity period |
| FADING | PRUNED | `decay_score = 0` or orphaned + not pinned |

资料来源：[src/genesys_memory/engine/transitions.py:25-40](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/transitions.py)

### Tagged Memory Expiration

Tagged memories auto-expire after 24 hours if no connections form:

```python
# Auto-expire tagged memories after 24h with no connections
age_hours = (datetime.now(timezone.utc) - node.created_at).total_seconds() / 3600
```

资料来源：[src/genesys_memory/engine/transitions.py:40-41](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/transitions.py)

## Reactivation Patterns

Reactivation tracks how memories are accessed over time:

| Pattern | Description | Effect on Score |
|---------|-------------|-----------------|
| `SINGLE` | Single retrieval event | Baseline reactivation boost |
| `SPIKE` | Burst of retrievals | Stronger boost, may indicate importance |
| `CONSOLIDATED` | Regular spaced retrieval | Maximum stability increase |

资料来源：[src/genesys_memory/models/node.py:30](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/node.py)

## Core Memory Promotion

Memories can be promoted to **core status** — structurally important memories that are:
- Auto-pinned on promotion
- Never pruned
- Automatically identified based on graph centrality

```mermaid
graph LR
    A[High Causal Weight] --> B{Evaluate Core<br/>Promotion}
    C[Category Match] --> B
    D[User Annotation] --> B
    B --> E[Pin Memory]
    E --> F[Mark as Core]
```

Memories eligible for core promotion must:
1. Have high causal weight (hub nodes)
2. Match configured category patterns
3. Not be manually excluded

资料来源：[src/genesys_memory/mcp/tools.py:35-45](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/mcp/tools.py)

## Configuration

Engine thresholds are environment-configurable and should not be hardcoded:

| Parameter | Source | Default | Description |
|-----------|--------|---------|-------------|
| Decay rates | `engine/config.py` | Environment | Time-based relevance decay |
| Causal thresholds | `engine/config.py` | Environment | Min connections for hub status |
| Reactivation boost | `engine/config.py` | Environment | Multiplier for recall events |

资料来源：[CONTRIBUTING.md](https://github.com/rishimeka/genesys/blob/main/CONTRIBUTING.md)

## LLM Integration

The scoring engine uses LLM providers for advanced operations:

### Consolidation

Combines episodic memories into coherent summaries:

```python
async def consolidate(self, episodic_memories: list[str]) -> str:
    memories_text = "\n".join(f"- {m}" for m in episodic_memories)
    # LLM generates consolidated summary
```

资料来源：[src/genesys_memory/engine/llm_provider.py:45-50](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/llm_provider.py)

### Causal Link Detection

Automatically identifies relationships between memories:

```python
async def identify_causal_relationships(
    new_memory: str,
    existing_memories: list[tuple[str, str]]
) -> list[tuple[str, EdgeType, float, str | None]]:
```

Edge types detected:
- `caused_by` — Causal dependency
- `supports` — Supporting evidence
- `derived_from` — Extracted from source

资料来源：[src/genesys_memory/engine/llm_provider.py:15-35](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/llm_provider.py)

### Confidence Threshold

Only relationships with confidence > 0.6 are included:

```
"Only include relationships with confidence > 0.6."
```

资料来源：[src/genesys_memory/engine/llm_provider.py:25](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/llm_provider.py)

## MCP Tools for Scoring

| Tool | Function | Scoring Impact |
|------|----------|----------------|
| `memory_recall` | Hybrid search (vector + keyword + graph) | Updates `last_reactivated_at`, increments `reactivation_count` |
| `memory_traverse` | Graph walk from node | May boost connectivity scores |
| `memory_explain` | Score breakdown analysis | Read-only |
| `pin_memory` | Manual core promotion | Sets `pinned=True`, exempts from pruning |
| `unpin_memory` | Remove core status | Re-evaluates core eligibility |

资料来源：[src/genesys_memory/server.py:10-45](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/server.py)

## Engine Workflow

```mermaid
graph TD
    A[Memory Store Request] --> B{Parse & Validate}
    B -->|Valid| C[Generate Embedding]
    B -->|Invalid| Z[Reject]
    C --> D[LLM: Identify Causal Links]
    D --> E[Graph: Create Node + Edges]
    E --> F[Initial Scoring]
    F --> G[Evaluate Transitions]
    G --> H{Transition Needed?}
    H -->|Yes| I[Update State]
    H -->|No| J[Index for Retrieval]
    I --> J
    J --> K[Return to Client]
    
    L[Recall Query] --> M[Vector Search]
    M --> N[Graph Spreading Activation]
    N --> O[Rank by decay_score]
    O --> P[Update Reactivation Metrics]
    P --> Q[Return Ranked Results]
```

## Benchmark Performance

The scoring engine was evaluated on the [LoCoMo](https://arxiv.org/abs/2402.06397) benchmark:

| Category | J-Score |
|----------|---------|
| Single-hop | 94.3% |
| Temporal | 87.5% |
| Multi-hop | 69.8% |
| Open-domain | 91.7% |
| **Overall** | **89.9%** |

Compared against:
- Mem0: 67.1%
- Zep: 75.1%

资料来源：[README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

## Testing

The scoring engine modules are tightly coupled. When modifying scoring, transitions, or forgetting logic, run the full test suite:

```bash
# Run all unit tests
pytest tests/ -v

# With coverage
pytest tests/ -v --cov=src/genesys_memory --cov-report=term-missing
```

资料来源：[CONTRIBUTING.md](https://github.com/rishimeka/genesys/blob/main/CONTRIBUTING.md)

---

<a id='memory-lifecycle'></a>

## Memory Lifecycle Management

### 相关页面

相关主题：[Memory Scoring Engine](#memory-scoring), [Nodes and Edges Data Models](#nodes-edges)

<details>
<summary>Related Source Files</summary>

以下源码文件用于生成本页说明：

- [src/genesys_memory/engine/transitions.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/transitions.py)
- [src/genesys_memory/models/node.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/node.py)
- [src/genesys_memory/models/enums.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/enums.py)
- [src/genesys_memory/mcp/tools.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/mcp/tools.py)
- [src/genesys_memory/server.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/server.py)
</details>

# Memory Lifecycle Management

Memory Lifecycle Management is the core intelligence layer of Genesys that governs how memories are created, scored, transitioned between states, consolidated, and ultimately forgotten. It provides an intelligent forgetting mechanism that goes beyond simple time-based decay by evaluating memories through a multiplicative scoring formula that considers relevance, connectivity, and reactivation patterns.

## Overview

Genesys implements an active memory management system where memories are not passive storage entries but dynamic entities governed by lifecycle rules. Every memory in the system follows a deterministic path from creation through potential promotion or eventual pruning.

The lifecycle management system consists of several interconnected components:

| Component | Purpose |
|-----------|---------|
| **Transitions Engine** | Evaluates and executes status changes between memory states |
| **Scoring Engine** | Calculates decay scores using relevance, connectivity, and reactivation |
| **Consolidation Engine** | Processes episodic memories and forms causal relationships |
| **Forgetting Engine** | Handles pruning of low-value, orphaned memories |
| **Promotion System** | Manages core memory designation and pinning |

资料来源：[src/genesys_memory/engine/transitions.py:1-20]()

## Memory States

Memories exist in one of several distinct states, defined by the `MemoryStatus` enum. Each state represents a different phase in the memory's lifecycle with specific behavioral characteristics.

```mermaid
graph TD
    STORED["STORE (New)"] --> ACTIVE["ACTIVE"]
    ACTIVE --> DORMANT["DORMANT"]
    DORMANT --> FADING["FADING"]
    FADING --> PRUNED["PRUNED"]
    
    ACTIVE -.-> REACTIVATION["reactivation"]
    REACTIVATION -.-> ACTIVE
    
    FADING -.->|score=0, orphan, not pinned| PRUNED
    
    STYLED_STORE{{"Created - waiting for consolidation"}}
    STYLED_ACTIVE{{"In use - scored and tracked"}}
    STYLED_DORMANT{{"Low usage - may be accessed"}}
    STYLED_FADING{{"About to be forgotten"}}
    STYLED_PRUNED{{"Permanently deleted"}}
```

### State Definitions

| State | Description | Auto-transition |
|-------|-------------|------------------|
| `TAGGED` | Newly created, awaiting consolidation signal | 24h timeout → PRUNED |
| `ACTIVE` | Currently relevant, regularly scored | Decay → DORMANT |
| `DORMANT` | Infrequently accessed, reduced priority | Further decay → FADING |
| `FADING` | Pending deletion, low score | score=0 → PRUNED |
| `PRUNED` | Permanently deleted | None |

资料来源：[src/genesys_memory/models/enums.py]() (MemoryStatus enum referenced in transitions.py)

### State Transition Rules

The transition engine evaluates non-core, non-pruned nodes for status changes. The evaluation follows these rules:

1. **Tagged → Active**: Promote when the node has formed causal edges (consolidation signal received)
2. **Active → Dormant**: When reactivation count drops below threshold
3. **Dormant → Fading**: When decay score falls to critical levels
4. **Fading → Pruned**: Only when `score=0`, node is an orphan, and not pinned

```python
# From transitions.py - key evaluation logic
async def evaluate_transitions(
    graph: GraphStorageProvider,
    embeddings: EmbeddingProvider,
    llm: LLMProvider,
    context_embedding: list[float] | None = None,
    context_entities: list[str] | None = None,
) -> list[dict[str, Any]]:
```

资料来源：[src/genesys_memory/engine/transitions.py:18-25]()

## The Scoring System

Every memory is scored by three forces multiplied together, forming the core intelligence of the lifecycle management system:

```
decay_score = relevance × connectivity × reactivation
```

### Scoring Components

| Component | Description | Behavior |
|-----------|-------------|----------|
| **Relevance** | Time-based decay factor | Old memories fade unless reinforced |
| **Connectivity** | Causal graph weight | Rewards memories with many causal links; hub memories survive |
| **Reactivation** | Access frequency | Boosts memories that keep being recalled |

Because the formula is multiplicative, a memory must score on **all three axes** to survive. A highly connected but never-accessed memory still decays. A frequently recalled but causally orphaned memory still fades.

```mermaid
graph LR
    subgraph "Score Factors"
        R[Relevance]
        C[Connectivity]
        A[Reactivation]
    end
    
    R --> MULT["×"]
    C --> MULT
    A --> MULT
    MULT --> SCORE[decay_score]
    
    SCORE -->|high| SURVIVE["SURVIVE"]
    SCORE -->|zero| PRUNE["PRUNED"]
```

资料来源：[src/genesys_memory/engine/scoring.py]() (referenced in transitions.py)

## Memory Node Data Model

Each memory in the system is represented by a `MemoryNode` that tracks all lifecycle-relevant attributes:

```python
class MemoryNode(BaseModel):
    id: uuid.UUID = Field(default_factory=uuid.uuid4)
    status: MemoryStatus = MemoryStatus.ACTIVE
    content_summary: str = Field(max_length=200)
    content_full: str | None = None
    
    # Lifecycle scores
    decay_score: float = 1.0
    causal_weight: int = 0
    reactivation_count: int = 0
    reactivation_pattern: ReactivationPattern = ReactivationPattern.SINGLE
    
    # Timestamps
    created_at: datetime
    last_accessed_at: datetime
    last_reactivated_at: datetime
    
    # Core memory
    pinned: bool = False
    promotion_reason: str | None = None
    
    # Stability
    stability: float = 1.0
```

资料来源：[src/genesys_memory/models/node.py:14-45]()

### Key Lifecycle Fields

| Field | Type | Purpose |
|-------|------|---------|
| `decay_score` | `float` | Current composite score (0.0 to 1.0) |
| `causal_weight` | `int` | Number of causal connections |
| `reactivation_count` | `int` | Number of successful recalls |
| `reactivation_pattern` | `ReactivationPattern` | SINGLE, REPEATED, or CONSOLIDATED |
| `stability` | `float` | Increases on successful retrieval (spaced repetition) |
| `pinned` | `bool` | Core memory flag - never pruned |
| `irrelevance_counter` | `int` | Consecutive low-relevance evaluations |

## MCP Tools for Lifecycle Management

The MCP server exposes tools for programmatic lifecycle management:

| Tool | Description |
|------|-------------|
| `memory_explain` | Explain why a memory exists and its causal chain |
| `pin_memory` | Pin a memory so it's never forgotten |
| `unpin_memory` | Unpin a previously pinned memory |
| `list_core_memories` | List core memories, optionally filtered by category |
| `memory_stats` | Get memory system statistics |
| `promote_to_org` | Promote a private memory to org visibility |

资料来源：[src/genesys_memory/server.py:40-90]()

### Core Preferences Configuration

Users can configure automatic core memory behavior:

```python
Tool(name="set_core_preferences", description="Configure core memory category preferences.", inputSchema={
    "type": "object",
    "properties": {
        "auto": {"type": "array", "items": {"type": "string"}},
        "approval": {"type": "array", "items": {"type": "string"}},
        "excluded": {"type": "array", "items": {"type": "string"}},
    },
})
```

资料来源：[src/genesys_memory/server.py:80-90]()

## Engine Thresholds

The lifecycle behavior is controlled through configurable thresholds defined in `engine/config.py`. These thresholds govern transition points and scoring calculations.

| Threshold | Default | Description |
|-----------|---------|-------------|
| Active→Dormant decay | Configurable | Score threshold for dormancy |
| Dormant→Fading decay | Configurable | Score threshold for fading |
| Orphan detection | 0 edges | Nodes with no causal connections |
| Reactivation boost | Configurable | Multiplier for recalled memories |

> **Note:** Engine thresholds are environment-configurable. Do not hardcode magic numbers in engine files.

资料来源：[src/genesys_memory/engine/config.py]() (referenced in CONTRIBUTING.md)

## Consolidation and Causal Edge Formation

When new memories are stored, the LLM provider analyzes relationships with existing memories to form causal edges:

```python
async def identify_causal_relationships(
    self,
    new_memory: str,
    existing_memories: list[tuple[str, str]],
) -> list[tuple[str, EdgeType, float, str | None]]:
```

The provider identifies three types of causal relationships:

| Edge Type | Description |
|-----------|-------------|
| `caused_by` | Causal dependency |
| `supports` | Supporting evidence |
| `derived_from` | Information lineage |

Relationships are only created when confidence exceeds 0.6.

资料来源：[src/genesys_memory/engine/llm_provider.py:30-60]()

## Reactivation Patterns

Memories track how they are reactivated, which affects scoring:

| Pattern | Description |
|---------|-------------|
| `SINGLE` | Occasional single recall |
| `REPEATED` | Frequently recalled |
| `CONSOLIDATED` | Formed connections during consolidation |

Reactivation history is stored as timestamps in `reactivation_timestamps`, allowing the system to implement spaced repetition principles where successful retrievals increase memory stability.

资料来源：[src/genesys_memory/models/node.py:35-40]()

## Permissions and Ownership

Lifecycle management respects multi-tenant permissions:

```python
def _caller_owns_node(node: MemoryNode) -> bool:
    """Check if the current caller is the original owner of a node."""
    uid = _caller_uid()
    if uid is None:
        raise PermissionError("current_user_id not set — cannot verify ownership")
    role = current_user_role.get(None)
    if role == "admin" and node.org_id and node.org_id in current_org_ids.get([]):
        return True
    if node.original_user_id:
        return node.original_user_id == uid
    return True
```

资料来源：[src/genesys_memory/mcp/tools.py:25-38]()

## Benchmark Performance

The lifecycle management system was evaluated on the [LoCoMo](https://arxiv.org/abs/2402.06397) benchmark:

| Category | J-Score |
|----------|---------|
| Single-hop | 94.3% |
| Temporal | 87.5% |
| Multi-hop | 69.8% |
| Open-domain | 91.7% |
| **Overall** | **89.9%** |

For comparison, Mem0 scored 67.1% and Zep scored 75.1% on the same benchmark.

---

<a id='nodes-edges'></a>

## Nodes and Edges Data Models

### 相关页面

相关主题：[Graph Traversal and Causal Reasoning](#graph-traversal), [Storage Provider Implementation](#storage-implementation)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/genesys_memory/models/node.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/node.py)
- [src/genesys_memory/models/edge.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/edge.py)
- [src/genesys_memory/models/enums.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/enums.py)
- [src/genesys_memory/models/__init__.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/__init__.py)
- [src/genesys_memory/engine/consolidation.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/consolidation.py)
- [src/genesys_memory/mcp/tools.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/mcp/tools.py)
- [src/genesys_memory/engine/transitions.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/transitions.py)
</details>

# Nodes and Edges Data Models

The Nodes and Edges data models form the foundational graph structure of the Genesys memory system. Every piece of information stored in Genesys is represented as a node within a causal graph, with relationships between memories expressed through typed edges. This graph-native approach enables sophisticated memory operations including traversal, causal reasoning, and intelligent forgetting based on connectivity patterns.

## Overview

The data model architecture consists of two primary entities:

- **MemoryNode**: Represents an individual memory with content, metadata, embedding vectors, and lifecycle state
- **MemoryEdge**: Represents a typed, weighted relationship between two memory nodes

Together, these constructs enable the causal graph that powers Genesys's memory intelligence layer. The graph structure supports operations like vector similarity search, causal traversal, and the multiplicative scoring formula that determines memory survival.

## MemoryNode Model

The `MemoryNode` class represents the core unit of memory storage in the Genesys system. Each node encapsulates both the semantic content of a memory and its operational metadata.

### Core Attributes

```python
@dataclass
class MemoryNode:
    id: UUID
    status: MemoryStatus
    content_summary: str
    content_full: str
    embedding: list[float]
    created_at: datetime
    last_accessed_at: datetime
    last_reactivated_at: datetime
    entity_refs: list[str]
    # Additional fields from source code
    original_user_id: Optional[str] = None
    org_id: Optional[str] = None
    visibility: Visibility = Visibility.PRIVATE
    is_pinned: bool = False
    category: Optional[str] = None
```

### Attribute Descriptions

| Attribute | Type | Description |
|-----------|------|-------------|
| `id` | `UUID` | Unique identifier for the memory node |
| `status` | `MemoryStatus` | Current lifecycle state (ACTIVE, TAGGED, DORMANT, etc.) |
| `content_summary` | `str` | Concise summary of the memory content |
| `content_full` | `str` | Complete memory content |
| `embedding` | `list[float]` | Vector representation for similarity search |
| `created_at` | `datetime` | Timestamp when the memory was created |
| `last_accessed_at` | `datetime` | Timestamp of most recent access |
| `last_reactivated_at` | `datetime` | Timestamp of most recent recall operation |
| `entity_refs` | `list[str]` | References to entities mentioned in the memory |
| `original_user_id` | `str` | User who originally created the memory |
| `org_id` | `str` | Organization ID for org-scoped memories |
| `visibility` | `Visibility` | Access level (PRIVATE, ORG, PUBLIC) |
| `is_pinned` | `bool` | Whether memory is protected from pruning |
| `category` | `str` | Optional categorization for filtering |

### MemoryStatus Enum

The lifecycle state of a memory node is governed by the `MemoryStatus` enum, which defines the progression from creation through potential pruning.

资料来源：[src/genesys_memory/models/enums.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/enums.py)

```python
class MemoryStatus(Enum):
    SEMANTIC = "semantic"    # LLM-consolidated abstract memory
    ACTIVE = "active"        # Frequently accessed, high relevance
    TAGGED = "tagged"        # Newly created, not yet consolidated
    DORMANT = "dormant"      # Decaying relevance, low access
    FADING = "fading"        # Near-pruning threshold
    PRUNED = "pruned"        # Permanently removed
```

### Lifecycle State Transitions

```mermaid
graph TD
    TAGGED[TAGGED] -->|consolidation signal| ACTIVE[ACTIVE]
    TAGGED -->|24h no connections| PRUNED[PRUNED]
    ACTIVE -->|decay score drops| DORMANT[DORMANT]
    DORMANT -->|reactivation| ACTIVE
    DORMANT -->|score continues declining| FADING[FADING]
    FADING -->|score = 0| PRUNED
    FADING -->|reactivation| DORMANT
    TAGGED -->|LLM consolidation| SEMANTIC[SEMANTIC]
```

资料来源：[src/genesys_memory/engine/transitions.py:1-50](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/transitions.py)

The transition engine evaluates nodes for state changes based on:

1. **Consolidation signals**: Tagged nodes with formed edges promote to active
2. **Decay scoring**: Low scores trigger transitions toward dormant and fading states
3. **Reactivation**: Recall operations boost nodes back toward active status

## MemoryEdge Model

The `MemoryEdge` class represents relationships between memory nodes, enabling the causal graph structure that powers Genesys's understanding of memory interconnectedness.

### Core Attributes

```python
@dataclass
class MemoryEdge:
    source_id: UUID
    target_id: UUID
    type: EdgeType
    weight: float
    reason: Optional[str] = None
    created_by: Optional[str] = None
```

### Attribute Descriptions

| Attribute | Type | Description |
|-----------|------|-------------|
| `source_id` | `UUID` | ID of the memory node where the edge originates |
| `target_id` | `UUID` | ID of the memory node where the edge points |
| `type` | `EdgeType` | Semantic relationship type |
| `weight` | `float` | Connection strength (0.0 to 1.0) |
| `reason` | `str` | Explanation of why the relationship exists |
| `created_by` | `str` | Provenance: "user_explicit", "auto_link", or LLM-generated |

### EdgeType Enum

The relationship semantics between memory nodes are defined by the `EdgeType` enum, which categorizes different kinds of causal and associative connections.

资料来源：[src/genesys_memory/models/enums.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/enums.py)

```python
class EdgeType(Enum):
    CAUSED_BY = "caused_by"       # Causal relationship: source caused target
    SUPPORTS = "supports"         # Evidential: source supports/validates target
    DERIVED_FROM = "derived_from" # Created from: source derived from target
    RELATED_TO = "related_to"     # Semantic similarity
```

### Edge Relationship Types

| Edge Type | Direction | Semantics | Typical Weight |
|-----------|-----------|-----------|----------------|
| `CAUSED_BY` | source → target | Source memory caused/influenced target | 0.7 |
| `SUPPORTS` | source → target | Source provides evidence for target | 0.8 |
| `DERIVED_FROM` | source → target | Source is abstracted from target | 0.7 |
| `RELATED_TO` | bidirectional | Semantic similarity connection | 0.3-1.0 |

## Graph Data Flow

The interaction between nodes and edges creates the causal graph that powers Genesys's memory operations.

```mermaid
graph LR
    subgraph MemoryNode[MemoryNode]
        N1[Content + Embedding]
        N2[Status + Timestamps]
        N3[Entity References]
    end
    
    subgraph MemoryEdge[MemoryEdge]
        E1[Source → Target]
        E2[Type + Weight]
        E3[Reason + Provenance]
    end
    
    N1 -->|links| E1
    N2 -->|determines| E1
    N3 -->|informs| E2
```

## Memory Storage Operations

The storage layer implements the `GraphStorageProvider` interface to persist and query nodes and edges across different backend options.

### Node Creation

When storing a new memory, the system performs the following operations:

1. Generate embedding vector via the configured `EmbeddingProvider`
2. Create the `MemoryNode` with initial `TAGGED` status
3. Create explicit `CAUSED_BY` edges for related memories
4. Auto-link to semantically similar existing memories via vector search

资料来源：[src/genesys_memory/mcp/tools.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/mcp/tools.py)

```python
# Auto-link to semantically similar existing memories
if embedding:
    similar = await self.graph.vector_search(embedding, k=4, org_ids=org_ids)
    for other_node, score in similar:
        if score < 0.3:
            continue
        edge = MemoryEdge(
            source_id=node.id,
            target_id=other_node.id,
            type=EdgeType.RELATED_TO,
            weight=round(score, 4),
            reason=f"cosine similarity {score:.3f}",
            created_by="auto_link",
        )
        await self.graph.create_edge(edge)
```

### Consolidation Operations

The consolidation engine creates `SEMANTIC` nodes from related episodic memories, establishing `DERIVED_FROM` edges to track the abstraction chain.

资料来源：[src/genesys_memory/engine/consolidation.py:200](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/consolidation.py)

```python
# Create DERIVED_FROM edges
for source_node in matching:
    edge = MemoryEdge(
        source_id=semantic_node.id,
        target_id=source_node.id,
        type=EdgeType.DERIVED_FROM,
        weight=0.7,
    )
    await graph.create_edge(edge)
```

## Visibility and Access Control

Memory nodes support three visibility levels that govern cross-user and cross-organization access:

```python
class Visibility(Enum):
    PRIVATE = "private"   # Only visible to original user
    ORG = "org"           # Visible to organization members
    PUBLIC = "public"     # Visible to all users
```

### Org Boundary Rules

When a memory has `ORG` visibility:

- Edges can only connect to other `ORG` nodes within the same organization
- Private nodes cannot link to org-scoped nodes
- This isolation ensures data governance compliance

## ReactivationPattern Enum

The reactivation behavior tracking is defined by the `ReactivationPattern` enum, which captures how memories are accessed and reinforced over time.

```python
class ReactivationPattern(Enum):
    # Patterns for tracking memory access patterns
    EXPLICIT = "explicit"      # Direct recall request
    IMPLICIT = "implicit"      # Accessed via graph traversal
    CONSOLIDATED = "consolidated"  # Incorporated into semantic memory
```

## Integration with MCP Tools

The MCP server exposes tools that operate on the nodes and edges data models:

| MCP Tool | Operation | Data Model Impact |
|----------|-----------|-------------------|
| `memory_store` | Store new memory | Creates node + edges |
| `memory_recall` | Recall by query | Updates `last_reactivated_at` |
| `memory_traverse` | Graph walk | Reads nodes + edges |
| `memory_explain` | Score breakdown | Reads node + connected edges |
| `pin_memory` | Protect from pruning | Sets `is_pinned=True` |
| `delete_memory` | Remove memory | Deletes node + all edges |

## Scoring Formula Integration

The nodes and edges data models directly support the multiplicative scoring formula:

```
decay_score = relevance × connectivity × reactivation
```

- **Relevance**: Derived from `created_at` and `last_accessed_at` timestamps
- **Connectivity**: Calculated from edge weights connected to the node
- **Reactivation**: Boosted when `last_reactivated_at` is recent

The graph structure enables the connectivity calculation by summing weighted edges, while timestamps on nodes track relevance and reactivation factors.

## Storage Backend Options

The nodes and edges data models are abstracted behind the `GraphStorageProvider` interface, enabling multiple backend options:

| Backend | Description | Use Case |
|---------|-------------|----------|
| `memory` | In-memory Python dict/list | Development, testing |
| `postgres` | PostgreSQL with pgvector | Production, scalable |
| `obsidian` | SQLite sidecar in vault | Local-first knowledge base |
| `falkordb` | Redis-based graph database | Graph-native traversal |

## Summary

The Nodes and Edges data models provide the structural foundation for Genesys's causal graph memory system. `MemoryNode` captures the content, state, and metadata of individual memories, while `MemoryEdge` expresses the typed, weighted relationships between them. Together with the lifecycle states defined in `MemoryStatus` and relationship semantics in `EdgeType`, these models enable sophisticated memory operations including intelligent forgetting, causal reasoning, and semantic consolidation.

资料来源：[src/genesys_memory/models/__init__.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/__init__.py)

---

<a id='graph-traversal'></a>

## Graph Traversal and Causal Reasoning

### 相关页面

相关主题：[Nodes and Edges Data Models](#nodes-edges), [MCP Tools Reference](#mcp-tools)

<details>
<summary>Relevant Source Files</summary>

以下源码文件用于生成本页说明：

- [src/genesys_memory/engine/contradiction.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/contradiction.py)
- [src/genesys_memory/mcp/tools.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/mcp/tools.py)
- [src/genesys_memory/engine/transitions.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/transitions.py)
- [src/genesys_memory/engine/consolidation.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/consolidation.py)
- [src/genesys_memory/engine/llm_provider.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/llm_provider.py)
- [src/genesys_memory/storage/memory.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/storage/memory.py)
</details>

# Graph Traversal and Causal Reasoning

Genesys implements a sophisticated graph-based memory system where memories are interconnected through causal relationships. This design enables the system to traverse memory networks, explain why memories exist, detect contradictions, and intelligently consolidate related information.

## Architecture Overview

The graph traversal and causal reasoning system consists of several interconnected components that work together to maintain a living memory network.

```mermaid
graph TB
    subgraph "Graph Layer"
        TRAVERSE[memory_traverse]
        EXPLAIN[memory_explain]
        CAUSAL[Causal Chain Resolution]
    end
    
    subgraph "Engine Layer"
        CONTRADICT[Contradiction Detection]
        CONSOLIDATE[Memory Consolidation]
        TRANSITIONS[Status Transitions]
        LLM_PROC[LLM Provider]
    end
    
    subgraph "Storage Layer"
        GRAPH[GraphStorageProvider]
        VECTOR[Vector Search]
    end
    
    TRAVERSE --> GRAPH
    EXPLAIN --> CAUSAL
    CAUSAL --> GRAPH
    CONTRADICT --> VECTOR
    CONTRADICT --> LLM_PROC
    CONSOLIDATE --> LLM_PROC
    TRANSITIONS --> GRAPH
    GRAPH --> VECTOR
```

## Causal Chain Resolution

Causal chains represent the lineage and relationships between memories. Each memory can have upstream causes (memories that influenced it) and downstream effects (memories it influenced).

### How Causal Chains Work

When a memory is stored or recalled, the system resolves its causal context by fetching neighboring nodes in both directions. The causal chain is limited to the top 5 most relevant upstream and downstream nodes to maintain performance while providing meaningful context.

```mermaid
graph LR
    A[Memory A] -->|caused_by| B[Memory B]
    B -->|caused_by| C[Memory C]
    C -->|caused_by| D[Memory D]
    
    style A fill:#e1f5fe
    style D fill:#ffcdd2
```

### Causal Chain Data Structure

When explaining a memory, the system builds a structured response containing:

| Field | Type | Description |
|-------|------|-------------|
| `id` | string | Memory node UUID |
| `summary` | string | Content summary of the memory |
| `direction` | string | "upstream" or "downstream" |
| `causal_chain` | array | Ordered list from origin to target |

资料来源：[src/genesys_memory/mcp/tools.py:1-1]()

### Implementation Details

The causal chain resolution iterates through upstream and downstream nodes, collecting their summaries and preventing duplicates via a `seen_causal` set:

```python
seen_causal: set[str] = set()
for n in upstream[:5]:
    nid_str = str(n.id)
    if nid_str not in seen_causal:
        causal_basis.append({"id": nid_str, "summary": n.content_summary, "direction": "upstream"})
        seen_causal.add(nid_str)
```

资料来源：[src/genesys_memory/mcp/tools.py:1-1]()

## Memory Traversal

The `memory_traverse` MCP tool enables walking the causal graph from any given memory node. This is fundamental for understanding memory context and retrieving related information.

### Traversal Workflow

```mermaid
sequenceDiagram
    participant Client
    participant MCP as MCP Server
    participant Graph as GraphStorageProvider
    participant Vector as Vector Search
    
    Client->>MCP: memory_traverse(node_id, direction)
    MCP->>Graph: get_causal_chain(node_id, direction)
    Graph->>Vector: vector_search(embedding, k)
    Vector-->>Graph: similar nodes
    Graph-->>MCP: causal chain nodes
    MCP->>MCP: format_response(nodes)
    MCP-->>Client: formatted traversal result
```

### Traversal Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `node_id` | string | required | Starting memory node ID |
| `direction` | string | "both" | "upstream", "downstream", or "both" |
| `max_depth` | integer | 3 | Maximum traversal depth |
| `k` | integer | 5 | Number of nodes per level |

### Edge Types in Traversal

The system maintains several edge types that govern traversal behavior:

| Edge Type | Semantics | Created By |
|-----------|-----------|------------|
| `CAUSED_BY` | Upstream dependency | User or LLM |
| `SUPPORTS` | Reinforcing relationship | LLM inference |
| `DERIVED_FROM` | Consolidation origin | Consolidation engine |
| `CONTRADICTS` | Conflicting memory | Contradiction detection |
| `RELATED_TO` | Semantic similarity | Auto-linking |

资料来源：[src/genesys_memory/engine/contradiction.py:1-1]()

## Auto-Linking Mechanism

When memories are stored, the system automatically links them to semantically similar existing memories. This creates the underlying graph structure that enables traversal.

### Auto-Linking Process

1. After storing a new memory, generate its embedding
2. Perform vector search for top-K similar memories (k=4)
3. Filter by similarity threshold (0.3 minimum score)
4. Create `RELATED_TO` edges for qualifying matches

```mermaid
graph TD
    A[New Memory] --> B[Generate Embedding]
    B --> C[Vector Search]
    C --> D{score >= 0.3?}
    D-->|No| E[Skip]
    D-->|Yes| F{Cross-org?}
    F-->|Yes| E
    F-->|No| G{Edge exists?}
    G-->|Yes| E
    G-->|No| H[Create RELATED_TO edge]
```

资料来源：[src/genesys_memory/mcp/tools.py:1-1]()

### Auto-Link Constraints

The auto-linking mechanism enforces organizational boundaries:

- Org-scoped memories (`visibility=ORG`) can only link to nodes with matching `org_id`
- Cross-organization linking is prohibited
- Duplicate edges are prevented via existence check

```python
if vis == Visibility.ORG:
    if other_node.visibility != Visibility.ORG or other_node.org_id != org_id:
        continue
already = await self.graph.edge_exists(node_id, str(other_node.id), EdgeType.RELATED_TO)
```

资料来源：[src/genesys_memory/mcp/tools.py:1-1]()

## Contradiction Detection

The contradiction detection system identifies conflicting memories and creates appropriate edges to track them.

### Detection Pipeline

```mermaid
graph LR
    A[New Memory] --> B[Vector Search]
    B --> C{Similarity > 0.85?}
    C-->|No| D[Skip]
    C-->|Yes| E[LLM Confirmation]
    E --> F{Confirmed?}
    F-->|No| D
    F-->|Yes| G[Create CONTRADICTS edge]
```

### Detection Algorithm

The contradiction detection follows a two-stage approach:

1. **Vector Search Stage**: Find highly similar candidates (>0.85 similarity)
2. **LLM Confirmation Stage**: Use language model to verify actual contradiction

```python
candidates = await graph.vector_search(new_node.embedding, k=20)
for candidate_node, sim_score in candidates:
    similarity = 1.0 - sim_score if sim_score <= 1.0 else sim_score
    if similarity < 0.85:
        continue
    is_contradiction, confidence, _ = await llm.check_contradiction(...)
```

资料来源：[src/genesys_memory/engine/contradiction.py:1-1]()

### LLM Contradiction Check

The LLM provider compares the content of both memories and determines if they truly contradict:

```python
prompt = f"""Compare these two memories and determine if they contradict each other:

Memory A: {content_a}

Memory B: {content_b}

Respond with JSON: {{"contradicts": bool, "confidence": 0.0-1.0, "reason": "..."}}"""
```

资料来源：[src/genesys_memory/engine/llm_provider.py:1-1]()

## Causal Relationship Identification

The LLM provider can identify causal relationships between a new memory and existing memories, creating appropriate causal edges.

### Relationship Types

| Type | Confidence Threshold | Description |
|------|---------------------|-------------|
| `caused_by` | > 0.6 | Direct causation |
| `supports` | > 0.6 | Reinforcing evidence |
| `derived_from` | > 0.6 | Semantic extraction |

### Identification Process

```python
prompt = (
    "Given a new memory and a list of existing memories, identify causal relationships.\n\n"
    f"New memory: {new_memory}\n\nExisting memories:\n{mem_lines}\n\n"
    "For each causal relationship found, specify:\n"
    "- target_id: the ID of the existing memory\n"
    '- edge_type: one of "caused_by", "supports", "derived_from"\n'
    "- confidence: 0.0 to 1.0\n"
    "- reason: brief explanation\n\n"
    "Only include relationships with confidence > 0.6."
)
```

资料来源：[src/genesys_memory/engine/llm_provider.py:1-1]()

## Memory Consolidation

Consolidation converts episodic (short-lived) memories into semantic (long-term) representations, creating `DERIVED_FROM` edges to track the source memories.

### Consolidation Workflow

```mermaid
graph TD
    A[Episodic Memories] --> B[Fetch Content]
    B --> C[LLM Consolidation]
    C --> D[Generate Summary]
    D --> E[Create Semantic Node]
    E --> F[Create DERIVED_FROM Edges]
    F --> G[Update Graph]
```

### Semantic Node Creation

The consolidation engine:

1. Collects episodic memory contents
2. Sends to LLM for summarization
3. Generates new embedding for consolidated content
4. Creates semantic memory node with `DERIVED_FROM` edges

```python
summary = await llm.consolidate([m.content_full or m.content_summary for m in matching])
embedding = await embeddings.embed(consolidated_text)

semantic_node = MemoryNode(
    status=MemoryStatus.SEMANTIC,
    content_summary=summary,
    content_full=consolidated_text,
    embedding=embedding,
    ...
)

for source_node in matching:
    edge = MemoryEdge(
        source_id=semantic_node.id,
        target_id=source_node.id,
        type=EdgeType.DERIVED_FROM,
        weight=0.7,
    )
    await graph.create_edge(edge)
```

资料来源：[src/genesys_memory/engine/consolidation.py:1-1]()

## Status Transitions Based on Graph Activity

The transition engine evaluates memories for promotion based on their graph connectivity.

### Tagged → Active Promotion

Memories in `TAGGED` status are promoted to `ACTIVE` when they form connections in the causal graph:

```python
tagged_nodes = await graph.get_nodes_by_status(MemoryStatus.TAGGED)
for node in tagged_nodes:
    if node.visibility == Visibility.ORG:
        continue
    if not await graph.is_orphan(str(node.id)):
        await graph.update_node(str(node.id), {"status": MemoryStatus.ACTIVE})
        transitions.append({
            "node_id": str(node.id),
            "old": "tagged",
            "new": "active",
            "reason": "consolidation signal: edge formed",
        })
```

资料来源：[src/genesys_memory/engine/transitions.py:1-1]()

### Orphan Expiration

Tagged memories that remain disconnected for 24 hours are automatically expired:

```python
age_hours = (datetime.now(timezone.utc) - node.created_at).total_seconds() / 3600
if age_hours > 24:
    await graph.update_node(str(node.id), {"status": MemoryStatus.FADING})
```

资料来源：[src/genesys_memory/engine/transitions.py:1-1]()

## Graph Storage Provider

The storage layer implements efficient graph operations with per-user isolation and edge indexing.

### In-Memory Graph Implementation

The `InMemoryGraphProvider` provides graph storage with performance optimizations:

```python
class InMemoryGraphProvider:
    """GraphStorageProvider backed by plain dicts with per-user isolation."""
    
    # Edge indexes: {user_id: {node_id: [edges]}}
    _idx_by_source: dict[str, dict[str, list[MemoryEdge]]] = {}
    _idx_by_target: dict[str, dict[str, list[MemoryEdge]]] = {}
```

资料来源：[src/genesys_memory/storage/memory.py:1-1]()

### Performance Characteristics

| Operation | Complexity | Notes |
|-----------|------------|-------|
| Edge lookup by source | O(degree) | Indexed by `_idx_by_source` |
| Edge lookup by target | O(degree) | Indexed by `_idx_by_target` |
| Is orphan check | O(degree) | Uses edge indexes |
| Full graph scan | O(total_edges) | Only for full traversals |

### Persistence Support

The in-memory provider supports JSON persistence for survival across process restarts:

```python
def __init__(self, persist_path: str | None = None):
    self._persist_path = Path(persist_path) if persist_path else None
    self._save_depth = 0
    self._dirty = False
```

资料来源：[src/genesys_memory/storage/memory.py:1-1]()

## MCP Tools Reference

### memory_traverse

Walk the causal graph from a given memory node.

```json
{
  "node_id": "uuid-string",
  "direction": "upstream | downstream | both",
  "max_depth": 3,
  "k": 5
}
```

### memory_explain

Explain why a memory exists by showing its causal chain.

```json
{
  "node_id": "uuid-string",
  "include_context": true
}
```

Returns the memory with `causal_basis` (immediate neighbors) and `causal_chain` (full lineage).

## Related Systems

- **Scoring Engine**: Applies the decay formula `decay_score = relevance × connectivity × reactivation` where connectivity is derived from graph structure
- **Reactivation Tracking**: Updates `last_reactivated_at` timestamps when memories are traversed
- **Pruning System**: Uses connectivity metrics to determine which memories to prune

资料来源：[README.md:1-1]()

---

<a id='backends-overview'></a>

## Storage Backend Comparison

### 相关页面

相关主题：[Storage Provider Implementation](#storage-implementation)

<details>
<summary>Related Source Files</summary>

以下源码文件用于生成本页说明：

- [src/genesys_memory/storage/memory.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/storage/memory.py)
- [src/genesys_memory/storage/base.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/storage/base.py)
- [src/genesys_memory/models/node.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/node.py)
- [src/genesys_memory/models/edge.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/edge.py)
- [docker-compose.yml](https://github.com/rishimeka/genesys/blob/main/docker-compose.yml)
- [config/init.sql](https://github.com/rishimeka/genesys/blob/main/config/init.sql)
- [CONTRIBUTING.md](https://github.com/rishimeka/genesys/blob/main/CONTRIBUTING.md)
</details>

# Storage Backend Comparison

Genesys supports multiple storage backends to accommodate different deployment scenarios, from zero-dependency local development to production-scale distributed systems. This page provides a comprehensive comparison of available backends, their architectures, and guidance for selecting the appropriate backend for your use case.

## Architecture Overview

Genesys implements a **provider abstraction pattern** where all data access flows through standardized interfaces defined in `storage/base.py`. This design ensures that business logic remains decoupled from storage implementation details, enabling seamless backend switching without code changes.

```mermaid
graph TD
    A["🔷 MCP Tools Layer<br/>(tools.py)"] --> B["📦 Storage Provider Interface<br/>(base.py)"]
    B --> C1["🟢 In-Memory Provider"]
    B --> C2["🔵 Postgres Provider"]
    B --> C3["🟡 Obsidian Provider"]
    B --> C4["🟣 FalkorDB Provider"]
    B --> C5["⚪ Custom Provider"]
    
    C1 --> D1["Dict + JSON File"]
    C2 --> D2["PostgreSQL + pgvector"]
    C3 --> D3["SQLite + File System"]
    C4 --> D4["Redis Graph"]
    
    style A fill:#4a90d9,color:#fff
    style B fill:#f5a623,color:#fff
    style D1 fill:#7ed321,color:#fff
    style D2 fill:#4a90d9,color:#fff
    style D3 fill:#f5a623,color:#fff
    style D4 fill:#9013fe,color:#fff
```

**Key Design Principle:** Storage abstraction is mandatory. All data access goes through provider interfaces in `storage/base.py`. Never import a database client directly in business logic. 资料来源：[CONTRIBUTING.md:1]()

## Storage Provider Interfaces

The storage layer is composed of three interconnected provider types that handle different aspects of memory management.

### Provider Types

| Provider | Responsibility | Key Methods |
|----------|---------------|-------------|
| **GraphStorageProvider** | Nodes, edges, causal relationships | `upsert_node`, `get_node`, `delete_node`, `upsert_edge`, `get_neighbors` |
| **CacheProvider** | Short-term caching, TTL management | `get`, `set`, `delete`, `exists` |
| **EmbeddingProvider** | Vector embedding generation | `embed`, `batch_embed` |

资料来源：[src/genesys_memory/storage/base.py:1]()

### Memory Node Structure

Every memory in Genesys is represented as a `MemoryNode` with the following core attributes:

```python
class MemoryNode(BaseModel):
    id: uuid.UUID
    status: MemoryStatus  # ACTIVE, DORMANT, FADING, PRUNED
    content_summary: str  # Max 200 chars
    content_full: str | None
    embedding: list[float] | None
    
    # Lifecycle scores
    decay_score: float = 1.0
    causal_weight: int = 0
    reactivation_count: int = 0
    
    # Core memory
    pinned: bool = False
    category: str | None
```

资料来源：[src/genesys_memory/models/node.py:1]()

## Available Backends

### 1. In-Memory Backend (Built-in)

The default backend with zero external dependencies. Suitable for development, testing, and lightweight deployments.

#### Features

- Built-in dict-based storage with per-user isolation
- Optional JSON file persistence via `GENESYS_PERSIST_PATH`
- No Docker, database, or API keys required for basic operation
- Fast startup, ideal for local development

#### Architecture

```python
class InMemoryCacheProvider:
    """CacheProvider backed by a plain dict."""
    def __init__(self) -> None:
        self._data: dict[str, str] = {}

class InMemoryGraphProvider:
    """GraphStorageProvider backed by plain dicts with per-user isolation."""
    # State persisted to JSON if persist_path is set
```

资料来源：[src/genesys_memory/storage/memory.py:1]()

#### Configuration

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `GENESYS_BACKEND` | No | `memory` | Set to `memory` explicitly |
| `GENESYS_PERSIST_PATH` | No | None | Path for JSON state persistence |
| `OPENAI_API_KEY` | If using OpenAI embeddings | - | For vector search |
| `GENESYS_EMBEDDER` | No | `openai` | Or `local` for no API key |

#### Use Cases

- Local development and testing
- Single-user CLI applications
- Prototyping and evaluation
- When infrastructure overhead must be minimized

---

### 2. PostgreSQL + pgvector (Production)

Persistent, scalable storage with native vector search capabilities via the pgvector extension.

#### Features

- Full ACID compliance and relational integrity
- pgvector extension for efficient similarity search
- Horizontal scalability with connection pooling
- Alembic migrations for schema management
- Docker Compose orchestration included

#### Architecture

```mermaid
graph LR
    A["Genesys API"] --> B["PostgreSQL Driver"]
    B --> C["PostgreSQL 15+"]
    C --> D["pgvector Extension"]
    D --> E["Vectors + Relations"]
    
    style C fill:#4a90d9,color:#fff
    style D fill:#7ed321,color:#fff
```

#### Database Schema

The Postgres backend uses a normalized schema with dedicated tables for nodes, edges, and embeddings:

```sql
-- Core memory nodes table
CREATE TABLE memory_nodes (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    status VARCHAR(20) NOT NULL,
    content_summary VARCHAR(200) NOT NULL,
    content_full TEXT,
    embedding vector(1536),
    decay_score FLOAT DEFAULT 1.0,
    causal_weight INTEGER DEFAULT 0,
    reactivation_count INTEGER DEFAULT 0,
    pinned BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP DEFAULT NOW(),
    last_accessed_at TIMESTAMP DEFAULT NOW()
);

-- Create index for vector similarity search
CREATE INDEX ON memory_nodes USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
```

资料来源：[config/init.sql:1]()

#### Configuration

```bash
# Install
pip install 'genesys-memory[postgres]'

# Environment variables
GENESYS_BACKEND=postgres
DATABASE_URL=postgresql://genesys:genesys@localhost:5432/genesys
OPENAI_API_KEY=sk-...
```

#### Docker Compose Setup

```yaml
# docker-compose.yml
services:
  postgres:
    image: pgvector/pgvector:pg15
    environment:
      POSTGRES_USER: genesys
      POSTGRES_PASSWORD: genesys
      POSTGRES_DB: genesys
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:
```

资料来源：[docker-compose.yml:1]()

#### Startup Commands

```bash
docker compose up -d postgres
alembic upgrade head
GENESYS_BACKEND=postgres uvicorn genesys.api:app --port 8000
```

---

### 3. Obsidian Vault (Local-First)

Transforms an existing Obsidian vault into a Genesys memory store where Markdown files become memory nodes and `[[wikilinks]]` become causal edges.

#### Features

- Markdown files become memory nodes automatically
- `[[wikilinks]]` converted to causal edges
- SQLite sidecar (`.genesys/index.db`) handles indexing
- File watcher for incremental re-indexing
- Zero external API dependencies with local embeddings
- Works fully offline

#### Architecture

```mermaid
graph TD
    A["📁 Obsidian Vault"] --> B["File Watcher"]
    B --> C["Indexing Engine"]
    C --> D[".genesys/index.db<br/>(SQLite)"]
    D --> E["Vector Embeddings"]
    
    F[".md Files"] --> G["Memory Nodes"]
    H["[[wikilinks]]"] --> I["Causal Edges"]
    
    style A fill:#f5a623,color:#fff
    style D fill:#7ed321,color:#fff
```

#### Configuration

```bash
# Install with local embeddings (no API key needed)
pip install 'genesys-memory[obsidian,local]'

# Environment variables
GENESYS_BACKEND=obsidian
GENESYS_EMBEDDER=local
OBSIDIAN_VAULT_PATH=/path/to/your/vault
```

#### Vault Auto-Detection

If `OBSIDIAN_VAULT_PATH` is not set, Genesys auto-detects by looking for `.obsidian/` in these directories:

| Search Path | Priority |
|-------------|----------|
| `~/Documents/personal` | 1st |
| `~/Documents/Obsidian` | 2nd |
| `~/obsidian` | 3rd |

#### Embedding Model

The local embedder uses `all-MiniLM-L6-v2` (384-dimensional vectors) via `sentence-transformers`:

- Model size: ~80 MB (downloaded on first use)
- No API key required
- Suitable for most recall accuracy requirements

---

### 4. FalkorDB (Graph-Native)

Uses FalkorDB (Redis-based graph database) for native graph traversal with O(1) edge lookups.

#### Features

- Native graph data structure with no ORM mapping
- Redis-backed for high performance
- Excellent for complex causal chain traversal
- Scalable Redis ecosystem

#### Architecture

```mermaid
graph LR
    A["Genesys API"] --> B["FalkorDB Client"]
    B --> C["Redis Protocol"]
    C --> D["FalkorDB Container"]
    D --> E["Native Graph<br/>Traversal"]
    
    style D fill:#9013fe,color:#fff
```

#### Configuration

```bash
# Install
pip install 'genesys-memory[falkordb]'

# Environment variables
GENESYS_BACKEND=falkordb
FALKORDB_HOST=localhost
OPENAI_API_KEY=sk-...
```

#### Startup

```bash
docker compose up -d falkordb
uvicorn genesys.api:app --port 8000
```

---

## Backend Comparison Matrix

| Criteria | In-Memory | PostgreSQL | Obsidian | FalkorDB |
|----------|-----------|------------|----------|----------|
| **Dependencies** | None | Docker + Postgres | None | Docker + Redis |
| **Persistence** | JSON file | Full database | Markdown + SQLite | Redis dump |
| **Scalability** | Single instance | Horizontal | Vault size | Redis cluster |
| **Vector Search** | Via embedding API | pgvector native | Local models | Via API |
| **Graph Traversal** | Dict-based | SQL joins | File parsing | Native |
| **Offline Capable** | Yes | No | Yes | No |
| **Setup Complexity** | None | Medium | Low | Medium |
| **Best For** | Dev/Testing | Production | Personal KB | Complex graphs |

## Configuration Reference

### Environment Variables

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `OPENAI_API_KEY` | Unless `GENESYS_EMBEDDER=local` | - | Embedding generation |
| `ANTHROPIC_API_KEY` | No | - | LLM memory processing |
| `GENESYS_BACKEND` | No | `memory` | `memory`, `postgres`, `obsidian`, `falkordb` |
| `GENESYS_EMBEDDER` | No | `openai` | `openai` or `local` |
| `DATABASE_URL` | If postgres | - | PostgreSQL connection string |
| `OBSIDIAN_VAULT_PATH` | If obsidian | Auto-detect | Path to vault |
| `FALKORDB_HOST` | If falkordb | `localhost` | FalkorDB host |
| `GENESYS_PERSIST_PATH` | If using persistence | - | JSON state file path |
| `GENESYS_USER_ID` | No | - | Default user ID (single-tenant) |

资料来源：[README.md:1]()

## Implementing Custom Backends

To implement a custom storage backend, implement the `GraphStorageProvider` interface from `storage/base.py`:

```python
from genesys_memory.storage.base import GraphStorageProvider
from genesys_memory.models.node import MemoryNode
from genesys_memory.models.edge import MemoryEdge

class MyCustomProvider(GraphStorageProvider):
    async def upsert_node(self, node: MemoryNode) -> MemoryNode:
        # Your implementation
        pass
    
    async def get_node(self, node_id: str) -> MemoryNode | None:
        # Your implementation
        pass
    
    async def upsert_edge(self, edge: MemoryEdge) -> MemoryEdge:
        # Your implementation
        pass
    
    async def get_neighbors(
        self, 
        node_id: str, 
        edge_types: list[str] | None = None,
        depth: int = 1
    ) -> list[MemoryEdge]:
        # Your implementation
        pass
```

资料来源：[src/genesys_memory/storage/base.py:1]()

## Selection Guide

```mermaid
graph TD
    A["Need external APIs?"] --> B{"No API Keys?"}
    B -->|Yes| C["Local Embeddings?"]
    C -->|Yes| D["Use Obsidian + Local"]
    C -->|No| E["Use Obsidian + OpenAI"]
    B -->|No| F["Scale Requirements?"]
    
    F -->|High Volume| G["Use PostgreSQL"]
    F -->|Complex Graphs| H["Use FalkorDB"]
    F -->|Simple/Testing| I["Use In-Memory + Persist"]
    
    style D fill:#7ed321,color:#fff
    style G fill:#4a90d9,color:#fff
    style H fill:#9013fe,color:#fff
    style I fill:#f5a623,color:#fff
```

### Decision Criteria

**Choose In-Memory when:**
- Building prototypes or running tests
- Single-user deployment with no persistence requirements
- Infrastructure constraints prevent containerized deployments

**Choose PostgreSQL when:**
- Production deployment with multi-user support
- Need for ACID compliance and data integrity
- Vector similarity search is primary retrieval method
- Existing Postgres infrastructure available

**Choose Obsidian when:**
- Already using Obsidian for note-taking
- Prefer local-first, offline-capable solution
- Markdown-based knowledge management is preferred
- Zero cloud dependency is a requirement

**Choose FalkorDB when:**
- Complex causal chain traversal is frequent
- Graph-native operations are performance critical
- Redis ecosystem is already in use
- Sub-millisecond edge lookups required

---

<a id='storage-implementation'></a>

## Storage Provider Implementation

### 相关页面

相关主题：[Storage Backend Comparison](#backends-overview), [System Architecture](#architecture)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/genesys_memory/storage/base.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/storage/base.py)
- [src/genesys_memory/storage/memory.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/storage/memory.py)
- [src/genesys_memory/storage/cache.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/storage/cache.py)
- [src/genesys_memory/providers.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/providers.py)
- [src/genesys_memory/models/node.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/node.py)
- [src/genesys_memory/models/edge.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/edge.py)
- [src/genesys_memory/mcp/tools.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/mcp/tools.py)
</details>

# Storage Provider Implementation

## Overview

The Storage Provider Implementation in Genesys provides a modular, pluggable architecture for persisting memory nodes and their causal relationships. This abstraction layer enables the memory system to operate with different storage backends—from simple in-memory dictionaries to production-grade databases like PostgreSQL with pgvector, or even Obsidian vaults and FalkorDB—without changing the core memory logic.

The storage layer is composed of four provider types that work together:

- **GraphStorageProvider**: Manages `MemoryNode` entities and `MemoryEdge` relationships (the causal graph)
- **CacheProvider**: Provides fast key-value caching for temporary data
- **EmbeddingProvider**: Generates and retrieves vector embeddings for semantic search
- **EventBusProvider**: Handles event-driven communication between system components

资料来源：[src/genesys_memory/storage/base.py]()

---

## Architecture

```mermaid
graph TD
    subgraph "Storage Provider Layer"
        GP[GraphStorageProvider]
        CP[CacheProvider]
        EP[EmbeddingProvider]
        EBP[EventBusProvider]
    end
    
    subgraph "Backend Implementations"
        subgraph "In-Memory"
            IMGP[InMemoryGraphProvider]
            IMCP[InMemoryCacheProvider]
        end
        
        subgraph "PostgreSQL"
            PG[PostgresGraphProvider]
            PGEM[PostgresEmbeddingProvider]
        end
        
        subgraph "Obsidian"
            OV[ObsidianGraphProvider]
        end
        
        subgraph "FalkorDB"
            FK[FalkorDBGraphProvider]
        end
    end
    
    GP --> IMGP
    GP --> PG
    GP --> OV
    GP --> FK
    CP --> IMCP
    EP --> PGEM
    
    subgraph "Higher Layers"
        MCP[MCP Tools]
        Engine[Scoring Engine]
    end
    
    MCP --> GP
    Engine --> GP
    Engine --> CP
    Engine --> EP
```

资料来源：[src/genesys_memory/providers.py]()

---

## Provider Interface Contracts

### GraphStorageProvider

The `GraphStorageProvider` is the core interface for managing the memory graph. It handles both node storage and edge management for the causal graph structure.

资料来源：[src/genesys_memory/storage/base.py]()

| Method | Description | Returns |
|--------|-------------|---------|
| `upsert_node(node)` | Create or update a memory node | `MemoryNode` |
| `get_node(node_id)` | Retrieve a node by ID | `MemoryNode \| None` |
| `delete_node(node_id)` | Remove a node and its edges | `bool` |
| `list_nodes(filters)` | List nodes with optional filtering | `list[MemoryNode]` |
| `upsert_edge(edge)` | Create or update an edge | `MemoryEdge` |
| `get_edge(edge_id)` | Retrieve an edge | `MemoryEdge \| None` |
| `delete_edge(edge_id)` | Remove an edge | `bool` |
| `get_neighbors(node_id)` | Get adjacent nodes | `list[MemoryNode]` |
| `get_stats()` | Return graph statistics | `dict` |

### CacheProvider

The `CacheProvider` provides ephemeral key-value storage with optional TTL support.

| Method | Description | Returns |
|--------|-------------|---------|
| `get(key)` | Retrieve cached value | `str \| None` |
| `set(key, value, ttl_seconds)` | Store value with TTL | `None` |
| `delete(key)` | Remove cached entry | `None` |
| `exists(key)` | Check if key exists | `bool` |

资料来源：[src/genesys_memory/storage/cache.py]()

### EmbeddingProvider

The `EmbeddingProvider` interface handles vector embedding generation and similarity search.

| Method | Description |
|--------|-------------|
| `embed(text)` | Generate embedding vector for text |
| `search(query, k)` | Find top-k similar vectors |
| `delete(embedding_id)` | Remove an embedding |

---

## In-Memory Implementation

The in-memory storage providers are the default implementation, requiring no external dependencies. They use Python dictionaries for storage and are suitable for development, testing, or single-user scenarios.

### InMemoryCacheProvider

Located in `src/genesys_memory/storage/memory.py`, this provider backs the cache interface with a simple dictionary:

```python
class InMemoryCacheProvider:
    """CacheProvider backed by a plain dict."""

    def __init__(self) -> None:
        self._data: dict[str, str] = {}

    async def get(self, key: str) -> str | None:
        return self._data.get(key)

    async def set(self, key: str, value: str, ttl_seconds: int = 300) -> None:
        self._data[key] = value
```

**Configuration**: No configuration required. Default TTL is 300 seconds.

**Limitations**:
- Data is lost on application restart
- No horizontal scaling support
- In-memory storage only

资料来源：[src/genesys_memory/storage/memory.py:28-40]()

### InMemoryGraphProvider

The `InMemoryGraphProvider` implements the full graph storage interface using dictionaries with per-user isolation. It supports optional JSON persistence via `persist_path`.

```python
class InMemoryGraphProvider:
    """GraphStorageProvider backed by plain dicts with per-user isolation."""

    def __init__(self, persist_path: Path | None = None) -> None:
        # State includes: nodes, edges, adjacency lists
        ...
```

**Key Features**:
- Per-user isolation enforced via `current_user_id` context variable
- Optional JSON file persistence
- In-memory graph traversal using adjacency lists

```python
def _uid() -> str:
    uid = current_user_id.get(None)
    if uid is None:
        raise RuntimeError("No user context — current_user_id not set")
    return uid
```

资料来源：[src/genesys_memory/storage/memory.py:42-58]()

---

## Provider Factory

The `get_providers()` function in `src/genesys_memory/providers.py` is the central factory that instantiates and wires together the appropriate provider implementations based on environment configuration.

```python
providers = get_providers()
tools = providers.tools
```

The factory reads environment variables to determine which backend to use:

| Environment Variable | Options | Default |
|---------------------|---------|---------|
| `GENESYS_BACKEND` | `memory`, `postgres`, `obsidian`, `falkordb` | `memory` |
| `GENESYS_EMBEDDER` | `openai`, `local` | `openai` |
| `DATABASE_URL` | PostgreSQL connection string | — |
| `OBSIDIAN_VAULT_PATH` | Path to vault directory | auto-detect |
| `FALKORDB_HOST` | FalkorDB host | `localhost` |

资料来源：[src/genesys_memory/providers.py]()

---

## MCP Tool Integration

The MCP (Model Context Protocol) tools interact with storage providers through a dispatch table that maps tool names to provider methods:

```python
_TOOL_DISPATCH: dict[str, tuple[Any, ...]] = {
    "memory_store": (tools.memory_store, ["content"], {"source_session": "", "related_to": None, "visibility": "private", "org_id": None}),
    "memory_recall": (tools.memory_recall, ["query"], {"k": 10, "max_results": None}),
    "memory_search": (tools.memory_search, ["query"], {"filters": None, "k": 10}),
    "memory_traverse": (tools.memory_traverse, ["node_id"], {"depth": 2, "edge_types": None}),
    "memory_explain": (tools.memory_explain, ["node_id"], {}),
    "pin_memory": (tools.pin_memory, ["node_id"], {}),
    "unpin_memory": (tools.unpin_memory, ["node_id"], {}),
    "list_core_memories": (tools.list_core_memories, [], {"category": None}),
    "delete_memory": (tools.delete_memory, ["node_id"], {}),
    "memory_stats": (tools.memory_stats, [], {}),
    "set_core_preferences": (tools.set_core_preferences, [], {"auto": None, "approval": None, "excluded": None}),
}
```

资料来源：[src/genesys_memory/server.py]()

### Tool-to-Provider Mapping

| MCP Tool | Storage Provider Method | Purpose |
|----------|------------------------|---------|
| `memory_store` | `GraphStorageProvider.upsert_node` | Create new memories |
| `memory_recall` | `GraphStorageProvider` + `EmbeddingProvider` | Hybrid search |
| `memory_search` | `GraphStorageProvider.list_nodes` | Filtered search |
| `memory_traverse` | `GraphStorageProvider.get_neighbors` | Graph traversal |
| `memory_explain` | `GraphStorageProvider.get_node` | Retrieve single memory |
| `pin_memory` | `GraphStorageProvider.upsert_node` | Update pinned status |
| `delete_memory` | `GraphStorageProvider.delete_node` | Remove memory |
| `memory_stats` | `GraphStorageProvider.get_stats` | Graph metrics |

资料来源：[src/genesys_memory/mcp/tools.py]()

---

## Data Models

### MemoryNode

The `MemoryNode` model represents a single memory unit with full lifecycle tracking:

```python
class MemoryNode(BaseModel):
    id: uuid.UUID = Field(default_factory=uuid.uuid4)
    status: MemoryStatus = MemoryStatus.ACTIVE
    content_summary: str = Field(max_length=200)
    content_full: str | None = None
    content_ref: str | None = None
    embedding: list[float] | None = None

    # Timestamps
    created_at: datetime
    last_accessed_at: datetime
    last_reactivated_at: datetime

    # Lifecycle scores
    decay_score: float = 1.0
    causal_weight: int = 0
    reactivation_count: int = 0
    reactivation_pattern: ReactivationPattern
    irrelevance_counter: int = 0

    # Stability (increases on successful retrieval, per spaced repetition)
    stability: float = 1.0

    # Core memory
    pinned: bool = False
    promotion_reason: str | None = None
```

资料来源：[src/genesys_memory/models/node.py:1-35]()

### MemoryEdge

Edges represent causal relationships between memories:

```python
class MemoryEdge(BaseModel):
    id: uuid.UUID
    source_id: uuid.UUID
    target_id: uuid.UUID
    edge_type: EdgeType  # caused_by, supports, derived_from
    weight: float = 1.0
    confidence: float
    reason: str | None = None
```

资料来源：[src/genesys_memory/models/edge.py]()

---

## Backend Comparison

| Backend | Use Case | Scalability | Persistence | External Dependencies |
|---------|----------|-------------|-------------|----------------------|
| **In-Memory** | Development, testing | Single instance | Optional JSON file | None |
| **PostgreSQL + pgvector** | Production, multi-tenant | High | Full ACID | Docker Compose |
| **Obsidian Vault** | Personal knowledge base | Single user | Markdown files | None |
| **FalkorDB** | Graph-native traversal | High | Redis-based | Docker Compose |

资料来源：[README.md]()

---

## Adding Custom Storage Backends

To implement a custom storage backend, create a class that inherits from the base provider interfaces:

```python
from genesys_memory.storage.base import GraphStorageProvider, CacheProvider

class MyCustomGraphProvider(GraphStorageProvider):
    async def upsert_node(self, node: MemoryNode) -> MemoryNode:
        # Implement node persistence
        pass
    
    async def get_node(self, node_id: str) -> MemoryNode | None:
        # Implement node retrieval
        pass
    
    # ... implement all interface methods
```

Register your provider in the factory function within `providers.py` by adding a new condition branch.

---

## Security Considerations

The storage layer enforces user isolation through context variables:

```python
def _caller_owns_node(node: MemoryNode) -> bool:
    uid = _caller_uid()
    if uid is None:
        raise PermissionError("current_user_id not set — cannot verify ownership")
    role = current_user_role.get(None)
    if role == "admin" and node.org_id and node.org_id in current_org_ids.get([]):
        return True
    if node.original_user_id:
        return node.original_user_id == uid
    return True
```

资料来源：[src/genesys_memory/mcp/tools.py:27-38]()

Access control rules:
1. All operations require an authenticated `current_user_id`
2. Admin users can access nodes within their organization
3. Nodes maintain `original_user_id` for ownership tracking
4. Private nodes cannot be accessed by other users

---

## Performance Notes

- The in-memory provider provides sub-millisecond latency for local operations
- PostgreSQL with pgvector provides vector similarity search with approximate nearest neighbor (ANN) indexing
- FalkorDB leverages Redis for fast graph traversal operations
- Cache operations use a default TTL of 300 seconds to prevent stale data

资料来源：[src/genesys_memory/storage/memory.py:35-37]()

---

<a id='mcp-tools'></a>

## MCP Tools Reference

### 相关页面

相关主题：[Configuration Guide](#configuration), [Getting Started with Genesys](#getting-started)

<details>
<summary>Relevant Source Files</summary>

以下源码文件用于生成本页说明：

- [src/genesys_memory/mcp/tools.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/mcp/tools.py)
- [src/genesys_memory/server.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/server.py)
- [src/genesys_memory/models/node.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/node.py)
- [src/genesys_memory/models/edge.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/edge.py)
- [src/genesys_memory/engine/llm_provider.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/llm_provider.py)
</details>

# MCP Tools Reference

The Model Context Protocol (MCP) Tools layer is the primary interface through which AI agents interact with the Genesys memory system. This module exposes all memory operations as callable tools via the MCP stdio transport, enabling seamless integration with Claude Desktop and other MCP-compatible clients.

## Architecture Overview

The MCP tools layer sits between the MCP protocol server and the core Genesys engine. It handles:

- **Tool dispatching**: Routing tool calls to appropriate engine methods
- **Context injection**: Providing user/org context for multi-tenant support
- **Permission validation**: Ensuring callers have appropriate access rights
- **Response formatting**: Converting engine results into MCP-compatible format

```mermaid
graph TD
    A[MCP Client] -->|call_tool| B[MCP Server]
    B -->|dispatch| C[Tool Dispatcher]
    C -->|inject context| D[Context Managers]
    D -->|verify permissions| E[Core Memory Engine]
    E -->|execute| F[Storage Providers]
    F -->|graph ops| G[Vector DB / FalkorDB / Obsidian]
    C -->|format response| H[TextContent Response]
```

## Tool Registry

All available MCP tools are registered in `server.py` with their schemas and dispatch mappings.

### Tool Dispatch Table

| Tool Name | Required Args | Optional Args | Description |
|-----------|---------------|---------------|-------------|
| `memory_store` | `content` | `source_session`, `related_to`, `visibility`, `org_id` | Store a new memory |
| `memory_recall` | `query` | `k`, `max_results` | Hybrid search recall |
| `memory_search` | `query` | `filters`, `k` | Filtered vector search |
| `memory_traverse` | `node_id` | `depth`, `edge_types` | Graph traversal |
| `memory_explain` | `node_id` | - | Score breakdown explanation |
| `pin_memory` | `node_id` | - | Pin to core status |
| `unpin_memory` | `node_id` | - | Unpin and re-evaluate |
| `list_core_memories` | - | `category` | List core memories |
| `delete_memory` | `node_id` | - | Permanently delete |
| `memory_stats` | - | - | Get graph statistics |
| `set_core_preferences` | - | `auto`, `approval`, `excluded` | Configure core categories |
| `promote_to_org` | `node_id`, `org_id` | `action`, `dry_run` | Promote to org visibility |

资料来源：[src/genesys_memory/server.py:15-60]()

## Memory Store Tool

Creates a new memory node with automatic causal edge discovery.

### Input Schema

```json
{
  "type": "object",
  "required": ["content"],
  "properties": {
    "content": { "type": "string" },
    "source_session": { "type": "string" },
    "related_to": { 
      "type": "array",
      "items": { "type": "string" }
    },
    "visibility": { 
      "type": "string",
      "enum": ["private", "org", "public"],
      "default": "private"
    },
    "org_id": { "type": "string" }
  }
}
```

### Behavior

1. Generates embedding for content via configured embedder
2. Creates `MemoryNode` with `ACTIVE` status
3. Optionally links to existing memories via `related_to`
4. Triggers causal edge discovery via LLM provider
5. Emits `MemoryStoredEvent` to event bus

资料来源：[src/genesys_memory/mcp/tools.py:1-50]()

## Memory Recall Tool

Implements hybrid search combining vector similarity, keyword matching, and graph spreading activation.

### Input Schema

```json
{
  "type": "object",
  "required": ["query"],
  "properties": {
    "query": { "type": "string" },
    "k": { "type": "integer", "default": 10 },
    "max_results": { "type": "integer" }
  }
}
```

### Search Algorithm

```mermaid
graph LR
    A[Query Text] --> B[Vector Embedding]
    A --> C[Keyword Extraction]
    B --> D[Vector Similarity Search]
    C --> E[BM25 Ranking]
    D --> F[Initial Candidates]
    E --> F
    F --> G[Graph Spreading Activation]
    G --> H[Score Normalization]
    H --> I[Top K Results]
```

The `k` parameter controls the number of initial vector candidates considered. Spreading activation propagates through causal edges, boosting memories connected to initially-matched nodes.

资料来源：[src/genesys_memory/engine/llm_provider.py:20-60]()

## Memory Traverse Tool

Walks the causal graph from a starting node using configurable depth and edge type filtering.

### Input Schema

```json
{
  "type": "object",
  "required": ["node_id"],
  "properties": {
    "node_id": { "type": "string" },
    "depth": { "type": "integer", "default": 2 },
    "edge_types": { 
      "type": "array",
      "items": { "type": "string" }
    }
  }
}
```

### Traversal Behavior

| Depth | Nodes Explored | Description |
|-------|----------------|-------------|
| 1 | Direct neighbors | Immediate causal relationships |
| 2 | Friends-of-friends | Secondary connections |
| N | N-level reach | Deeper causal chains |

Edge type filtering supports: `caused_by`, `supports`, `derived_from`, `reactivated`, `contradicts`

## Memory Explain Tool

Returns the score breakdown for a memory node, revealing why it exists and how it scores on each axis.

### Input Schema

```json
{
  "type": "object",
  "required": ["node_id"],
  "properties": {
    "node_id": { "type": "string" }
  }
}
```

### Score Components

The decay formula is multiplicative:

```
decay_score = relevance × connectivity × reactivation
```

| Component | Factor | Description |
|-----------|--------|-------------|
| Relevance | Time-based decay | How recently accessed |
| Connectivity | Causal weight | Number/type of edges |
| Reactivation | Frequency pattern | Recall history |

资料来源：[src/genesys_memory/models/node.py:15-45]()

## Pin/Unpin Memory Tools

Controls core memory status for individual nodes.

### pin_memory

```json
{
  "type": "object",
  "required": ["node_id"],
  "properties": {
    "node_id": { "type": "string" }
  }
}
```

Pinned memories are immune to automatic pruning. Setting `pinned=true` also sets `promotion_reason` to indicate manual promotion.

### unpin_memory

```json
{
  "type": "object",
  "required": ["node_id"],
  "properties": {
    "node_id": { "type": "string" }
  }
}
```

Unpinning triggers re-evaluation for automatic core promotion based on category preferences.

## List Core Memories Tool

Retrieves all memories marked as core (pinned or auto-promoted).

### Input Schema

```json
{
  "type": "object",
  "properties": {
    "category": { "type": "string" }
  }
}
```

### Response Structure

```json
{
  "cores": [
    {
      "id": "uuid",
      "content_summary": "...",
      "category": "project_context",
      "promotion_reason": "auto|manual",
      "pinned": true
    }
  ]
}
```

## Set Core Preferences Tool

Configures automatic core memory categorization rules.

### Input Schema

```json
{
  "type": "object",
  "properties": {
    "auto": { 
      "type": "array",
      "items": { "type": "string" }
    },
    "approval": { 
      "type": "array",
      "items": { "type": "string" }
    },
    "excluded": { 
      "type": "array",
      "items": { "type": "string" }
    }
  }
}
```

| Category | Behavior |
|----------|----------|
| `auto` | Auto-promoted to core when category matches |
| `approval` | Queued for user approval before promotion |
| `excluded` | Never auto-promoted, even if frequently accessed |

## Permission Model

All tools enforce permission checks before execution.

### Permission Hierarchy

```mermaid
graph TD
    A[Tool Call] --> B{_caller_uid set?}
    B -->|No| C[PermissionError]
    B -->|Yes| D{Node Owner?}
    D -->|Own| E[Allow]
    D -->|Admin + Org| F[Check Org Membership]
    F -->|Member| E
    F -->|Not Member| C
```

### Permission Functions

| Function | Purpose |
|----------|---------|
| `_caller_uid()` | Returns current user ID from context |
| `_caller_owns_node(node)` | Verifies ownership or admin org membership |
| `_is_edge_stale(edge)` | Checks if edge requires refresh |

资料来源：[src/genesys_memory/mcp/tools.py:25-50]()

## Visibility Levels

Memory nodes support three visibility levels:

| Level | Access | Description |
|-------|--------|-------------|
| `private` | Owner only | Personal memories |
| `org` | Organization members | Shared team context |
| `public` | All users | Knowledge base entries |

### promote_to_org Tool

Promotes a private memory to org visibility:

```json
{
  "type": "object",
  "required": ["node_id", "org_id"],
  "properties": {
    "node_id": { "type": "string" },
    "org_id": { "type": "string" },
    "action": {
      "type": "string",
      "enum": ["keep_private", "promote_all", "delete_links"],
      "default": "keep_private"
    },
    "dry_run": { "type": "boolean", "default": false }
  }
}
```

Actions:
- `keep_private`: Only this node becomes org-visible
- `promote_all`: All causally-linked nodes also promoted
- `delete_links`: Remove private edges before promotion

## Context Managers

The tools layer uses FastAPI-style context variables for multi-tenant support:

```python
current_user_id      # Active user identifier
current_org_ids      # List of user's org memberships
current_user_role     # "admin", "member", etc.
```

资料来源：[src/genesys_memory/context.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/context.py)

## Response Format

All tool responses are returned as `list[TextContent]` with type `"text"`:

```json
[
  {
    "type": "text",
    "text": "JSON serialized response"
  }
]
```

Error responses include structured error messages:

```json
[
  {
    "type": "text",
    "text": "Error: Permission denied for memory node abc-123"
  }
]
```

## Integration with MCP Transport

The stdio transport enables direct connection to Claude Desktop:

```bash
# Claude Desktop config
{
  "mcpServers": {
    "genesys": {
      "url": "http://localhost:8000/mcp"
    }
  }
}
```

Or for Claude Code CLI:

```bash
claude mcp add --transport http genesys http://localhost:8000/mcp
```

资料来源：[README.md:80-100]()

## Summary

The MCP Tools layer provides a complete interface for AI memory operations:

- **12 core tools** covering CRUD, traversal, and lifecycle management
- **Multi-tenant support** via context injection and permission checks
- **Three visibility levels** (private, org, public)
- **Hybrid search** combining vectors, keywords, and graph traversal
- **Core memory automation** via category-based promotion rules

---

<a id='configuration'></a>

## Configuration Guide

### 相关页面

相关主题：[Getting Started with Genesys](#getting-started)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this documentation:

- [.env.example](https://github.com/rishimeka/genesys/blob/main/.env.example)
- [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)
- [src/genesys_memory/engine/llm_provider.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/llm_provider.py)
- [src/genesys_memory/retrieval/embedding.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/retrieval/embedding.py)
- [src/genesys_memory/models/node.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/node.py)
- [src/genesys_memory/mcp/tools.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/mcp/tools.py)
</details>

# Configuration Guide

This guide covers all configuration options available in Genesys, including environment variables, storage backends, embedding providers, and LLM integration settings.

## Overview

Genesys supports multiple configuration options to accommodate different deployment scenarios, from local development with zero dependencies to production-grade deployments with persistent storage. Configuration is primarily driven by environment variables, with sensible defaults provided for most settings.

The configuration system enables:
- **Multi-backend storage**: Choose between in-memory, PostgreSQL, Obsidian vault, or FalkorDB
- **Flexible embedding**: Use OpenAI embeddings or local sentence-transformers
- **LLM integration**: Optional Anthropic API for memory consolidation and processing
- **Multi-tenancy**: Support for user and organization-level memory isolation

## Environment Variables Reference

### Core Configuration

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `OPENAI_API_KEY` | No* | - | OpenAI API key for embedding generation. Not required if `GENESYS_EMBEDDER=local` |
| `ANTHROPIC_API_KEY` | No | - | Anthropic API key for LLM-based memory processing (consolidation, contradiction detection) |
| `GENESYS_BACKEND` | No | `memory` | Storage backend: `memory`, `postgres`, `obsidian`, or `falkordb` |
| `GENESYS_EMBEDDER` | No | `openai` | Embedding provider: `openai` or `local` |
| `GENESYS_USER_ID` | No | - | Default user ID for single-tenant mode |
| `GENESYS_PERSIST_PATH` | No | - | File path for persisting state in memory backend mode |

*Required unless using local embedder

资料来源: [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

### Backend-Specific Configuration

| Variable | Required For | Default | Description |
|----------|--------------|---------|-------------|
| `DATABASE_URL` | `postgres` | - | PostgreSQL connection string (e.g., `postgresql://user:pass@localhost:5432/genesys`) |
| `OBSIDIAN_VAULT_PATH` | `obsidian` | Auto-detect | Path to your Obsidian vault directory |
| `FALKORDB_HOST` | `falkordb` | `localhost` | FalkorDB host address |
| `CLERK_SECRET_KEY` | Seed scripts | - | Clerk authentication secret for demo seeding |
| `CLERK_USER_ID` | Seed scripts | - | Clerk user ID for demo seeding |

资料来源: [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

## Storage Backends

Genesys is designed to work with multiple storage backends, each suited for different use cases.

### Backend Comparison

| Backend | Dependencies | Use Case | Persistence |
|---------|--------------|----------|-------------|
| `memory` | None | Local development, quick testing | Ephemeral (state lost on restart) |
| `postgres` | PostgreSQL + pgvector | Production deployments | Persistent |
| `obsidian` | Obsidian vault | Local-first knowledge management | File-based |
| `falkordb` | FalkorDB | Graph-native traversal | Persistent |

资料来源: [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

### Memory Backend (Default)

The in-memory backend requires no additional dependencies and is ideal for exploration.

```env
GENESYS_BACKEND=memory
```

To persist state across restarts:

```env
GENESYS_BACKEND=memory
GENESYS_PERSIST_PATH=.genesys_state.json
```

资料来源: [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

### PostgreSQL Backend

Requires PostgreSQL with pgvector extension for vector similarity search.

```env
GENESYS_BACKEND=postgres
DATABASE_URL=postgresql://genesys:genesys@localhost:5432/genesys
```

Start PostgreSQL with Docker:

```bash
docker compose up -d postgres
alembic upgrade head
uvicorn genesys.api:app --port 8000
```

资料来源: [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

### Obsidian Backend

Integrates directly with your Obsidian vault. Markdown files become memory nodes, and `[[wikilinks]]` become causal edges.

```env
GENESYS_BACKEND=obsidian
OBSIDIAN_VAULT_PATH=/path/to/your/vault
```

If `OBSIDIAN_VAULT_PATH` is not set, Genesys auto-detects by looking for `.obsidian/` in:
- `~/Documents/personal`
- `~/Documents/Obsidian`
- `~/obsidian`

资料来源: [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

### FalkorDB Backend

Uses FalkorDB (Redis-based graph database) for native graph traversal.

```env
GENESYS_BACKEND=falkordb
FALKORDB_HOST=localhost
```

Start FalkorDB:

```bash
docker compose up -d falkordb
uvicorn genesys.api:app --port 8000
```

资料来源: [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

## Embedding Configuration

### OpenAI Embeddings (Default)

Uses OpenAI's embedding models for vector representation.

```env
GENESYS_EMBEDDER=openai
OPENAI_API_KEY=sk-...
```

### Local Embeddings (No API Key Required)

Uses `sentence-transformers` for fully local embedding generation. Downloads `all-MiniLM-L6-v2` (~80 MB) on first use.

```env
GENESYS_EMBEDDER=local
```

For local Obsidian mode with zero external dependencies:

```env
GENESYS_BACKEND=obsidian
GENESYS_EMBEDDER=local
OBSIDIAN_VAULT_PATH=/path/to/your/vault
# No OPENAI_API_KEY needed
```

资料来源: [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

## Memory Node Model

The core data model for memories in Genesys. Key configuration-related fields:

```python
class MemoryNode(BaseModel):
    id: uuid.UUID = Field(default_factory=uuid.uuid4)
    status: MemoryStatus = MemoryStatus.ACTIVE
    content_summary: str = Field(max_length=200)
    content_full: str | None = None
    embedding: list[float] | None = None
    
    # Timestamps
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    last_accessed_at: datetime
    last_reactivated_at: datetime
    
    # Lifecycle scores
    decay_score: float = 1.0
    causal_weight: int = 0
    reactivation_count: int = 0
    
    # Core memory
    pinned: bool = False
    promotion_reason: str | None = None
```

资料来源: [src/genesys_memory/models/node.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/models/node.py)

## LLM Provider Configuration

The LLM provider handles memory consolidation and causal relationship detection.

### Causal Link Detection

When storing new memories, the LLM provider can automatically identify causal relationships with existing memories:

```python
prompt = (
    "Given a new memory and a list of existing memories, identify causal relationships.\n\n"
    f"New memory: {new_memory}\n\nExisting memories:\n{mem_lines}\n\n"
    "For each causal relationship found, specify:\n"
    "- target_id: the ID of the existing memory\n"
    '- edge_type: one of "caused_by", "supports", "derived_from"\n'
    "- confidence: 0.0 to 1.0\n"
    "- reason: brief explanation of why this relationship exists\n\n"
    "Only include relationships with confidence > 0.6.\n"
    "Respond with ONLY a JSON array of objects, no other text."
)
```

Configuration requires `ANTHROPIC_API_KEY` for LLM-based processing. Edge types include:
- `caused_by`
- `supports`
- `derived_from`

资料来源: [src/genesys_memory/engine/llm_provider.py](https://github.com/rishimeka/genesys/blob/main/src/genesys_memory/engine/llm_provider.py)

## MCP Server Configuration

The MCP (Model Context Protocol) server exposes Genesys functionality as tools. Configure the MCP endpoint in your AI client's configuration.

### Claude Desktop

Add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "genesys": {
      "url": "http://localhost:8000/mcp"
    }
  }
}
```

### Claude Code

```bash
claude mcp add --transport http genesys http://localhost:8000/mcp
```

### MCP Tools Available

| Tool | Description |
|------|-------------|
| `memory_store` | Store a new memory, optionally linking to related memories |
| `memory_recall` | Recall memories by natural language query (vector + graph) |
| `memory_search` | Search memories with filters (status, date range, keyword) |
| `memory_traverse` | Walk the causal graph from a given memory node |
| `memory_explain` | Explain why a memory exists and its causal chain |
| `memory_stats` | Get memory system statistics |
| `pin_memory` | Pin a memory so it's never forgotten |
| `unpin_memory` | Unpin a previously pinned memory |
| `delete_memory` | Permanently delete a memory |
| `list_core_memories` | List core memories, optionally filtered by category |
| `set_core_preferences` | Set user preferences for core memory categories |

资料来源: [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

## Quick Start Configurations

### Minimal Setup (Zero Dependencies)

```env
# No .env file needed - defaults work out of the box
```

```bash
pip install genesys-memory
uvicorn genesys.api:app --port 8000
```

### Fully Local with Obsidian

```env
GENESYS_BACKEND=obsidian
GENESYS_EMBEDDER=local
OBSIDIAN_VAULT_PATH=/path/to/your/vault
```

### Production with PostgreSQL

```env
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
GENESYS_BACKEND=postgres
DATABASE_URL=postgresql://genesys:genesys@localhost:5432/genesys
```

### Multi-Tenant with Organizations

```env
OPENAI_API_KEY=sk-...
GENESYS_BACKEND=postgres
DATABASE_URL=postgresql://genesys:genesys@localhost:5432/genesys
```

资料来源: [README.md](https://github.com/rishimeka/genesys/blob/main/README.md)

## Configuration Flow

```mermaid
graph TD
    A[Application Start] --> B{Load Environment Variables}
    B --> C{GENESYS_BACKEND?}
    C -->|memory| D[In-Memory Storage]
    C -->|postgres| E[PostgreSQL + pgvector]
    C -->|obsidian| F[Obsidian Vault]
    C -->|falkordb| G[FalkorDB]
    
    H{GENESYS_EMBEDDER?}
    H -->|openai| I[OpenAI Embeddings]
    H -->|local| J[Local sentence-transformers]
    
    D --> K[Initialize MCP Server]
    E --> K
    F --> K
    G --> K
    
    I --> L[Ready]
    J --> L
    
    K --> M[Register Tools]
    M --> L
```

## Engine Thresholds

Engine thresholds such as decay rates, scoring multipliers, and transition thresholds are configurable through environment variables. These values are defined in `engine/config.py` and should not be hardcoded.

For the most current threshold configurations, refer to the source file:

```python
# Refer to src/genesys_memory/engine/config.py for threshold values
```

资料来源: [CONTRIBUTING.md](https://github.com/rishimeka/genesys/blob/main/CONTRIBUTING.md)

## See Also

- [Contributing Guide](CONTRIBUTING.md) - Development setup and coding standards
- [README.md](README.md) - Project overview and features
- [Benchmarks](../benchmarks/) - Performance testing configurations

---

---

## Doramagic 踩坑日志

项目：rishimeka/genesys

摘要：发现 7 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：配置坑 - 可能修改宿主 AI 配置。

## 1. 配置坑 · 可能修改宿主 AI 配置

- 严重度：medium
- 证据强度：source_linked
- 发现：项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。
- 对用户的影响：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。
- 建议检查：列出会写入的配置文件、目录和卸载/回滚步骤。
- 防护动作：涉及宿主配置目录时必须给回滚路径，不能只给安装命令。
- 证据：capability.host_targets | github_repo:1207565616 | https://github.com/rishimeka/genesys | host_targets=mcp_host, claude

## 2. 能力坑 · 能力判断依赖假设

- 严重度：medium
- 证据强度：source_linked
- 发现：README/documentation is current enough for a first validation pass.
- 对用户的影响：假设不成立时，用户拿不到承诺的能力。
- 建议检查：将假设转成下游验证清单。
- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。
- 证据：capability.assumptions | github_repo:1207565616 | https://github.com/rishimeka/genesys | README/documentation is current enough for a first validation pass.

## 3. 维护坑 · 维护活跃度未知

- 严重度：medium
- 证据强度：source_linked
- 发现：未记录 last_activity_observed。
- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。
- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。
- 证据：evidence.maintainer_signals | github_repo:1207565616 | https://github.com/rishimeka/genesys | last_activity_observed missing

## 4. 安全/权限坑 · 下游验证发现风险项

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：下游已经要求复核，不能在页面中弱化。
- 建议检查：进入安全/权限治理复核队列。
- 防护动作：下游风险存在时必须保持 review/recommendation 降级。
- 证据：downstream_validation.risk_items | github_repo:1207565616 | https://github.com/rishimeka/genesys | no_demo; severity=medium

## 5. 安全/权限坑 · 存在评分风险

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：风险会影响是否适合普通用户安装。
- 建议检查：把风险写入边界卡，并确认是否需要人工复核。
- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。
- 证据：risks.scoring_risks | github_repo:1207565616 | https://github.com/rishimeka/genesys | no_demo; severity=medium

## 6. 维护坑 · issue/PR 响应质量未知

- 严重度：low
- 证据强度：source_linked
- 发现：issue_or_pr_quality=unknown。
- 对用户的影响：用户无法判断遇到问题后是否有人维护。
- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。
- 防护动作：issue/PR 响应未知时，必须提示维护风险。
- 证据：evidence.maintainer_signals | github_repo:1207565616 | https://github.com/rishimeka/genesys | issue_or_pr_quality=unknown

## 7. 维护坑 · 发布节奏不明确

- 严重度：low
- 证据强度：source_linked
- 发现：release_recency=unknown。
- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。
- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。
- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。
- 证据：evidence.maintainer_signals | github_repo:1207565616 | https://github.com/rishimeka/genesys | release_recency=unknown

<!-- canonical_name: rishimeka/genesys; human_manual_source: deepwiki_human_wiki -->
