☰
Decepticon 中间件插件开发实战:基于 decepticon-example-middleware 掌握 SDK 脚手架、入口点注册与框架装配
2026/10/13 9:27:58 网站建设 项目流程

【免费下载链接】Decepticon

Autonomous Hacking Agent for Red Team

项目地址:https://gitcode.com/gh_mirrors/de/Decepticon
点击查看免费下载

Decepticon 是面向红队场景的自主攻击 Agent 框架,其插件体系允许在不修改开源主代码的前提下,向任意 Agent 追加或替换中间件(middleware)。本文以官方示例decepticon-example-middleware为骨架,完整讲解中间件插件从decepticon-sdk plugin new脚手架生成、pyproject.toml入口点注册、uv build构建安装,到框架端build_middleware装配的完整生命周期,并给出基于FakeBackend/FakeLLM/FakeSandbox的免框架 hermetic 测试方法。读完本文,你将能独立编写、打包、安装并测试一个可被 Decepticon 自动发现的中间件插件。

中间件在 Decepticon 中的定位:一个协议、一组命名槽位

在 Decepticon 中,中间件是 Agent 每次模型调用(model call)前后的拦截与改写层,负责承载知识库注入、RoE 规则执行、HITL 审批、prompt 注入防护、预算控制、事件日志等横切能力。插件作者实现的中间件需要满足MiddlewareProtocol,这是一个@runtime_checkable协议,定义于 decepticon_core/protocols/middleware.py:

  • 必备属性:name(人读的中间件标识,用于内省)、slot(该中间件占据的MiddlewareSlot,接受枚举值或插件自定义字符串)、priority(槽位内的装配排序提示,数值越小越靠前;官方约定 OSS 中间件用 100/200/…,插件常用 50 表示"替换在标准之前"、150 表示"替换在标准之后")。
  • 必备方法:wrap_model_call(state, runtime, config)——Agent 运行器在每次模型调用时调用主回调。
  • 可选钩子(框架只调用存在的部分):before_agent、after_agent、modify_request。

MiddlewareSlot是一个StrEnum,声明顺序即装配顺序,完整枚举定义于 decepticon_core/contracts/slots.py,包括ENGAGEMENT_CONTEXT、ROE_GUARDRAIL、HITL_APPROVAL、UNTRUSTED_OUTPUT、PROMPT_INJECTION_SHIELD、SKILLS、FILESYSTEM、SUBAGENT、OPPLAN、KG、EVENT_LOG、SANDBOX_NOTIFICATION、OPSCONTROL_NOTIFICATION、BUDGET、MODEL_OVERRIDE、MODEL_FALLBACK、PROXY_KEY_OVERRIDE、SUMMARIZATION、PROMPT_CACHING、PATCH_TOOL_CALLS等约 20 个命名槽位。

每个 Agent 角色(role)只装配自己声明的那部分槽位,映射关系集中在SLOTS_PER_ROLE(同样定义于 slots.py):例如recon/exploit/postexploit等 bash 执行型专家使用_BASH_AGENT_SLOTS,analyst/contract_auditor/ad_operator在 bash 槽位集之上额外启用KG槽位,而blue_cell有独立的最小槽位集。插件中间件通过slot属性声明自己挂靠的位置——示例中挂到SKILLS槽位(MiddlewareSlot.SKILLS)。

值得注意的安全约束:SAFETY_CRITICAL_SLOTS集合(slots.py)标记了ENGAGEMENT_CONTEXT、ROE_GUARDRAIL、UNTRUSTED_OUTPUT、PROMPT_INJECTION_SHIELD、HITL_APPROVAL等槽位为安全关键项。插件对这些槽位做替换是允许的(前提是新实现遵守原契约),但直接禁用会触发装配期异常,除非设置环境变量DECEPTICON_ALLOW_SAFETY_OVERRIDES=1——这一门禁由 decepticon/agents/build.py 中的_check_safety_gate强制实施,防止误装插件静默瓦解安全护栏。

示例项目解剖:HelloMiddleware 的三处关键代码

示例项目位于 packages/decepticon-sdk/examples/middleware,是标准的 src-layout PyPI 包,由脚手架命令decepticon-sdk plugin new生成(命令本身定义于 decepticon_sdk/scaffold/cli.py,对应的中间件代码模板在 decepticon_sdk/scaffold/templates.py)。其源码只有一份文件 src/decepticon_example_middleware/init.py,包含三处关键结构:

"""Custom middleware contributed to Decepticon.""" from __future__ import annotations from decepticon_sdk import MiddlewareProtocol, MiddlewareSlot class HelloMiddleware: """Minimal MiddlewareProtocol-compliant middleware.""" name = "decepticon_example_middleware" slot: MiddlewareSlot | str = MiddlewareSlot.SKILLS priority = 150 def wrap_model_call(self, state: object, runtime: object, config: object) -> object: return state def get_middleware(role: str | None = None, **_: object) -> list[MiddlewareProtocol]: """Plugin factory called by the framework's middleware loader.""" del role return [HelloMiddleware()]

逐段解读:

  1. 导入面(Import surface):只从decepticon_sdk导入,不触碰任何带下划线前缀的框架内部模块。SDK 的init.py 重新导出decepticon-core的协议、契约与注册表,这正是"一个完整的插件只需要一条 import 语句"的设计目标(Phase 3 surface)。__all__中列出的公开名称遵循 SemVer 稳定性承诺。

  2. 中间件类:HelloMiddleware声明slot = MiddlewareSlot.SKILLS(挂靠 skills 槽位)与priority = 150(在标准 skills 中间件之后装配)。wrap_model_call原样透传state,是一个最小可用实现——真实中间件在此处对 state 做改写(例如向系统消息追加策略、记录日志、改写模型请求)。MiddlewareProtocol是@runtime_checkable的,因此isinstance(mw, MiddlewareProtocol)在运行时可以用于防御性校验。

  3. 工厂函数get_middleware:这是框架 loader 约定的可调用形状——接收role=关键字(可据此按角色裁剪贡献内容),返回中间件实例列表。示例中忽略role并固定返回[HelloMiddleware()]。

配套的 pyproject.toml 中,注册入口是插件被发现的关键:

[project.entry-points."decepticon.middleware"] decepticon_example_middleware = "decepticon_example_middleware"

这里decepticon.middleware是入口点组名,右侧值指向模块decepticon_example_middleware(模块级get_middleware工厂会被 loader 调用)。其余构建元数据:requires-python = ">=3.13"、依赖decepticon-sdk、构建后端hatchling、wheel 打包目标src/decepticon_example_middleware。

仓库对示例结构有结构不变式测试保障:tests/test_examples.py 参数化地对六类示例(tool / middleware / agent / callback / skill / prompt)断言三件事:示例目录存在且含pyproject.toml、README.md、src/decepticon_example_<kind>/__init__.py;pyproject.toml声明了与 kind 匹配的入口点组(middleware 对应decepticon.middleware)且入口点引用模块名decepticon_example_middleware;生成的__init__.py在 Python 3.13 下可被 AST 解析(语法可编译)。

构建与安装:uv build 到 pip install

按示例 README 的指引,构建与安装分两步:

uv build pip install dist/*.whl

uv build使用 hatchling 构建出 wheel(产出物位于dist/下),pip install dist/*.whl将 wheel 装入当前 Python 环境。安装完成后,wheel 的 metadata 会携带decepticon.middleware入口点声明;此后任何 Decepticon Agent 工厂在构造时都会通过importlib.metadata.entry_points发现该贡献,无需对框架做任何注册动作。也可以不先构建,直接以可编辑方式安装(pip install -e .),入口点同样生效。

适用前提:示例与 SDK 均要求 Python>=3.13;SDK 依赖decepticon-core(协议与契约的载体)与typer>=0.9.0(脚手架 CLI 用)。安装 SDK 本体使用pip install decepticon-sdk;若需要测试辅助设施(FakeBackend/FakeLLM/FakeSandbox)与脚手架能力,安装pip install "decepticon-sdk[testing]";若需要基于真实(mock)框架实例的 fixture,则安装pip install "decepticon-sdk[fixtures]"(该 extra 会拉入decepticon框架本体),详见 packages/decepticon-sdk/README.md。

框架端装配:build_middleware 如何把插件放进 Agent 栈

安装后,插件中间件进入 Agent 栈的路径是build_middleware(decepticon/agents/build.py),其装配逻辑可以概括为四个阶段:

  1. 角色槽位解析:slots未显式传入时按SLOTS_PER_ROLE.get(role)查表;查不到且未显式传入则抛KeyError——插件自带的编排 Agent 使用自定义角色名时必须显式传slots=,框架拒绝静默构建空栈。
  2. 覆盖解析与安全门禁:_resolve_overrides合并显式overrides/disabled_slots与插件入口点返回的PluginBundle覆盖,随后_check_safety_gate校验安全关键槽位(前文所述)。
  3. 按枚举顺序装配标准槽位:以DEFAULT_SLOT_FACTORIES(decepticon/agents/middleware_slots.py)为基座,factories.update(resolved.middleware_replace)浅合并插件替换,然后遍历MiddlewareSlot枚举声明顺序,跳过角色未启用或已禁用的槽位,逐槽调用工厂(统一签名f(*, backend, llm, role, fallback_models, sandbox, subagents));工厂返回None的槽位(如无条件成立的MODEL_FALLBACK、KG 不可用时的KG)被静默跳过。
  4. 追加插件中间件:result.extend(load_plugin_middleware(role=role, backend=backend))(build.py)——非覆盖式(additive)插件中间件统一追加在标准槽位之后,这是不替换任何标准槽位、只想"尾巴上挂一个中间件"的向后兼容逃生口。

load_plugin_middleware最终落到decepticon_core.plugin_loader的_discover通用发现逻辑(plugin_loader.py):

  • 通过entry_points(group="decepticon.middleware")枚举入口点;
  • 逐个ep.load();加载失败的插件记录日志后跳过,框架回退到 OSS 行为,保证纯 OSS 环境与坏插件环境下框架不被拖垮;
  • 对返回值做三种形状归一化:可调用且不是运行时对象(_looks_like_runtime_object通过invoke/before_agent/modify_request/after_agent等属性启发式判别)→ 以obj(role=role, **deps)调用工厂;list/tuple→ 原样展平;单个运行时实例 → 包装成单元素列表;
  • 若返回PluginBundle包装,则先经is_bundle_enabled(result.bundle)做 bundle 白名单过滤(默认只启用standard,DECEPTICON_PLUGINS环境变量或.decepticon.toml/pyproject.toml的[plugins].enabled可扩展,"*"为通配),再展平result.items。

关于priority的语义:示例 README 只标注了priority = 150,从 middleware.py 的约定看,这是一个"装配顺序提示(数值小者优先)"——OSS 中间件用 100/200/…,插件常用 50(replace before)或 150(replace after)。需要说明的是,非覆盖式插件中间件在build_middleware中统一追加到标准槽位之后(第 4 阶段),因此priority的实际影响主要体现于插件之间的相对顺序及作为面向未来的契约字段。

用 SDK 测试辅助设施编写免框架的 hermetic 测试

示例 README 的测试部分是关键工程实践:

pip install decepticon-sdk[testing] pytest

测试辅助设施位于 decepticon_sdk/testing/init.py,提供三个内存级 fake,各自满足decepticon_core.protocols对应的 Protocol,因此被测代码可以安全地做isinstance(fake, BackendProtocol)之类的运行时检查,而无需拉起真实框架:

  • FakeBackend:以 Python dict 为后端的BackendProtocol实现。read(path, offset=, limit=)兼容 deepagents 的切片语义;write/list/exists均无 IO。构造示例:FakeBackend({"/skills/recon/index.md": "..."})。
  • FakeLLM:脚本化的LLMProtocol。按顺序逐次返回responses列表中的条目;calls属性记录每次invoke()的输入,便于断言;响应耗尽后再调用会抛IndexError,防止"多调一次却静默成功"的假阳性测试。
  • FakeSandbox:无操作SandboxProtocol。execute_command()被记录进self.commands,并按构造时的responses队列返回 stdout(队列耗尽后返回空串),用于断言命令构造逻辑而不启动沙箱容器。

一个典型的 hermetic 测试形态(README 的指导用法展开):

from decepticon_sdk.testing import FakeBackend, FakeLLM, FakeSandbox from decepticon_example_middleware import HelloMiddleware def test_middleware_passthrough(): mw = HelloMiddleware() state = {"messages": []} # wrap_model_call 的第二个参数是 runtime(如 llm),第三个是 config out = mw.wrap_model_call(state, object(), object()) assert out is state # 透传语义

针对更真实的中间件(会读取 backend、调用 llm、执行沙箱命令)可组合三者:用FakeBackend预置技能文件、用FakeLLM(responses=[...])固化模型输出、用FakeSandbox记录命令序列,从而在完全脱离框架与容器的前提下验证插件的输入输出契约。这三个 fake 覆盖约 80% 的插件测试场景;README 亦注明未来会补充make_test_engagement/make_test_opplan以支持更丰富的 engagement 级 fixture。

从示例到生产:替换/禁用/安全门禁与常见扩展方向

示例是"最小可运行",真实插件往往需要与框架的PluginBundle机制配合(plugin_loader.py)。中间件相关的覆盖字段:

  • disabled_middleware:按槽位名(MiddlewareSlot的枚举值字符串)跳过装配;
  • replaced_middleware:槽位名 → 工厂可调用,工厂签名与DEFAULT_SLOT_FACTORIES一致(f(*, backend, llm, role, fallback_models, sandbox, subagents)),返回中间件实例或None;
  • items:纯追加形态,等同本文主线的入口点直返列表;
  • roles:覆盖作用域过滤(空元组 = 作用于所有触发加载的角色);
  • bundle:bundle 白名单标签,None= 安装即加载。

示例(来自 plugin_loader.py 的文档示例):禁用 OSS 的 prompt-caching 并用厂商版替代——

PluginBundle( bundle="vendor", disabled_middleware=("prompt-caching",), items=(VendorCacheMiddleware(),), )

替换ask_user_question之类的工具、按角色重定向模型等其它能力同理。此外,contracts/contributions.py 还提供聚焦的MiddlewareContribution(items/disabled_slots/replaced_slots/roles,roles为空元组时构造直接抛ValueError,杜绝隐式"全角色生效")以及SafetyDeclaration(插件只能新增安全关键项,不能撤销 OSS 声明的安全项)。

扩展路径的常见选择:对已有槽位做增强(如企业审计策略注入EVENT_LOG前后)优先考虑replaced_middleware或追加模式;实现全新横切能力(如自定义加密、流量改写)可声明自定义 slot 字符串或直接追加;无论如何,务必遵守安全门禁——涉及SAFETY_CRITICAL_SLOTS的替换必须保证新实现遵守原契约(例如替换ENGAGEMENT_CONTEXT的中间件仍须注入 RoE 范围约束),否则不仅装配期会被拒,更可能在运行时静默破坏安全叙事。

小结

从decepticon-sdk plugin new --kind=middleware生成骨架、在__init__.py中实现MiddlewareProtocol与get_middleware工厂、在pyproject.toml的decepticon.middleware入口点组注册、uv build打包安装,到框架build_middleware按枚举顺序装配并追加插件中间件——Decepticon 的中间件插件链路是一条无侵入、可回退、带安全门禁的完整闭环。配合decepticon-sdk[testing]的FakeBackend/FakeLLM/FakeSandbox,插件作者可以在不启动框架、不拉起容器的前提下获得确定性的单元测试体验。本文相关的可继续深入阅读材料:协议契约 decepticon_core/protocols/middleware.py、槽位与角色映射 decepticon_core/contracts/slots.py、发现机制 decepticon_core/plugin_loader.py、框架装配 decepticon/agents/build.py、默认槽位工厂 decepticon/agents/middleware_slots.py 以及 SDK 测试辅助设施 decepticon_sdk/testing/init.py。

【免费下载链接】Decepticon

Autonomous Hacking Agent for Red Team

项目地址:https://gitcode.com/gh_mirrors/de/Decepticon
点击查看免费下载
上一篇:TFLearn 深度学习库指南:基于 TensorFlow 的高层 API 从安装、建模到训练可视化
下一篇:RPFM的DB表格编辑器深度评测:像Excel一样编辑总战争兵种与科技数据表

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询