Chuyển tới nội dung chính

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ápMặc địnhGhi đè khi
on_session_start(session_id, **kwargs)Không hoạt độngBạ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 độngBạ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áoBạ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ưỡngBạ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 JSONBạn triển khai trình xử lý công cụ
should_compress_preflight(messages)Trả về FalseBạ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ẩnBạ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