Skip to main content
Glama

Seahorse

CI License Python versions PyPI version Release

Долговременная, битемпоральная память для LLM-агентов — локально-ориентированная, нативная для MCP, читаемая в Obsidian.

pip install seahorse-memory
seahorse init myvault && seahorse remember "Sergio lives in Madrid"
seahorse recall "where does Sergio live?"

Зачем

LLM-агенты начинают каждую сессию с нуля. Контекстное окно — не память: это черновик, который сбрасывается, и он слишком мал, чтобы вместить то, что агент узнал за недели работы. Инструменты, которые пытаются это исправить, имеют свои проблемы:

  • Они сильно забывают. Большинство систем памяти бесконечно накапливают факты и никогда не разрешают противоречия — агент «помнит», что пользователь живёт одновременно в Мадриде и Барселоне, и нет никакого способа понять, что актуально сейчас.

  • Они непрозрачны. Память живёт внутри проприетарной базы данных, которую человек не может прочитать, отредактировать или проверить. Если агент ошибся, исправить ошибку невозможно.

  • Их дорого наполнять. Каждый эпизод проходит через LLM, поэтому запись тысяч мелких фактов стоит реальных денег.

  • Они привязывают вас. Внедрение системы памяти часто означает принятие её рантайма, провайдера или экосистемы.

  • Их бенчмаркам нельзя доверять. Собственные результаты самой области трудно воспроизвести: в бенчмарке LOCOMO 6.4% ошибочных эталонных ответов, репродукция результatlors Mem0 сломана (issue #2800), a sklearn MTEB-эмбеддинг не предсказывает качество поиска по памяти, того же (LMEB, arXiv 2603.12572).

Seahorse — это другой подход: открытый, переносимый, битемпоральный стандарт памяти, который агент пишет и читает, который человек может прочитать и исправить и который не запирает вас ни в какой рантайм и провайдер.

Related MCP server: agentcairn

Кому подходит

  • Развиватели, создающие агентов (Claude Code, Cursor, Codex или вашим собственным) — которые хотят, чтобы агент помнит решения и контекст между сессиями.

  • Опытные пользователи Obsidian, которые хотят, чтобы их заметки были не просто статическим архивом, а базой знаний, которую агент может запрашивать и обновлять.

  • Команды, которым нужна переносимая память — формат, который можно переносить между вендорам, не проматывая историю заново.

Пример: Claude Code с долговременной памятью

Быстрее всего увидеть Seahorse в действии — дать Claude Code память, которая сохраняется между сессиями. Три шага:

1. Захват сессий. Команда seahorse setup ставит хуки-наблюдателя в ~/.claude/settings.json; seahorse observe start запускает фоновый процесс записи. Каждая сессия фиксируется в виде эпизодов — режим skip-first (почти нулевая стоимость), с удалением чувствительных данных и обобумённой сводкой.

seahorse setup
seahorse observe start

2. Вспоминание между сессиями. Хук SessionStart впрыскивает seahorse context в следующую сессию, так что агент начинает с того, что узнал раньше. Спросить напрямую можно командой seahorse recall:

seahorse context
seahorse recall "what did we decide about the API design?"

3. Принесите свою память. Если вы уже используете claude-mem, seahorse import переносит его наблюдения в канонические эпизоды — без повторного проигрывания из логов и без блof:

seahorse import --mode commit

Ключевое отличие: агент пишет в то же хранилище, которое вы редактируете в Obsidian. Каждый эпизод — это файл в Markdown с YAML-frontmatter: читаемый, редактируемый, поддаваться диффу в git и аудиту человеком. Память агента — не чёрный ящик; это ваши заметки.

Подключение из агента (MCP)

Seahorse построен для агентов: поверхность памяти — это вами stdio-сервер MCP (io.seahorse.memory/v1, любой агент, говорящий из протокола MCP. CLI предназначен для людей и скриптов; агенты общаются с се dvseahorse-mcp.

Зарегистрируйте сервер в Claude Code (локальная область видимого окружения — используется по умолчанию):

claude mcp add seahorse-mcp -- uvx --from seahorse-memory seahorse-mcp --vault "${HOME}/myvault"

Обязателен --: он отделяет собственные флаги Claude от команды сервера. --scope project .mcp.json даёт возможную команду. Проверка — через claude mcp list (должно показывать ✔ Connected) и ``claude mcp get seahorse-mcp`.

Или настройте его в .mcp.json в корне проекта (работает с любым MCP-клиентом):

{
  "mcpServers": {
    "seahorse-mcp": {
      "type": "stdio",
      "command": "uvx",
      "args": ["--from", "seahorse-memory", "seahorse-mcp", "--vault", "${HOME}/myvault"]
    }
  }
}

Примечание: в .mcp.json тильды ~ не раскрываются — используйте $\{HOME} или абсолютный путь. (mcpServers в settings.json молча игнорируется; MCP-серверы для пользовательской/локальной области хранятся в ~/.claude.json, а для области проекта — в .mcp.json.)

После подключения агент видит 14 инструментов памяти — remember, recall, recall_timeline, recall_full, improve, forget, build_pit, skill_add, skill_show, skill_list, skill_search, freshness_view, audit_log, `follow_supersedes_chain(см. Поверхность агента).

Наблюдатель (seahorse setup) — это отдельный компонент: он захватывает сессии Claude Code в эпизоды. MCP-сервер — это то, как агент читает и пишет память. Оба компонента работают вместе: сначала захватку сессий, затем вспоминания по ним.

Как это работает

graph LR
    A[Claude Code / any MCP agent] -- stdio MCP io.seahorse.memory/v1 --> S[seahorse-mcp]
    S --> E[Bi-temporal engine]
    E --> DB[(sqlite3 + sqlite-vec + FTS5)]
    E --> V[Obsidian vault: markdown + F3.1 frontmatter]
    H[Human in Obsidian] --> V

Агент общается с seahorse-mcp через stdio MCP. Движок хранит каждый эпизод дважды: в один — в однофайловой SQLite-базе (sqlite-vec для векторного поиска, FTS5 для полнотекстового поиска), второй — в файл и уговор с frontmatter F3.1 в хранилище. Человек редактирует те же файлы Markdown. Формат версионируется и описан в docs/f3.1-format.md.

Быстрый старт

# Install (PyPI):
pip install seahorse-memory
# …or with uv:
uv tool install seahorse-memory
# For hybrid semantic retrieval (FastEmbed ONNX, downloads mE5-small on first
# embed): pip install "seahorse-memory[embeddings]"
# For the multi-LLM extraction path (LiteLLM): pip install "seahorse-memory[llm]"

# Create a vault and write your first episode:
seahorse init myvault
seahorse remember "Sergio lives in Madrid" --title home
seahorse recall "madrid"

# Improve and forget (append-only; history is preserved):
seahorse improve <ep_id> "Sergio lives in Barcelona" --reason correction
seahorse forget <ep_id> --reason done

# Session capture, context, and consolidation:
# Install the observer (writes [observe] + merges the Claude Code hooks into
# ~/.claude/settings.json):
seahorse setup
# Start the observer (unix socket + worker), then the next session is captured
# automatically (skip-first, redacted, deterministic summary):
seahorse observe start
seahorse observe status
# Bootstrap context by recency (the SessionStart hook injects this):
seahorse context
# Distill recurrent episodes into semantic knowledge notes (N≥3, idempotent):
seahorse consolidate
# Remove the observer:
seahorse setup --uninstall

# Serve an agent over stdio MCP (io.seahorse.memory/v1):
seahorse-mcp --vault myvault
# …equivalently:
seahorse mcp --vault myvault

Консольный скрипт seahorse — для людей и скриптов (shell); seahorse-mcp — для агентов. Подкоманда seahorse mcp запускает тот же stdio-сервер, что и seahorse-mcp`, так что оба того, как точки входа равнозначны. Подключение агента — см. Подключение из агента.

Предварительные требования

  • Python ≥ 3.11 (подходит любой свежо 3.11/3.12/3.13). Модуль sqlite3 интерпретатора должен поддерживать enable_load_extension (для этого требует sqlite-vec); почти все стандартные сборки так и есть — seahorse doctor отчитается об этом FAIL, если это не так.

  • Obsidian не обязателен. Seahorse работает в любой папке с Markdown — seahorse init создаёт служебную папку .seahorse/ в обычной папке. Obsidian — человеческий редактирование для той же папки; её каталог .obsidian/ игнорируется Seahorsое и никогда не потребуется.

Миграция существующего хранилища Obsidian

Хранилище с заметками Obsidian, созданными ранее (без frontmatter или со старым полями classье created), пока не находится в каноническом формате — seahorse index rebuild честно падают на таких заметках. seahorse frontmatter migrate преобразует их:

# Preview: classify every note, write nothing (always exit 0):
seahorse frontmatter migrate --vault myvault --dry-run
# Apply: convert legacy notes, leave canonical notes untouched, refuse
# incompatible notes:
seahorse frontmatter migrate --vault myvault
# Rebuild the sidecar index from the converted notes:
seahorse index rebuild --vault myvault

Применение завершается кодом 97, когда показывает несовместимые заметки блокируют полную миграцию — сначала печатается сводка манифеста, чтобы оператор увидел, какие заметки требуют ручного разрешения. --resume пропускает заметки, не изменившиеся с прошлого манифеста; --batchРайф-статы задаёт кадаст, как часто проставляются точки реакции в манифесте. Миграция работает до сессии seahorse init (она затрагивает только .md-файл(и + манифест).

Первый запуск: модель семантических эмбеддингов (mE5-small, ~235MB) скачивается лениво при первом вызове remember/recall — CLI объявляет об этом, чтобы первый вызов не выглядел зависшим. seahorse status показывает активный режим поиска: hybrid RRF (модель кэширована)vscurrent-state listing — установите seahorse-memory[embeddings] для семантической выборки`.

Сравнение с другими инструментами памяти

Сравнение основано на проверяемых фактах, а не на рейтинге. Источники: анализ уровня области внутри проекта (исследовательские полностью) — research notes — и утверждения, указанные ниже.

| | Seahorse | Mem0 | Letta / MemGPT | Zep / Graphiti | claude-mem | LangMem | | ------------------------------- | ----------------- | ---------------- ------ | ------------------- | -------------- | ------------- | ---------- | | Переносимый открытый формат | ✓ спецификация F3.1 | ✗ фирменный | ✗ привязка к рантайму | ✗ | ✗ своя схема | ✗ | | Человекочитаемый слой | ✓ хранилище Obsidian | ✗ | ✗ | ✗ | ✗ | ✗ | | Битемпоральность (точка во времени) | ✓ | ~ | ~ | ✓ Graphiti | ✗ | ✗ | | Локальный приоритет, без инфраструктуры | ✓ | ~ | ~ | ✗ только облако | ✓ | ~ | | Воспроизводимый бенчмарк | ✓ каркас в репозитории | ✗ #2800 | — | — | — | — | | Лицензия | Apache-2.0 | Apache-2.0 (open-core) | Apache-2.0 | Apache-2.0 | AGPL | Apache-2.0 |

Значки: ✓ да ~~· частично ✗ нет · — не поддается проверкам.

Два важнейших факта: у mem0 монетизируются функции, которые дают им результаты бенчмарков, и Zep отказался от локального проживания в пользу облака. Seahorse по умолчанию работает локально, публика базы для бенчмарков в своих репозиториях и держит формат памяти открытым — вы никогда не заперт.

Бенчмарк

Seahorse по признанию (поставляется) с воспроизводимым измерительным стендом (LMEB)pple-S ~ подвыборкой подбенчмарка LongMemEval) и публикует свои цифры — с оговорками. Цель не в рейтинг таблица, а честное и воспроизводимое измерение.

Метрика

Значение

Примечание

recall@10

0.13

срез обновления знаний: 0.44

ndcg@10

0.11

mrr

0.13

срез обновления знаний: 0.47

precision@10

0.02

токенная принятость

0.998

51.5M токенов полным контексте → 121K измерено

latency p95 (INDEX)

42 мс

только поиск, без реранки

Оговорки: этот прогон использует подвыборку (n≈470–500 вопросов, т.е. неполный набор данных); релевантность оценивается небольшой LLM, без проверки человеком; и это оценивает только извлечение, а не итоговый ответ агента. Проверялось и было отклонено — кросс-энкодерное реранжирование — оно снизило recall@10 до 0.11 с лаунценсиеся особенности во time 1.2 с. Полная методология и команды воспроизведения — в docs/benchmark.md.

Приведённые цифры измеряют только ранжирование поисковой выдачи на подвыборке к маленьком оценку, поэтому они не соответствуют . несопоставимы с результатами точности end-to-end, которые публикуют другие системы памяти (например, Graphiti 63.8%, M-chem0 94.8, Hindsight 91.4%). О том, как не нужно действовать, — в docs/benchmark.md.

Век — ЧАВО

Что такое эпизод? Одна запись памяти — это файл Markdown с YAML-frontmatter, содержащий две временнющие оси: ось (valid_at — когда он занял силу) и тему — ось created_at — когда был записан), происхождение и когнитивный тип. Формат версионифицирован и описан в docs/f3.1-format.md.

Почему Obsidian? Потому что память является иерархией в человеческой системе памяти. Агенты пишут в то же хранилище, которое вы редактируете: Markдown читают, дифф отдельных, с целью хранения ревизии. Если агент неправа — вы исправляете БДных заметку, а не базу.

Чем это отличается от claude-mem? claude-mem хранит наблюдения сессий в своей собственной схеме. Seahorse — открытый битемпоральный стандарт с переносимым форматом и человекочитаемым слоя, в также seahorse import переносит наблюдения claude-mem в канонические эпизоды — значит, это мост, а не конкурент.

Нужен ли мне LLM? Нет. Детерминированный skip-path остаётся стандартным для основной массы записей (почти нулевая стоимость). Извлечение через LLM опционально (seahorse-memory[llm]) и зарезервировано для тех немногих эпизодов, которые этого оправдывают.

Это бесплатно? Да. Apache-2.0, local-first, zero-infra. Управляемый SaaS и корпоративный тариф планируются в будущем (см. стратегические заметки проекта).

Как внести вклад? См. CONTRIBUTING.md — настройка окружения, команды тестов/линта и процесс pull request.

Дорожная карта

См. ROADMAP.md, чтобы узнать, что уже реализовано, что дальше и в каком направлении движется проект. История релизов — в CHANGELOG.md.

Агентский интерфейс — 7 примитивов памяти + 7 процедурных/read-only инструментов

Доступен через stdio MCP (io.seahorse.memory/v1, протокол закреплён 2025-11-25) и продублирован в CLI. Это примитивы памяти, а не обычный CRUD: агент вызывает remember / recall / improve / forget так, как человек говорит о памяти.

Первые 7 примитивов (запись + возврат):

Примитив

Что делает

remember

Записывает эпизод (тело, источник, опциональные заголовок/тему).

recall

Уровень INDEX — перечень текущего состояния, ограниченный top_k.

recall_timeline

Уровень TIMELINE — цепь supersedes вокруг опорного эпизода.

recall_full

Уровень FULL — полный эпизод со всем метаданными происхождения.

improve

Заменяет эпизод исправленной версией (append-only).

forget

Мягко удаляет эпизод (append-only; история сохраняется).

build_pit

Создаёт проекцию на момент времени (все None → текущее состояние).

Плюс 7 процедурных / read-only инструментов (навыки + интроспекция фасада):

Инструмент

Что делает

skill_add

Создаёт процедурный навык (детерминированно, почти нулевая стоимость).

skill_show

Показывает закрытое тело навыка (trust gate).

skill_list

Перечисляет процедурные навыки (уровень Discovery).

skill_search

Ищет процедурные навыки (гибридный возврат, процедурный фильтр).

freshness_view

Снимок свежести эпизода (возраст, устаревание, pending_ingest).

audit_log

События аудита эпизода (история пути записи).

follow_supersedes_chain

Замыкание supersedes для эпизода (история версий).

Три уровня возврата дают прогрессирующее раскрытие: сначала дешёвый перечень (INDEX), затем цепочка типов по запросу (TIMELINE) и полная запись только при необходимости (FULL). Это сохраняет обычный путь дешёвым.

Что работает

  • Битемпоральное, append-only хранилище эпизодов на stdlib sqlite3 + sqlite-vec (FTS5

    • vec0). Автомигрирующая схема.

  • Семь примитивов памяти плюс семь процедурных / read-only инструментов в CLI и stdio MCP (всего 14 инструментов).

  • Прогрессивное раскрытие (INDEX / TIMELINE / FULL) и проекция на момент времени.

  • Гибридный семантический поиск: recall ранжирует по релевантности — sqlite-vec kNN + FTS5 BM25, объединённые через Reciprocal Rank Fusion, с маршрутизацией по времени (state_at / known_at), когда подключён настоящий эмбеддер. Путь записи и seahorse index rebuild заполняют vec0/FTS (best-effort — выход эмбеддера не приводит к потере записи эпизода).

  • Честная деградация: без embeddings extra (пустая или частично пустая), recall возвращается к списку текущего состояния (score 0.0, без ранжирования), а динамический поиск возврата отключается — движок продолжает работать без ранжирования.

  • Опциональное ослабляющее ранжирование (по умолчанию выкл.): кривая забывания в стиле FAMA/Эббингауза устаревает знания с (score' = score · 2^(-age/half_life)), с приоритетами по типу. По умолчанию выключено: чистая RRF-подпись остаётся бит-сопоставимой.

  • Извлечение через LLM: настоящий мульти-LLM путь (ollama / gemini / groq / openrouter / openai / anthropic / deepseek / vllm, local-first) со строгим валидатором схемы + циклом исправления, цепочкой повторов/фолбэков и рабочим ограничением стоимости (локальные и дешёвые модели стоят $0). seahorse init --llm его запускает; путь пропускающ без оплаты default для обычных записей.

  • Локальный CI-гейт: реальный путь извлечения в CI работает против самой слабой моделью семейства (ollama/qwen3:0.6b), так что валидатор + восстановитель вынуждены справляться полностью — путь не зависит объясняющих от нативного структурированного вывода или сильной тройки.

  • Замещение (improve) и мягкое удаление (forget) с полной историей сохранения.

  • Пакетная дистилляция (seahorse consolidate): превращает много эпизодов в единую консолидированную заметку — по умолчанию детерминированно, с опциональным LLM-синтезом (--synthesis llm) и плата supersedes (--supersede), так что консолидированная заметка замещает свои исходники.

  • Frontmatter импорт/экспорт для уровня Obsidian-хранилища (markdown как человекочитаемый, переносимый контракт на диске).

  • Миграция legacy хранилища: seahorse frontmatter migrate преобразует устаревшие заметки Obsidian с --dry-run предпросмотром, --resume и честным кодом выхода 97, когда несовместимые заметки блокируют полную миграю.

  • Честные коды выхода и структурированная оболочка {"error": {...}} в stderr, чтобы агенты и сценарии могли детерминированно разветвляться по seahorse_code / cli_code.

Несколько CLI-команд настроены, но намеренно возвращают код выхода 75 с причиной (expire, revalidate, index verify), чтобы преднамеренно было честно, что реализовано, а не сорканный пробег. llm_partial остаётся полностью детерминированным.

Стек

  • Python ≥ 3.11. stdlib sqlite3 + sqlite-vec для хранения данных (без инфраструктуры, один файл; виртуальная таблица vec0 + FTS5).

  • numpy для формы блоба эмбеддингов.

  • Pydantic v2 для канонического контракта Episode (ядровая система типов).

  • Typer для встроенной оболочки CLI (люди и сценарии). Ограничен пакетом seahorse.cli.

  • stdio JSON-RPC 2.0 для MCP частей агента (ручной фрейминг, только стандартный набор seahorse.mcp — import seahorse.mcp не загружает Typer).

  • ruamel.yaml + python-frontmatter, ограничены адаптером frontmatter.

  • FastEmbed ONNX + onnxruntime (extra embeddings, НЕ включено в стандартный install): пакет mE5-small по умолчанию использует model_O6.onnx (fp32, ~235MB) — никакой int8/fp16 артефакт не распространяется на Apple Silicon, и открытый стандарт должен работать на Windows/Linux/macOS. Портатив пакет int8 — контрольный исследуемый.

  • LiteLLM (llm extra, НЕ предлагает в default install): объединяет больше 100 провайдеров для LLM-инструмента. Без extra пакет seahorse.llm всё ещё импортируется (контракт + StubLLMClient), а реальный путь плавно деградирует к llm→skip с подсказкой по настройке.

Стек FastAPI / SQLAlchemy / Postgres заложен для будущего многоагентного уровня (Postgres + pgvector). README соответствует тому, что уже готово сейчас, а не целевой архитектуре.

Тестирование

  • Unit + интеграционные: noc run pytest (покрытие ≥ 80%).

  • Свежий-пользователь e2e: scripts/e2e-fresh-user.sh — полный путь установки → инициализация → core CLI → embeddings → LLM → импорт → MCP-поток из чистой, изолированной HOME (никогда не касается реальных ~/.claude / ~/.claude-mem).

  • Матрица окружений: scripts/e2e-matrix.sh — поток нового пользователя по сочетаниям параметров (install method × extras × Obsidian × Ollama × online/offline × состояние vault × параллелизм). --ci-subset запускает безопасные для CI комбинации (core_min + uv_sync_dev); --list показывает все комбинации.

  • Стресс core: scripts/stress-core.sh — приём 1000+ эпизодов, возврат --top-k 100 p95 ≤ 50ms (встроенный бюджет INDEX), concurrent single-writer, переиндексация, идемпотентный импорт, цикл улучшение/удаление.

Участие

Вклады приветствуются. См. CONTRIBUTING.md для настроек разработчика, команд тестирования/линков и процесса pull request. История релизов — в CHANGELOG.md.

Лицензия

Apache-2.0. См. LICENSE.

Текущий статус

v0.10.0. Механический движок работает end-to-end с чистой установки: запись эпизодов, их возврат через гибридное семантическое опознавание, извлечение через реальный мульти-LLM путь (local-first, CI-n-проверяемый), улучшение и удаление записей, а также обслуживание агента через MCP. recall ранжирует по релевантности, когда векторы загружены и эмбеддер установлен, и честно откатывается до простого перечня в остальных случаях. Опциональное весовое затухание (по умолчанию выкл.) устаревает знания по возрасту. seahorse import переносит observationы claude-mem в эпизоды, а пакетная дистилляция (seahorse consolidate`) превращает много эпизодов в одну итоговую заметку с опциональным LLM-синтезом и улучшением. Харбор для контроля есть в репозитории с предостережениями и командами воспроизведения в docs/benchmark.md. См. Что и ROADMAP.md для ближайших планов.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Local-first, file-based memory layer for AI agents — one shared Markdown vault across Claude, Codex, Gemini, Cursor and any MCP client. Provides read/write memory tools with an audit trail, per-agent trust levels, and Git sync; no cloud and no lock-in.
    2
    MIT
  • A
    license
    B
    quality
    A
    maintenance
    agentcairn is a local-first memory MCP server: your agent's memories live as Markdown in an Obsidian vault you own — the source of truth — with a rebuildable DuckDB index providing fast hybrid BM25 + vector + graph recall. It exposes tools to capture, recall, and manage those memories (non-lossy, with secret redaction) and works the same across Claude Code, Codex, Cursor, and any MCP host.
    5
    392 PyPI
    69
    Apache 2.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    Local-first, source-grounded memory for AI agents, with citations, bitemporal history, review-gated corrections, and MCP tools for search and recall.
    46 PyPI
    3
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Durable memory with sources, proof, history, and review for MCP-capable agents. It turns a Markdown/Obsidian vault into a local knowledge substrate, enabling agents to store, search, and retrieve governed knowledge.
    42,624 PyPI
    9
    AGPL 3.0