hermes-agent/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer-guide/context-engine-plugin.md
Teknium 76135b329d
docs(i18n): translate all docs into Simplified Chinese (zh-Hans) (#31942)
Translates the full English docs corpus (335 files) into Simplified
Chinese under website/i18n/zh-Hans/. Combined with PR #31895 (cross-
locale link fix), the 简体中文 locale toggle now serves a complete
Chinese site with working cross-page navigation.

Pipeline:
- Claude Sonnet 4.6 via OpenRouter, 8-way concurrent
- Preserves frontmatter keys, code blocks, MDX/JSX, link URLs, brand
  names, and technical jargon (prompt/token/hook/MCP/ACP/etc.)
- Translates only frontmatter title/description and prose
- Two largest files (configuration.md 93KB, research-paper-writing.md
  107KB) retried with 64K max_tokens after initial fence-drift
- 3 manual post-fixes for MDX edge cases the model didn't escape:
  < in optional-skills-catalog table, double-quotes in an alt= tag,
  and a bare URL adjacent to a full-width period

Cost: ~$30 total (Sonnet 4.6 input $3/M + output $15/M).

Verified `npm run build` succeeds for both en and zh-Hans locales,
no double-prefixed /docs/zh-Hans/docs/ URLs in rendered output,
all in-page navigation resolves correctly.

Translations are machine-generated and may need human review on
specific pages — but they're an enormous improvement over the
previous state (3 zh-Hans pages out of 335).
2026-05-25 01:47:38 -07:00

6.7 KiB
Raw Blame History

sidebar_position title description
9 Context Engine 插件 如何构建替换内置 ContextCompressor 的 context engine 插件

构建 Context Engine 插件

Context engine 插件用于替换内置的 ContextCompressor以实现管理对话上下文的替代策略。例如无损上下文管理LCM引擎通过构建知识 DAG 来替代有损摘要。

工作原理

Agent 的上下文管理基于 ContextEngine ABCagent/context_engine.py)构建。内置的 ContextCompressor 是默认实现。插件引擎必须实现相同的接口。

同一时间只能有一个 context engine 处于激活状态。选择由配置驱动:

# config.yaml
context:
  engine: "compressor"    # 默认内置
  engine: "lcm"           # 激活名为 "lcm" 的插件引擎

插件引擎永远不会自动激活 — 用户必须显式将 context.engine 设置为插件名称。

目录结构

每个 context engine 位于 plugins/context_engine/<name>/

plugins/context_engine/lcm/
├── __init__.py      # 导出 ContextEngine 子类
├── plugin.yaml      # 元数据name、description、version
└── ...              # 引擎所需的其他模块

ContextEngine ABC

你的引擎必须实现以下必需方法:

from agent.context_engine import ContextEngine

class LCMEngine(ContextEngine):

    @property
    def name(self) -> str:
        """短标识符,例如 'lcm'。必须与 config.yaml 中的值匹配。"""
        return "lcm"

    def update_from_response(self, usage: dict) -> None:
        """每次 LLM 调用后,以 usage dict 为参数调用。

        从响应中更新 self.last_prompt_tokens、self.last_completion_tokens、
        self.last_total_tokens。
        """

    def should_compress(self, prompt_tokens: int = None) -> bool:
        """若本轮应触发压缩则返回 True。"""

    def compress(self, messages: list, current_tokens: int = None,
                 focus_topic: str = None) -> list:
        """压缩消息列表并返回新的(可能更短的)列表。

        返回的列表必须是有效的 OpenAI 格式消息序列。

        ``focus_topic`` 是来自手动 ``/compress <focus>`` 的可选主题字符串;
        支持引导式压缩的引擎应优先保留与其相关的信息,其他引擎可忽略。
        """

引擎必须维护的类属性

Agent 直接读取这些属性用于显示和日志记录:

last_prompt_tokens: int = 0
last_completion_tokens: int = 0
last_total_tokens: int = 0
threshold_tokens: int = 0        # 触发压缩的阈值
context_length: int = 0          # 模型的完整上下文窗口
compression_count: int = 0       # compress() 已运行的次数

可选方法

这些方法在 ABC 中有合理的默认实现,按需覆盖:

方法 默认行为 何时覆盖
on_session_start(session_id, **kwargs) 空操作 需要加载持久化状态DAG、DB
on_session_end(session_id, messages) 空操作 需要刷新状态、关闭连接时
on_session_reset() 重置 token 计数器 有需要清除的会话级状态时
update_model(model, context_length, ...) 更新 context_length 和阈值 需要在切换模型时重新计算预算时
get_tool_schemas() 返回 [] 引擎提供 agent 可调用的工具时(例如 lcm_grep
handle_tool_call(name, args, **kwargs) 返回错误 JSON 实现工具处理器时
should_compress_preflight(messages) 返回 False 可在 API 调用前进行低成本预估时
get_status() 标准 token/阈值字典 有自定义指标需要暴露时

引擎工具

Context engine 可以暴露 agent 直接调用的工具。从 get_tool_schemas() 返回 schema并在 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}"})

引擎工具在启动时注入到 agent 的工具列表中并自动分发 — 无需注册到注册表。

注册

通过目录(推荐)

将引擎放置于 plugins/context_engine/<name>/__init__.py 必须导出一个 ContextEngine 子类。发现系统会自动找到并实例化它。

通过通用插件系统

通用插件也可以注册 context engine

def register(ctx):
    engine = LCMEngine(context_length=200000)
    ctx.register_context_engine(engine)

只能注册一个引擎。第二个尝试注册的插件将被拒绝并发出警告。

生命周期

1. 引擎实例化(插件加载或目录发现)
2. on_session_start() — 对话开始
3. update_from_response() — 每次 API 调用后
4. should_compress() — 每轮检查
5. compress() — 当 should_compress() 返回 True 时调用
6. on_session_end() — 会话边界CLI 退出、/reset、gateway 过期)

on_session_reset()/new/reset 时调用,用于清除会话级状态而不完全关闭。

配置

用户通过 hermes plugins → Provider Plugins → Context Engine 选择引擎,或直接编辑 config.yaml

context:
  engine: "lcm"   # 必须与引擎的 name 属性匹配

compression 配置块(compression.thresholdcompression.protect_last_n 等)专属于内置的 ContextCompressor。如有需要,你的引擎应定义自己的配置格式,并在初始化期间从 config.yaml 读取。

测试

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

另请参阅