hermes - 💡(How to fix) Fix Feature request: expose multi-bank routing for Hindsight memory tools

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Hermes' Hindsight memory provider currently supports a single active bank_id per agent/session, plus bank_id_template for deriving a bank from profile, workspace, platform, user, or session metadata. This works well for simple deployments, but it is limiting for agents that need to work across multiple durable memory domains.

Please consider adding first-class multi-bank routing for Hindsight-backed memory: named bank definitions in config, per-tool-call bank selection, and optional read/write policy controls.

The goal is not to make memory configuration more complex for default users. The default single-bank behavior should remain. The goal is to let advanced Hermes users and multi-agent workflows separate long-term memory by domain while still allowing one agent to consult the right memories for the task at hand.

Root Cause

Many Hermes users use the agent for productivity, engineering, research, operations, writing, and personal organization. In those workflows, one agent may legitimately need access to multiple specialized memory banks.

Examples:

  • A coding agent may need:

    • code for repository conventions, architecture decisions, test commands, and debugging patterns;
    • ops for deployment quirks, service topology, secrets-handling conventions, and host-specific operational notes;
    • research for prior investigation notes, paper summaries, API comparisons, and vendor documentation findings.
  • A research agent may need:

    • research as its primary writable bank;
    • read-only access to code when turning research into implementation guidance;
    • read-only access to ops when recommendations depend on deployment constraints.
  • A project-manager or orchestrator agent may need to read from several banks while writing only to a planning/project bank.

  • Sub-profile agents may need their own private bank while still reading from shared team/domain banks. For example:

    • code-python-worker writes to its own task/profile bank but can read shared code and research banks;
    • ops-worker writes to ops but can read code for repository layout and build commands.

Without explicit multi-bank routing, users must either:

  1. collapse unrelated memory into one large bank, which increases retrieval noise and makes extracted facts less trustworthy;
  2. create separate Hermes profiles for every memory domain, which is awkward when one agent needs cross-domain context;
  3. rely on tags as a soft boundary, which is less robust than bank-level separation;
  4. repeatedly edit bank_id and restart/reset sessions, which is easy to forget and unsuitable for autonomous workflows.

Code Example

{
  "bank_id": "hermes",
  "bank_id_template": "",
  "recall_budget": "mid"
}

---

{
  "banks": {
    "hermes": {
      "bankId": "hermes",
      "budget": "mid",
      "enabled": true
    }
  }
}

---

{
  "bank_id": "default",
  "recall_budget": "mid",
  "banks": {
    "default": {
      "bankId": "hermes",
      "budget": "mid",
      "enabled": true,
      "description": "General agent memory."
    },
    "code": {
      "bankId": "code",
      "budget": "mid",
      "enabled": true,
      "description": "Repository conventions, architecture, debugging patterns, and test/build commands."
    },
    "research": {
      "bankId": "research",
      "budget": "high",
      "enabled": true,
      "description": "Research notes, source summaries, comparisons, papers, API investigations, and decision support."
    },
    "ops": {
      "bankId": "ops",
      "budget": "mid",
      "enabled": true,
      "description": "Deployment, infrastructure, service topology, host quirks, and operational procedures."
    }
  }
}

---

{
  "name": "hindsight_recall",
  "parameters": {
    "type": "object",
    "properties": {
      "query": { "type": "string" },
      "bank": {
        "type": "string",
        "description": "Optional named bank from configured banks, e.g. default, code, research, ops. Defaults to the active bank."
      }
    },
    "required": ["query"]
  }
}

---

hindsight_retain(content, context?, tags?, bank?)
hindsight_recall(query, bank?)
hindsight_reflect(query, bank?)

---

{
  "banks": {
    "default": { "bankId": "hermes", "access": "read_write" },
    "code": { "bankId": "code", "access": "read_write" },
    "research": { "bankId": "research", "access": "read_only" },
    "ops": { "bankId": "ops", "access": "read_only" }
  }
}

---

{
  "hindsight": {
    "default_bank": "default",
    "read_banks": ["default", "code", "research", "ops"],
    "write_banks": ["default", "code"]
  }
}

---

{
  "query": "What do we know about deploying this service?",
  "banks": ["code", "ops"]
}

---

hindsight_recall_multi(query, banks)
hindsight_reflect_multi(query, banks)

---

[code] The API service uses pytest with integration tests under tests/integration.
[ops] Production deploys run behind nginx on the app host; systemd restarts the service on failure.

---

def _resolve_bank(self, alias_or_id: str | None) -> tuple[str, str]:
       """Return (alias, bank_id), validating against configured banks when present."""

---

{
  "bank_id": "default",
  "banks": {
    "default": { "bankId": "hermes", "budget": "mid", "enabled": true },
    "code": { "bankId": "code", "budget": "mid", "enabled": true },
    "research": { "bankId": "research", "budget": "high", "enabled": true },
    "ops": { "bankId": "ops", "budget": "mid", "enabled": true }
  }
}

---

hindsight_recall(query="What are the known deploy constraints?", bank="ops")
hindsight_recall(query="What testing conventions does this repo use?", bank="code")
hindsight_retain(content="This repository uses pnpm for package management.", context="repo convention", bank="code")
hindsight_retain(content="The staging service is restarted through systemd.", context="ops convention", bank="ops")
RAW_BUFFERClick to expand / collapse

Feature request: expose multi-bank routing for Hindsight memory tools

Summary

Hermes' Hindsight memory provider currently supports a single active bank_id per agent/session, plus bank_id_template for deriving a bank from profile, workspace, platform, user, or session metadata. This works well for simple deployments, but it is limiting for agents that need to work across multiple durable memory domains.

Please consider adding first-class multi-bank routing for Hindsight-backed memory: named bank definitions in config, per-tool-call bank selection, and optional read/write policy controls.

The goal is not to make memory configuration more complex for default users. The default single-bank behavior should remain. The goal is to let advanced Hermes users and multi-agent workflows separate long-term memory by domain while still allowing one agent to consult the right memories for the task at hand.

Current behavior

The Hindsight plugin config supports top-level settings such as:

{
  "bank_id": "hermes",
  "bank_id_template": "",
  "recall_budget": "mid"
}

The generated/default config shape may also contain a banks object, for example:

{
  "banks": {
    "hermes": {
      "bankId": "hermes",
      "budget": "mid",
      "enabled": true
    }
  }
}

However, the exposed Hindsight tools do not currently accept a bank_id or named bank parameter:

  • hindsight_retain(content, context?, tags?)
  • hindsight_recall(query)
  • hindsight_reflect(query)

As a result, the LLM cannot intentionally route a memory operation to a specialized bank at tool-call time. All tool calls use the provider's active resolved bank.

bank_id_template is useful for automatic isolation by profile/workspace/platform/user/session, but it does not cover domain routing inside a single agent's work. It answers “which bank should this session use?” rather than “which memory domain is appropriate for this operation?”

Why this matters

Many Hermes users use the agent for productivity, engineering, research, operations, writing, and personal organization. In those workflows, one agent may legitimately need access to multiple specialized memory banks.

Examples:

  • A coding agent may need:

    • code for repository conventions, architecture decisions, test commands, and debugging patterns;
    • ops for deployment quirks, service topology, secrets-handling conventions, and host-specific operational notes;
    • research for prior investigation notes, paper summaries, API comparisons, and vendor documentation findings.
  • A research agent may need:

    • research as its primary writable bank;
    • read-only access to code when turning research into implementation guidance;
    • read-only access to ops when recommendations depend on deployment constraints.
  • A project-manager or orchestrator agent may need to read from several banks while writing only to a planning/project bank.

  • Sub-profile agents may need their own private bank while still reading from shared team/domain banks. For example:

    • code-python-worker writes to its own task/profile bank but can read shared code and research banks;
    • ops-worker writes to ops but can read code for repository layout and build commands.

Without explicit multi-bank routing, users must either:

  1. collapse unrelated memory into one large bank, which increases retrieval noise and makes extracted facts less trustworthy;
  2. create separate Hermes profiles for every memory domain, which is awkward when one agent needs cross-domain context;
  3. rely on tags as a soft boundary, which is less robust than bank-level separation;
  4. repeatedly edit bank_id and restart/reset sessions, which is easy to forget and unsuitable for autonomous workflows.

Requested behavior

1. Support named banks in Hindsight config

Make banks a documented and active config section rather than a mostly implicit/default shape.

Example:

{
  "bank_id": "default",
  "recall_budget": "mid",
  "banks": {
    "default": {
      "bankId": "hermes",
      "budget": "mid",
      "enabled": true,
      "description": "General agent memory."
    },
    "code": {
      "bankId": "code",
      "budget": "mid",
      "enabled": true,
      "description": "Repository conventions, architecture, debugging patterns, and test/build commands."
    },
    "research": {
      "bankId": "research",
      "budget": "high",
      "enabled": true,
      "description": "Research notes, source summaries, comparisons, papers, API investigations, and decision support."
    },
    "ops": {
      "bankId": "ops",
      "budget": "mid",
      "enabled": true,
      "description": "Deployment, infrastructure, service topology, host quirks, and operational procedures."
    }
  }
}

The top-level bank_id can remain as the default/fallback bank for backward compatibility.

2. Expose bank selection in Hindsight tool schemas

Allow the model to select a named bank or explicit bank id per operation.

Possible schema shape:

{
  "name": "hindsight_recall",
  "parameters": {
    "type": "object",
    "properties": {
      "query": { "type": "string" },
      "bank": {
        "type": "string",
        "description": "Optional named bank from configured banks, e.g. default, code, research, ops. Defaults to the active bank."
      }
    },
    "required": ["query"]
  }
}

Likewise for retain and reflect:

hindsight_retain(content, context?, tags?, bank?)
hindsight_recall(query, bank?)
hindsight_reflect(query, bank?)

A stricter variant could expose only configured bank aliases rather than arbitrary bank_id strings. That would prevent the model from inventing new banks accidentally.

3. Support read/write policy per bank

A useful policy layer would let a profile/toolset define which banks are readable and writable.

Example:

{
  "banks": {
    "default": { "bankId": "hermes", "access": "read_write" },
    "code": { "bankId": "code", "access": "read_write" },
    "research": { "bankId": "research", "access": "read_only" },
    "ops": { "bankId": "ops", "access": "read_only" }
  }
}

Or:

{
  "hindsight": {
    "default_bank": "default",
    "read_banks": ["default", "code", "research", "ops"],
    "write_banks": ["default", "code"]
  }
}

This would let sub-profile agents read shared banks without polluting them, while still writing to their own domain-specific memory.

4. Allow multi-bank recall/reflection

Some queries naturally span domains. It would be useful to support multi-bank recall, either explicitly:

{
  "query": "What do we know about deploying this service?",
  "banks": ["code", "ops"]
}

or through a separate tool:

hindsight_recall_multi(query, banks)
hindsight_reflect_multi(query, banks)

The returned result should preserve source bank labels so the agent can distinguish where each fact came from.

Example output:

[code] The API service uses pytest with integration tests under tests/integration.
[ops] Production deploys run behind nginx on the app host; systemd restarts the service on failure.

Source labels are important because facts from research should not be treated the same as verified ops facts, and project-specific code facts should not be generalized across unrelated repositories.

Backward compatibility

This can be additive:

  • Existing configs with only bank_id continue to work unchanged.
  • Existing tool calls without bank continue to use the active resolved bank.
  • bank_id_template continues to work as the default bank resolver.
  • banks becomes an optional alias/policy layer over Hindsight bank IDs.

Suggested implementation sketch

  1. Normalize bank config at provider initialization:

    • default_bank_alias from top-level bank_id or configured default;
    • banks map from alias -> bank config;
    • fallback alias default or hermes if no banks are configured.
  2. Add helper:

    def _resolve_bank(self, alias_or_id: str | None) -> tuple[str, str]:
        """Return (alias, bank_id), validating against configured banks when present."""
  3. Extend tool schemas with optional bank for retain/recall/reflect.

  4. In handlers, resolve args.get("bank") to a Hindsight bank_id; fall back to self._bank_id.

  5. Enforce optional read/write policies:

    • retain requires write access;
    • recall/reflect require read access.
  6. Include bank alias/id in logs and, for multi-bank recall, in returned text.

  7. Document the behavior in the Hindsight plugin README and Hermes memory docs.

Example user-facing workflow

A user configures:

{
  "bank_id": "default",
  "banks": {
    "default": { "bankId": "hermes", "budget": "mid", "enabled": true },
    "code": { "bankId": "code", "budget": "mid", "enabled": true },
    "research": { "bankId": "research", "budget": "high", "enabled": true },
    "ops": { "bankId": "ops", "budget": "mid", "enabled": true }
  }
}

Then the agent can intentionally do:

hindsight_recall(query="What are the known deploy constraints?", bank="ops")
hindsight_recall(query="What testing conventions does this repo use?", bank="code")
hindsight_retain(content="This repository uses pnpm for package management.", context="repo convention", bank="code")
hindsight_retain(content="The staging service is restarted through systemd.", context="ops convention", bank="ops")

Documentation note

If multi-bank routing is not intended, the banks config object should probably be documented as legacy/internal or removed from generated configs. As-is, the shape suggests named bank support even though the tools and provider behavior route through one active bank.

Either direction is fine, but explicit behavior would reduce confusion:

  • document single-bank behavior and remove/de-emphasize banks, or
  • implement banks as a real named-bank routing layer.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix Feature request: expose multi-bank routing for Hindsight memory tools