Xây dựng Plugin Công cụ bối cảnh
Các plugin công cụ ngữ cảnh thay thế ContextCompressor tích hợp sẵn bằng một chiến lược thay thế để quản lý ngữ cảnh hội thoại. Ví dụ: công cụ Quản lý bối cảnh không mất dữ liệu (LCM) xây dựng DAG kiến thức thay vì tóm tắt mất dữ liệu.
Cách thức hoạt động
Quản lý bối cảnh của tác nhân được xây dựng trên ContextEngine ABC (agent/context_engine.py). ContextCompressor tích hợp sẵn là cài đặt mặc định. Công cụ plugin phải triển khai cùng một giao diện.
Mỗi lần chỉ một công cụ ngữ cảnh có thể hoạt động. Lựa chọn được định hướng theo cấu hình:
# config.yaml
context:
engine: "compressor" # default built-in
engine: "lcm" # activates a plugin engine named "lcm"
Công cụ plugin không bao giờ được kích hoạt tự động — người dùng phải đặt rõ ràng context.engine thành tên của plugin.
Cấu trúc thư mục
Mỗi công cụ bối cảnh đều tồn tại trong plugins/context_engine/<name>/:
plugins/context_engine/lcm/
├── __init__.py # exports the ContextEngine subclass
├── plugin.YAML # metadata (name, description, version)
└── ... # any other modules your engine needs
Công cụ ngữ cảnh ABC
Công cụ của bạn phải triển khai các phương thức bắt buộc sau:
from agent.context_engine import ContextEngine
class LCMEngine(ContextEngine):
@property
def name(self) -> str:
"""Short identifier, e.g. 'lcm'. Must match config.yaml value."""
return "lcm"
def update_from_response(self, usage: dict) -> None:
"""Called after every LLM call with the usage dict.
Update self.last_prompt_tokens, self.last_completion_tokens,
self.last_total_tokens from the response.
"""
def should_compress(self, prompt_tokens: int = None) -> bool:
"""Return True if compaction should fire this turn."""
def compress(self, messages: list, current_tokens: int = None) -> list:
"""Compact the message list and return a new (possibly shorter) list.
The returned list must be a valid OpenAI-format message sequence.
"""
Thuộc tính lớp mà động cơ của bạn phải duy trì
Tác nhân đọc những thông tin này trực tiếp để hiển thị và ghi nhật ký:
last_prompt_tokens: int = 0
last_completion_tokens: int = 0
last_total_tokens: int = 0
threshold_tokens: int = 0 # when compression triggers
context_length: int = 0 # model's full context window
compression_count: int = 0 # how many times compress() has run
Các phương thức tùy chọn
Chúng có những giá trị mặc định hợp lý trong ABC. Ghi đè khi cần thiết:
| Phương pháp | Mặc định | Ghi đè khi |
|---|---|---|
on_session_start(session_id, **kwargs) | Không hoạt động | Bạn cần tải trạng thái liên tục (DAG, DB) |
on_session_end(session_id, messages) | Không hoạt động | Bạn cần xóa trạng thái, đóng kết nối |
on_session_reset() | Đặt lại bộ đếm mã thông báo | Bạn có trạng thái mỗi phiên cần xóa |
update_model(model, context_length, ...) | Cập nhật context_length + ngưỡng | Bạn cần tính toán lại ngân sách trên model switch |
get_tool_schemas() | Trả về [] | Công cụ của bạn cung cấp các công cụ có thể gọi được đại lý (ví dụ: lcm_grep) |
handle_tool_call(name, args, **kwargs) | Trả về lỗi JSON | Bạn triển khai trình xử lý công cụ |
should_compress_preflight(messages) | Trả về False | Bạn có thể thực hiện ước tính giá rẻ trước cuộc gọi API |
get_status() | Lệnh mã thông báo/ngưỡng tiêu chuẩn | Bạn có số liệu tùy chỉnh để hiển thị |
Công cụ động cơ
Công cụ bối cảnh có thể hiển thị các công cụ mà tác nhân gọi trực tiếp. Trả về các lược đồ từ get_tool_schemas() và xử lý các lệnh gọi trong handle_tool_call():
def get_tool_schemas(self):
return [{
"name": "lcm_grep",
"description": "Search the context knowledge graph",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "Search query"}
},
"required": ["query"],
},
}]
def handle_tool_call(self, name, args, **kwargs):
if name == "lcm_grep":
results = self._search_dag(args["query"])
return JSON.dumps({"results": results})
return JSON.dumps({"error": f"Unknown tool: {name}"})
Các công cụ công cụ được đưa vào danh sách công cụ của tác nhân khi khởi động và được gửi tự động — không cần đăng ký.
Đăng ký
Qua thư mục (được khuyến nghị)
Đặt động cơ của bạn vào plugins/context_engine/<name>/. __init__.py phải xuất lớp con ContextEngine. Hệ thống khám phá sẽ tự động tìm và khởi tạo nó.
Qua hệ thống plugin chung
Một plugin chung cũng có thể đăng ký một công cụ ngữ cảnh:
def register(ctx):
engine = LCMEngine(context_length=200000)
ctx.register_context_engine(engine)
Chỉ có một động cơ có thể được đăng ký. Plugin thứ hai cố gắng đăng ký bị từ chối kèm theo cảnh báo.
Vòng đời
1. Engine instantiated (plugin load or directory discovery)
2. on_session_start() — conversation begins
3. update_from_response() — after each API call
4. should_compress() — checked each turn
5. compress() — called when should_compress() returns True
6. on_session_end() — session boundary (CLI exit, /reset, gateway expiry)
on_session_reset() được gọi trên /new hoặc /reset để xóa trạng thái mỗi phiên mà không cần tắt hoàn toàn.
Cấu hình
Người dùng chọn công cụ của bạn thông qua Hermes plugins → Plugin nhà cung cấp → Công cụ bối cảnh hoặc bằng cách chỉnh sửa config.yaml:
context:
engine: "lcm" # must match your engine's name property
Khối cấu hình compression (compression.threshold, compression.protect_last_n, v.v.) dành riêng cho ContextCompressor tích hợp sẵn. Công cụ của bạn nên xác định định dạng cấu hình riêng nếu cần, đọc từ config.yaml trong quá trình khởi tạo.
##Thử nghiệm
from agent.context_engine import ContextEngine
def test_engine_satisfies_abc():
engine = YourEngine(context_length=200000)
assert isinstance(engine, ContextEngine)
assert engine.name == "your-name"
def test_compress_returns_valid_messages():
engine = YourEngine(context_length=200000)
msgs = [{"role": "user", "content": "hello"}]
result = engine.compress(msgs)
assert isinstance(result, list)
assert all("role" in m for m in result)
Xem tests/agent/test_context_engine.py để biết bộ thử nghiệm hợp đồng ABC đầy đủ.
Xem thêm
- Context Compression and Caching - cách hoạt động của máy nén tích hợp
- Memory Provider Plugins — hệ thống plugin chọn một lần tương tự cho bộ nhớ
- Plugins - tổng quan về hệ thống plugin chung