DanielLi202/hermes-tag
Post images, add notes, let the thread run, then @ it — Hermes Tag pulls the few messages that matter (originals + your notes + relevant replies), not your last line, not your whole history. Claude-Tag-style context-selection for Hermes on Feishu/Lark & Slack — @-only, no full-history RAG, per-chat memory + audit.
readme
Hermes Tag
Post the images, add your notes, let the thread run — then @ it. It already has everything that matters.
Use Hermes to bring Claude-Tag-style capability to your Feishu/Lark (and Slack). Drop a few images, add a note, let other people chime in — when you finally @-mention it, it pulls those images (the originals), your note, and the relevant replies — not just your last line, and never your whole history. Silent until mentioned; then it retrieves exactly the few messages that matter.

Real screen recording · HD MP4
What it is
Hermes Tag is a Claude-Tag-style context-selection layer for Hermes on Feishu/Lark (and Slack). It overrides Hermes's built-in Feishu platform — it is not a new platform. Each enabled chat gets one shared agent identity, and it answers only when @-mentioned.
What it uniquely adds on top of Hermes's built-in channels:
- Late @, full context. You can scatter context before you ever invoke it — images, a note, other people's replies — and when you finally @-mention it, it reconstructs the right bounded evidence across time and media: the images' originals, your note, and the relevant discussion. Not just your trigger message; not the whole transcript.
- Per-chat memory, by design. Long-term memory is built only from @-mention interactions and stays scoped to that chat — one chat's memory never leaks into another, and never becomes your whole account history. There is no cross-channel "workspace memory"; that isolation is the privacy promise.
- Auditable, and it never stores your message bodies.
/tag admin auditreturns redacted events (scope, time, counts — never message text);/tag admin clear|disableremoves a chat's retained data. Theenabled_chatsallowlist is the only storage and processing boundary.
The ContextSelector chooses bounded evidence with focused_reply, thread, deictic_recent, and plain scopes instead of dumping the transcript. That means no full-history RAG and no ambient auto-answering.
Shipped now vs. roadmap. Shipped: bounded multimodal evidence, Tier-0/Tier-1 memory, per-chat isolation, admin lifecycle, and redacted audit — on Feishu/Lark and Slack. Roadmap: deeper connector/source-binding parity. The Claude-Tag comparison is the goal we measure against, not a claim that every Claude-Tag feature already ships.
This repository, the Python/pip package, and the manifest name are all hermes-tag.
Security & Risk Warnings (Read Before Use)
- The
enabled_chatsallowlist is the storage and processing boundary. - All messages in enabled chats may be buffered locally as Tier-0 short-term context.
- Only @-mention interactions create Tier-1 long-term memory.
- The declared
encryption_postureisplaintext-db-on-local-disk. - Admins can run
/tag admin clearor/tag admin disableto remove retained plugin data for a chat, and/tag admin auditto inspect redacted activity. - Audit events record startup, storage, admin, standing-job, and lifecycle actions — never message bodies.
Read SECURITY.md and docs/design/ before enabling a pilot chat.
Requirements / Compatibility
| Item | Requirement |
|---|---|
| hermes-agent | v2026.6.19 |
| lark-oapi | 1.6.9 |
| Python | >=3.11 |
| Required env | FEISHU_APP_ID + FEISHU_APP_SECRET |
These pins are a project convention; Hermes has no enforced compatibility mechanism.
Quickstart (<60s)
Installing with an AI agent? Point it at llms.txt and AGENTS.md — those are written for agent-driven install/config. This README is for humans.
hermes plugins install DanielLi202/hermes-tag
plugins:
enabled:
- hermes-tag
platforms:
feishu:
require_mention: false # so unmentioned group messages reach the adapter for Tier-0 context
extra:
feishu_tag:
enabled: true
enabled_chats: [oc_xxx_pilot_chat]
bot_open_id: ou_xxx_bot_open_id
granted_scopes: [im:message.group_msg]
admins: [ou_xxx_admin_open_id]
encryption_posture: plaintext-db-on-local-disk
Full onboarding + live verification: see after-install.md. Slack setup: see docs/slack-setup.md.
Usage
In groups, /tag commands require @-mention.
/tag status/tag admin count|clear|disable|audit/tag standing add <schedule> <timezone> <description>then/tag standing confirm/tag standing list|cancel <id>|pause <id>|enable <id>
| Context scope | Meaning |
|---|---|
focused_reply |
Explicit reply -> narrow to that parent as evidence. |
thread |
Real thread without explicit reply -> narrow to that thread as evidence. |
deictic_recent |
"上面那张图" / "the image above" -> nearest recent media. |
plain |
Bounded recent text. |
| Memory tier | Behavior |
|---|---|
Tier-0 |
Short-term per-chat buffer, TTL/count evicted. |
Tier-1 |
Long-term, @-derived, consolidated, tombstoned on delete. |
Project Structure
src/hermes_tag/core.py— config, sqlite store, TagEngine, PlatformSeam.src/hermes_tag/context.py— ContextSelector: the bounded-evidence selector.src/hermes_tag/base.py— TagAdapterMixin: the platform-agnostic orchestration.src/hermes_tag/platforms/feishu.py— Feishu binding: mention detection, media fetch/download, registration.src/hermes_tag/platforms/slack.py— Slack binding: mention detection, media buffering, registration.src/hermes_tag/i18n.py— locale strings.src/hermes_tag/adapter.py— back-compat re-export shim.
The platform-agnostic base plus a narrow seam means each platform is a thin add; the generic policy is written once for all of them.
Contributing · Changelog · License
- Contributing
- Changelog
- License: MIT, DanielLi202.