본문으로 건너뛰기

메모리 제공자 플러그인

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: True` 및 `env_var`이 있는 필드는 `.env`로 이동합니다. 비밀이 아닌 필드는 `save_config()`로 전달됩니다.

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

:::
## 구성 저장 \{#save-config}

```python
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는 경고와 함께 이를 거부합니다. 이를 통해 도구 스키마 팽창 및 백엔드 충돌을 방지할 수 있습니다.