본문으로 건너뛰기

메모리 제공자 플러그인

anchor alias

메모리 제공자 플러그인 구축

메모리 제공자 플러그인은 내장된 MEMORY.md 및 USER.md를 넘어서 Hermes Agent에 지속적인 세션 간 지식을 제공합니다. 이 가이드에서는 빌드 방법을 다룹니다.

메모리 제공자는 두 가지 제공자 플러그인 유형 중 하나입니다. 다른 하나는 내장된 컨텍스트 압축기를 대체하는 컨텍스트 엔진 플러그인입니다. 둘 다 동일한 패턴을 따릅니다: 단일 선택, 구성 기반, hermes plugins을 통해 관리됩니다.

디렉토리 구조

각 메모리 제공자는 plugins/memory/<name>/에 있습니다.

plugins/memory/my-provider/
├── __init__.py # MemoryProvider implementation + register() entry point
├── plugin.yaml # Metadata (name, description, hooks)
└── README.md # Setup instructions, config reference, tools

메모리 제공자 ABC

플러그인은 agent/memory_provider.pyMemoryProvider 추상 기본 클래스를 구현합니다.

from agent.memory_provider import MemoryProvider

class MyMemoryProvider(MemoryProvider):
@property
def name(self) -> str:
return "my-provider"

def is_available(self) -> bool:
"""Check if this provider can activate. NO network calls."""
return bool(os.environ.get("MY_API_KEY"))

def initialize(self, session_id: str, **kwargs) -> None:
"""Called once at agent startup.

kwargs always includes:
hermes_home (str): Active HERMES_HOME path. Use for storage.
"""
self._api_key = os.environ.get("MY_API_KEY", "")
self._session_id = session_id

#... implement remaining methods

필수 방법

핵심 수명주기

방법부름을 받았을 때구현해야 합니까?
name (속성)항상
is_available()에이전트 초기화, 활성화 전 - 네트워크 호출 없음
initialize(session_id, **kwargs)에이전트 시작
get_tool_schemas()초기화 후 도구 주입을 위해
handle_tool_call(name, args)에이전트가 도구를 사용하는 경우(도구가 있는 경우)

구성

방법목적구현해야 합니까?
get_config_schema()hermes memory setup에 대한 구성 필드 선언
save_config(values, hermes_home)기본 위치에 비밀이 아닌 구성 쓰기(env-var 전용이 아닌 경우)

옵션 후크

방법부름을 받았을 때사용 사례
system_prompt_block()시스템 프롬프트 조립정적 제공자 정보
prefetch(query)각 API 호출 전회상된 컨텍스트 반환
queue_prefetch(query)매 턴마다다음 차례를 위해 예열
sync_turn(user, assistant)각 턴이 완료되면대화 지속
on_session_end(messages)대화가 종료됩니다최종 추출/플러시
on_pre_compress(messages)컨텍스트 압축 전삭제하기 전에 통찰력을 저장하세요
on_memory_write(action, target, content)내장 메모리 쓰기백엔드에 미러링
shutdown()프로세스 종료연결 정리

구성 스키마

get_config_schema()hermes memory setup에서 사용하는 필드 설명자 목록을 반환합니다.

def get_config_schema(self):
return [
{
"key": "api_key",
"description": "My Provider API key",
"secret": True, # → written to.env
"required": True,
"env_var": "MY_API_KEY", # explicit env var name
"url": "https://my-provider.com/keys", # where to get it
},
{
"key": "region",
"description": "Server region",
"default": "us-east",
"choices": ["us-east", "eu-west", "ap-south"],
},
{
"key": "project",
"description": "Project identifier",
"default": "hermes",
},
]

secret: Trueenv_var이 있는 필드는 .env로 이동합니다. 비밀이 아닌 필드는 save_config()로 전달됩니다.

Minimal vs Full Schema

get_config_schema()의 모든 필드는 hermes memory setup 중에 프롬프트됩니다. 옵션이 많은 제공자는 스키마를 최소화해야 합니다. 즉, 사용자가 반드시 구성해야 하는 필드(API 키, 필수 자격 증명)만 포함해야 합니다. 설정 중에 옵션 설정을 모두 묻는 대신 구성 파일 참조(예: $HERMES_HOME/myprovider.json)에 옵션 설정을 문서화하세요. 이렇게 하면 고급 구성을 계속 지원하면서 설정 마법사의 속도가 빨라집니다. 예를 보려면 Supermemory 제공자를 참조하세요. API 키만 묻는 메시지가 표시됩니다. 다른 모든 옵션은 supermemory.json에 있습니다.

구성 저장

def save_config(self, values: dict, hermes_home: str) -> None:
"""Write non-secret config to your native location."""
import json
from pathlib import Path
config_path = Path(hermes_home) / "my-provider.json"
config_path.write_text(json.dumps(values, indent=2))

env-var-only 제공자의 경우 기본 no-op를 그대로 둡니다.

플러그인 진입점

def register(ctx) -> None:
"""Called by the memory plugin discovery system."""
ctx.register_memory_provider(MyMemoryProvider())

플러그인.yaml

name: my-provider
version: 1.0.0
description: "Short description of what this provider does."
hooks:
- on_session_end # list hooks you implement

스레딩 계약

sync_turn() 비차단이어야 합니다. 백엔드에 지연 시간(API 호출, LLM 처리)이 있는 경우 데몬 스레드에서 작업을 실행합니다.

def sync_turn(self, user_content, assistant_content):
def _sync():
try:
self._api.ingest(user_content, assistant_content)
except Exception as e:
logger.warning("Sync failed: %s", e)

if self._sync_thread and self._sync_thread.is_alive():
self._sync_thread.join(timeout=5.0)
self._sync_thread = threading.Thread(target=_sync, daemon=True)
self._sync_thread.start()

프로필 격리

모든 저장소 경로는 반드시 하드코딩된 ~/.hermes이 아닌 initialize()hermes_home kwarg를 사용해야 합니다.

# CORRECT — profile-scoped
from hermes_constants import get_hermes_home
data_dir = get_hermes_home() / "my-provider"

# WRONG — shared across all profiles
data_dir = Path("~/.hermes/my-provider").expanduser()

테스트

실제 SQLite 제공자를 사용한 전체 테스트 패턴은 tests/agent/test_memory_plugin_e2e.py을 참조하세요.

from agent.memory_manager import MemoryManager

mgr = MemoryManager()
mgr.add_provider(my_provider)
mgr.initialize_all(session_id="test-1", platform="cli")

# Test tool routing
result = mgr.handle_tool_call("my_tool", {"action": "add", "content": "test"})

# Test lifecycle
mgr.sync_all("user msg", "assistant msg")
mgr.on_session_end()
mgr.shutdown_all()

CLI 명령 추가

메모리 제공자 플러그인은 자체 CLI 하위 명령 트리(예: hermes my-provider status, hermes my-provider config)를 등록할 수 있습니다. 이는 규칙 기반 검색 시스템을 사용하므로 코어 파일을 변경할 필요가 없습니다.

작동 원리

  1. 플러그인 디렉터리에 cli.py 파일을 추가하세요.
  2. argparse 트리를 구축하는 register_cli(subparser) 함수를 정의합니다.
  3. 메모리 플러그인 시스템은 시작 시 discover_plugin_cli_commands()을 통해 이를 발견합니다.
  4. 명령은 hermes <provider-name> <subcommand> 아래에 표시됩니다.

활성 제공자 게이팅: CLI 명령은 제공자가 구성에서 활성 memory.provider인 경우에만 나타납니다. 사용자가 제공자를 구성하지 않은 경우 명령이 hermes --help에 표시되지 않습니다.

# plugins/memory/my-provider/cli.py

def my_command(args):
"""Handler dispatched by argparse."""
sub = getattr(args, "my_command", None)
if sub == "status":
print("Provider is active and connected.")
elif sub == "config":
print("Showing config...")
else:
print("Usage: hermes my-provider <status|config>")

def register_cli(subparser) -> None:
"""Build the hermes my-provider argparse tree.

Called by discover_plugin_cli_commands() at argparse setup time.
"""
subs = subparser.add_subparsers(dest="my_command")
subs.add_parser("status", help="Show provider status")
subs.add_parser("config", help="Show provider config")
subparser.set_defaults(func=my_command)

참조 구현

13개 하위 명령, 프로필 간 관리(--target-profile) 및 구성 읽기/쓰기가 포함된 전체 예는 plugins/memory/honcho/cli.py을 참조하세요.

CLI를 사용한 디렉터리 구조

plugins/memory/my-provider/
├── __init__.py # MemoryProvider implementation + register()
├── plugin.yaml # Metadata
├── cli.py # register_cli(subparser) — CLI commands
└── README.md # Setup instructions

단일 제공자 규칙

한 번에 하나 외부 메모리 제공자만 활성화할 수 있습니다. 사용자가 두 번째 등록을 시도하면 MemoryManager는 경고와 함께 이를 거부합니다. 이를 통해 도구 스키마 팽창 및 백엔드 충돌을 방지할 수 있습니다.