컨텍스트 엔진 플러그인 구축
컨텍스트 엔진 플러그인은 내장된 contextCompressor을 대화 컨텍스트 관리를 위한 대체 전략으로 대체합니다. 예를 들어 손실 요약 대신 지식 DAG를 구축하는 LCM(무손실 컨텍스트 관리) 엔진이 있습니다.
작동 원리
에이전트의 컨텍스트 관리는 contextEngine ABC(agent/context_engine.py)를 기반으로 구축되었습니다. 내장된 contextCompressor이 기본 구현입니다. 플러그인 엔진은 동일한 인터페이스를 구현해야 합니다.
한 번에 하나 컨텍스트 엔진만 활성화할 수 있습니다. 선택은 구성에 따라 이루어집니다.
# config.yaml
context:
engine: "compressor" # default built-in
engine: "lcm" # activates a plugin engine named "lcm"
플러그인 엔진은 자동으로 활성화되지 않습니다. 사용자는 플러그인 이름에 context.engine을 명시적으로 설정해야 합니다.
디렉토리 구조
각 컨텍스트 엔진은 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
컨텍스트Engine ABC
엔진은 다음과 같은 필수 메서드를 구현해야 합니다.
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,
focus_topic: str = None) -> list:
"""Compact the message list and return a new (possibly shorter) list.
The returned list must be a valid OpenAI-format message sequence.
``focus_topic`` is an optional topic string from manual
``/compress <focus>``; engines that support guided compression should
prioritise preserving information related to it, others may ignore it.
"""
엔진이 유지해야 하는 클래스 속성
에이전트는 표시 및 로깅을 위해 다음을 직접 읽습니다.
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
선택적 방법
ABC에는 합리적인 기본값이 있습니다. 필요에 따라 재정의합니다.
| 방법 | 기본값 | 재정의 시기 |
|---|---|---|
on_session_start(session_id, **kwargs) | 무작동 | 지속 상태(DAG, DB)를 로드해야 합니다. |
on_session_end(session_id, messages) | 무작동 | 상태를 플러시하고 연결을 닫아야 합니다. |
on_session_reset() | 토큰 카운터를 재설정합니다. | 삭제할 세션별 상태가 있습니다. |
update_model(model, context_length,...) | 컨텍스트_length + 임계값 업데이트 | 모델 전환 시 예산을 다시 계산해야 합니다. |
get_tool_schemas() | ``을 반환합니다. | 사용자의 엔진은 에이전트 호출 가능 도구(예: lcm_grep)를 제공합니다. |
handle_tool_call(name, args, **kwargs) | 오류 JSON을 반환합니다. | 도구 핸들러를 구현합니다. |
should_compress_preflight(messages) | False을 반환합니다. | 저렴한 사전 API 호출 추정을 수행할 수 있습니다. |
get_status() | 표준 토큰/임계값 사전 | 노출할 맞춤 측정항목이 있습니다. |
엔진 도구
컨텍스트 엔진은 에이전트가 직접 호출하는 도구를 노출할 수 있습니다. get_tool_schemas()에서 스키마를 반환하고 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}"})
엔진 도구는 시작 시 에이전트의 도구 목록에 삽입되고 자동으로 발송됩니다. 레지스트리 등록이 필요하지 않습니다.
등록
디렉터리를 통해(권장)
plugins/context_engine/<name>/에 엔진을 배치하세요. __init__.py은 컨텍스트Engine 하위 클래스를 내보내야 합니다. 검색 시스템은 이를 자동으로 찾아서 인스턴스화합니다.
일반 플러그인 시스템을 통해
일반 플러그인은 컨텍스트 엔진을 등록할 수도 있습니다.
def register(ctx):
engine = LCMEngine(context_length=200000)
ctx.register_context_engine(engine)
엔진은 하나만 등록할 수 있습니다. 등록을 시도하는 두 번째 플러그인은 경고와 함께 거부됩니다.
수명주기
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()`은 전체 종료 없이 세션별 상태를 지우기 위해 `/new` 또는 `/reset`에서 호출됩니다.
## 구성 \{#configuration}
사용자는 `hermes plugins` → 공급자 플러그인 → context 엔진을 통해 또는 `config.yaml`을 편집하여 엔진을 선택합니다.
```yaml
컨텍스트:
engine: "lcm" # must match your engine's name property
``compression` 구성 블록(`compression.threshold`, `compression.protect_last_n` 등)은 내장된 `컨텍스트Compressor`에만 적용됩니다. 엔진은 필요한 경우 초기화 중에 `config.yaml`에서 읽어 자체 구성 형식을 정의해야 합니다.
## 테스트 \{#configuration}
```python
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)
전체 ABC 계약 테스트 모음은 tests/agent/test_context_engine.py을 참조하세요.
또한보십시오
- 컨텍스트 압축 및 캐싱 — 내장 압축기 작동 방식
- 메모리 제공자 플러그인 — 유사한 메모리용 단일 선택 플러그인 시스템
- 플러그인 — 일반 플러그인 시스템 개요