Xây dựng Plugin cung cấp bộ nhớ
Các plugin của nhà cung cấp bộ nhớ cung cấp cho Hermes Agent kiến thức xuyên suốt, liên tục ngoài MEMORY.md và USER.md tích hợp sẵn. Hướng dẫn này bao gồm cách xây dựng một.
Cấu trúc thư mục
Mỗi nhà cung cấp bộ nhớ nằm trong 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
Nhà cung cấp bộ nhớ ABC
Plugin của bạn triển khai lớp cơ sở trừu tượng MemoryProvider từ agent/memory_provider.py :
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
Phương thức bắt buộc
Vòng đời cốt lõi
| Phương pháp | Khi được gọi | Phải thực hiện? |
|---|---|---|
name (tài sản) | Luôn luôn | Có |
is_available() | Đại lý khởi tạo, trước khi kích hoạt | Có — không có cuộc gọi qua mạng |
initialize(session_id, **kwargs) | Khởi động đại lý | Có |
get_tool_schemas() | Sau khi init, để chèn công cụ | Có |
handle_tool_call(name, args) | Khi đại lý sử dụng công cụ của bạn | Có (nếu bạn có công cụ) |
Cấu hình
| Phương pháp | Mục đích | Phải thực hiện? |
|---|---|---|
get_config_schema() | Khai báo các trường cấu hình cho hermes memory setup | Có |
save_config(values, hermes_home) | Viết cấu hình không bí mật vào vị trí gốc | Có (trừ khi chỉ có env-var) |
Móc tùy chọn
| Phương pháp | Khi được gọi | Trường hợp sử dụng |
|---|---|---|
system_prompt_block() | Lắp ráp nhắc nhở hệ thống | Thông tin nhà cung cấp tĩnh |
prefetch(query) | Trước mỗi lệnh gọi API | Trả lại bối cảnh được thu hồi |
queue_prefetch(query) | Sau mỗi lượt | Làm ấm trước cho lượt tiếp theo |
sync_turn(user, assistant) | Sau mỗi lượt hoàn thành | Kiên trì trò chuyện |
on_session_end(messages) | Cuộc trò chuyện kết thúc | Chiết/xả lần cuối |
on_pre_compress(messages) | Trước khi nén ngữ cảnh | Lưu thông tin chi tiết trước khi loại bỏ |
on_memory_write(action, target, content) | Bộ nhớ tích hợp ghi | Phản ánh phần phụ trợ của bạn |
shutdown() | Quá trình thoát | Dọn dẹp kết nối |
Lược đồ cấu hình
get_config_schema() trả về danh sách các bộ mô tả trường được sử dụng bởi 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",
},
]
Các trường có secret: True và env_var chuyển đến .env . Các trường không bí mật được chuyển tới save_config() .
Mọi trường trong get_config_schema() đều được nhắc trong hermes memory setup . Các nhà cung cấp có nhiều tùy chọn nên giữ lược đồ ở mức tối thiểu — chỉ bao gồm các trường mà người dùng phải định cấu hình (khóa API, thông tin xác thực bắt buộc). Ghi lại các cài đặt tùy chọn trong tham chiếu tệp cấu hình (ví dụ: $HERMES_HOME/myprovider.json ) thay vì nhắc tất cả các cài đặt đó trong khi thiết lập. Điều này giúp trình hướng dẫn thiết lập nhanh chóng trong khi vẫn hỗ trợ cấu hình nâng cao. Hãy xem ví dụ về nhà cung cấp Supermemory — nó chỉ nhắc nhập khóa API; tất cả các tùy chọn khác đều có trong supermemory.json .
Lưu cấu hình
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))
Đối với các nhà cung cấp chỉ env-var, hãy để mặc định no-op.
Điểm vào plugin
def register(ctx) -> None:
"""Called by the memory plugin discovery system."""
ctx.register_memory_provider(MyMemoryProvider())
plugin.yaml
name: my-provider
version: 1.0.0
description: "Short description of what this provider does."
hooks:
- on_session_end
# list hooks you implement
Hợp đồng luồng
** sync_turn() PHẢI không bị chặn.** Nếu phần phụ trợ của bạn có độ trễ (các lệnh gọi API, xử lý LLM), hãy chạy công việc trong một chuỗi daemon:
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()
Cách ly hồ sơ
Tất cả các đường dẫn lưu trữ phải sử dụng hermes_home kwarg từ initialize() , không được mã hóa cứng ~/.hermes :
# 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()
Thử nghiệmXem tests/agent/test_memory_plugin_e2e.py để biết mẫu thử nghiệm E2E hoàn chỉnh bằng cách sử dụng nhà cung cấp SQLite thực.
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()
Thêm lệnh CLI
Các plugin của nhà cung cấp bộ nhớ có thể đăng ký cây lệnh phụ CLI của riêng chúng (ví dụ: hermes my-provider status , hermes my-provider config ). Điều này sử dụng hệ thống khám phá dựa trên quy ước - không cần thay đổi các tệp cốt lõi.
Cách thức hoạt động
- Thêm tệp
cli.pyvào thư mục plugin của bạn - Xác định hàm
register_cli(subparser)để xây dựng cây argparse - Hệ thống plugin bộ nhớ phát hiện ra nó khi khởi động thông qua
discover_plugin_cli_commands() - Lệnh của bạn xuất hiện trong
hermes <provider-name> <subcommand>
Gating nhà cung cấp đang hoạt động: Các lệnh CLI của bạn chỉ xuất hiện khi nhà cung cấp của bạn là memory.provider đang hoạt động trong config. Nếu người dùng chưa định cấu hình nhà cung cấp của bạn thì các lệnh của bạn sẽ không hiển thị trong hermes --help .
Ví dụ
# 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)
Triển khai tham khảo
Xem plugins/memory/honcho/cli.py để biết ví dụ đầy đủ với 13 lệnh phụ, quản lý nhiều cấu hình ( --target-profile ) và đọc/ghi cấu hình.
Cấu trúc thư mục với CLI
plugins/memory/my-provider/
├── __init__.py
# MemoryProvider implementation + register()
├── plugin.yaml
# Metadata
├── cli.py
# register_cli(subparser) — CLI commands
└── README.md
# Setup instructions
Quy tắc nhà cung cấp duy nhất
Mỗi lần chỉ một nhà cung cấp bộ nhớ ngoài có thể hoạt động. Nếu người dùng cố gắng đăng ký một giây, MemoryManager sẽ từ chối nó bằng một cảnh báo. Điều này ngăn ngừa sự phình to của lược đồ công cụ và các chương trình phụ trợ xung đột.