Skip to main content

memobase

❖ Community★ 1

Memobase memory provider — self-hosted user profile + event timeline recall, with hybrid BM25/vector/entity retrieval and automatic per-turn prefetch.

Open in Hermes Desktop
hermes plugins install memobase

What it adds

Environment variables it needs 2

MEMOBASE_API_KEYMEMOBASE_BASE_URL

README

From the reviewed commit 4e8e447 ↗; it updates when the author re-pins.

Memobase Memory Provider for Hermes Agent

A Hermes Agent memory provider plugin that connects the MemoryProvider lifecycle to a self-hosted Memobase server (FastAPI + PostgreSQL + pgvector). Memobase stores a user profile (ontology-based topics) plus an append-only event timeline, extracted offline by an LLM when the buffer flushes.

This plugin gives the agent automatic per-turn recall instead of model-discretion search: every turn, relevant memories are prefetched and injected into context, and the completed turn is written back for background profile extraction.

How it works

When the provider is active, Hermes automatically:

  1. prefetch(query) — recalls the user profile + recent event timeline for the current user message and injects it into context (Memobase's /users/context assembly; hot path < 100 ms).
  2. sync_turn(user, asst) — inserts the completed turn into Memobase's buffer for background LLM profile extraction (auto-flush at the buffer threshold).
  3. Exposes memobase_search / memobase_profile tools as an on-demand backstop.

Hybrid retrieval (v3)

Recall is not a single vector lookup. The context endpoint is queried with a fixed budget, and the plugin runs its own three-leg hybrid retrieval locally over the returned event window:

Leg Signal Purpose
bm25 Okapi BM25 over CJK-bigram + latin tokens exact term / keyword match
vec Memobase's own embeddings semantic match
entity inverted index over extracted entities proper nouns, file paths, IPs, domains, IDs, quoted strings, book titles

The three ranked lists are fused with Reciprocal Rank Fusion (RRF), then refined by two optional passes:

  • Temporal boost — when the query contains a time expression (今天 / 昨天 / 上周 / 3天前 / …), events inside the parsed window are multiplied by temporal_gain; events outside decay exponentially with temporal_half_life_days, floored at temporal_floor.
  • Conditional rerank (opt-in) — a cross-encoder rerank pass fires only when the fused score distribution is low-discrimination (i.e. the ranking is too flat to trust), so a clear-cut ranking never pays the latency cost. It runs only when you configure both rerank_base_url and rerank_api_key. There is no default endpoint, so an unconfigured install makes no outbound request to any host but your own Memobase server.

Tunable through $HERMES_HOME/memobase.json — see the module docstring in __init__.py for the full list (hybrid_enabled, hybrid_keep, temporal_*, entity_boost_enabled, rerank_*, timezone, …).

CJK proper nouns

The entity leg recognizes structured entities (paths, IPs, domains, camel case, quoted text) out of the box. Personal names are deployment-specific, so the public build ships no name list. Add your own:

{
  "cjk_known_names": ["Alice", "Bob"]
}

Empty (the default) is fine — everything else still works.

Requirements

  • A running Memobase server (>= 0.0.42) with a bearer token.
  • Hermes Agent with the memory-provider plugin system (any recent build).

Install

Drop this repository's files into ~/.hermes/plugins/memobase/ (user-level memory provider discovery path), or clone it there:

mkdir -p ~/.hermes/plugins/memobase
git clone https://github.com/fred0m/hermes-memobase-provider.git ~/.hermes/plugins/memobase

Then configure:

# ~/.hermes/.env
MEMOBASE_BASE_URL=http://<your-memobase-host>:8019/api/v1
MEMOBASE_API_KEY=<your-memobase-token>
# optional: MEMOBASE_USER_NAME=user   (maps to uuid5(NAMESPACE_DNS, name+"memobase_client"))

Enable the provider:

hermes config set memory.provider memobase
hermes gateway restart
hermes memory status   # → Provider: memobase / Plugin: installed / Status: available

Behavioral settings may live in ~/.hermes/memobase.json:

{
  "prefetch_max_tokens": 2000,
  "prefetch_wait_secs": 5,
  "fill_window_events": true,
  "time_range_days": 180,
  "hybrid_enabled": true,
  "hybrid_keep": 10,
  "temporal_boost_enabled": true,
  "temporal_gain": 1.6,
  "temporal_half_life_days": 30,
  "temporal_floor": 0.6,
  "timezone": "Asia/Shanghai",
  "cjk_known_names": [],
  "rerank_base_url": "",
  "rerank_api_key": ""
}

API surface used

Lifecycle Endpoint
prefetch / memobase_search GET /users/context/{user_id}?max_token_size=…&chats_str=…
sync_turn (write) POST /blobs/insert/{user_id}?wait_process=false
on_session_end (flush) POST /users/buffer/{user_id}/chat?wait_process=true
memobase_profile GET /users/profile/{user_id}

Safety & reliability

  • Non-primary agents skip writes (subagent / cron / flush contexts cannot corrupt the user profile); recall still works.
  • Fail-open: any backend error is logged and swallowed — the agent turn never breaks because memory died.
  • Circuit breaker: after 5 consecutive failures the provider pauses for 60 s instead of hammering a down server; a success resets the counter.
  • Fast hot path: prefetch() consumes a background thread's cached result (wait ≤ prefetch_wait_secs); a slow backend degrades to "no injection" and the search tool remains available.
  • Business errors are caught: Memobase may return HTTP 200 with a non-zero errno body; those are treated as failures, not successes.
  • One outbound host by default: your Memobase server. Vector recall and the entity leg are computed locally from the context payload. The reranker is the only other path, and it stays off until you set both an endpoint and a key for it.

Development

Run the test suite (stdlib unittest + httpx.MockTransport, no extra deps):

python -m unittest discover -s tests -v

License

MIT

← Back to the catalog · catalog built Oct 8, 2026