Skip to content

reflex-guard

Verified

@niumingqing/reflex-guard · v0.1.4 · MIT

拦截+反思+重试守卫:执行前校验工具调用,违规回传可行动的反思提示,连续失败硬断升级。零依赖,可作独立模块或 DSH 插件。

Install

dsh plugin add @niumingqing/reflex-guard

Confirm the layer applied with dsh --profile default --dump-config — see the install guide.

Source

Tags

Creators

Readme

reflex-guard · 拦截 + 反思 + 重试 守卫

一个零依赖的「闸门」模块 + DSH 插件包装:在工具调用【执行前】校验,违规时回传一段带「原因 + 允许范围」的反思提示让模型重试,连续失败则硬断升级。

解决什么问题

  • 幻觉污染:模型调用未授权工具 / 写越界路径 / 直接覆盖文件 / 参数不合法。
  • token 浪费:模型跑偏后反复踩同一个错。
  • 性能:把「被动断掉」升级为「带原因的闭环重试」,成功率更高、轮次更少。

三个已知坑的解法(都有对应实现)

坑 解法 代码位置
副作用泄漏(半执行状态) Guard 只产出「决策」、绝不执行;拦截发生在执行前(fail-closed);越界/覆盖类动作被拦时尚未产生任何写入 lib/guard.js 的 submit()
假阳性死循环 每次违反都带 ruleId,硬断时打印完整规则ID轨迹;据此判断是规则太严(改规则)还是模型不行(改模型) lib/guard.js 的 trace + lib/logger.js
成本失控 maxRetry 硬上限(默认 2)+ shouldGuard 仅拦截关键工具 lib/guard.js + lib/index.js 的 createInterceptor

快速开始(不依赖 DSH,纯 Node)

运行演示:

node demo/demo.js

在你的智能体循环里接入:

import { Guard } from '@niumingqing/reflex-guard/guard';
import { writeScopeRule, forbidOverwriteRule, jsonSchemaRule } from '@niumingqing/reflex-guard/rules';
import { buildReflectPrompt } from '@niumingqing/reflex-guard/reflect';

const guard = new Guard({
  maxRetry: 2,
  rules: [
    writeScopeRule(process.cwd(), { onlyTools: ['write', 'edit'] }),
    forbidOverwriteRule(),
    jsonSchemaRule({ type: 'object', required: ['path'] }, { tools: ['edit'] }),
  ],
});

const res = guard.submit({ name: 'edit', args: { path: '/outside/x.txt' } });
if (res.decision === 'reflect') {
  // 把 buildReflectPrompt(res.violation) 追加回给模型,让它带原因重试
}

内置规则

  • jsonSchemaRule(schema, {ruleId, tools}) —— 参数校验
  • allowToolsRule([...], {ruleId}) —— 工具白名单
  • denyToolsRule([...], {ruleId}) —— 工具黑名单(被禁工具拒绝并回传反思提示)
  • writeScopeRule(root, {ruleId, pathKey, onlyTools}) —— 写范围(pathKey 默认 ['path', 'file_path'],可传单个或多个键覆盖)
  • forbidOverwriteRule({ruleId, pathKey, onlyTools}) —— 禁止覆盖:显式覆盖模式(mode=overwrite/replace)一律拒;且对整文件写工具(onlyTools 默认 ['write'])做目标存在性检查——目标已存在即拒。pathKey 默认 ['path', 'file_path']
  • composeRules([...]) —— 组合

作为 DSH 插件使用(镜像 dsh-ops)

一键安装(委托官方 DSH 命令行):

npx --yes @niumingqing/reflex-guard@latest install --profile desktop
# 桌面端若不在默认安装目录,需传 --dsh-cli <安装目录>/resources/runtime/cli/bin/dsh.cmd

或插件市场搜索 @niumingqing/reflex-guard 安装并启用。

reflex-guard install   --profile desktop --dry-run   # 只看会执行什么,不改动
reflex-guard status    --profile desktop             # 查看是否已安装/启用
reflex-guard uninstall --profile desktop             # 卸载

手动:把 cordis.patch.yml 的 insert 条目并入目标 profile 的 cordis.yml。

宿主入口 lib/index.js 把拦截接到 tools/pre-execute(返回 { kind: deny, reason } 即拒绝)与 ctx.tools.guard(返回 reason 字符串即拒绝),违规回传反思文本由 DSH 喂回模型完成重试。这两个钩子签名已对齐 [email protected] 的真实契约,并已用 DSH 自带 cordis + dsh-tools + dsh-fs-local 启动真实宿主验证通过(test/verify-host.mjs,18 项断言全过;demo/demo.js 为纯 Node 演示,7 个场景全过)。

配置(cordis.patch.yml 里的 config)

  • maxRetry:连续反思重试上限,默认 2
  • writeScope:是否启用写范围校验,默认 true;写范围根目录用 workspaceRoot 指定(默认 process.cwd())
  • forbidOverwrite:是否禁止直接覆盖写入,默认 true(0.1.4 起内置 write 覆盖已存在文件会被拦,不再只认 mode 参数)
  • forbidOverwriteTools:目标存在性检查覆盖的工具名列表,默认 ['write'](如需扩展到 edit/ops_replace 等在此配置)
  • writeTools:视为「写」的工具名列表,默认 [write, edit, replace, ops_replace, pwsh, rg_write]
  • allowTools:可选工具白名单(若配置且希望使用 rg_write,需把 'rg_write' 列入)
  • denyTools:可选工具黑名单;被禁工具调用会被拒绝,并走同一反思提示闭环(原因 + 允许范围 + 剩余次数)。黑名单优先于白名单裁决
  • schema / schemaTools:可选结构化参数校验
  • rgWrite:是否注册 rg_write 专用写工具,默认 true(写区详见下节)
  • writeZone:rg_write 的写区配置。root=写区根(默认 '.',相对会话工作目录解析);allowOverwrite=是否允许覆盖已有文件(默认 false)

rg_write:受控写区的专用写工具(B 方案)

DSH 宿主里注册一个零依赖的自定义工具 rg_write:在写区(writeZone.root)内写 UTF-8 文件,越出写区的路径(含 .. 与绝对路径)和覆盖已有文件都会被拒绝,拒绝理由为带「允许范围」的中文提示,模型可直接据其纠正。写区路径经 ctx.fs 落盘,生产环境由宿主沙箱(workspace-write 栅栏)兜底;0.1.2 起随写调用传入按会话解析的 sandboxPolicy,写区写入不再被 workspace-write 栅栏误拒。writeScope / forbidOverwrite 规则同样覆盖 rg_write(它在默认写工具列表里)。

writeZone: { root: 'rg-write-zone', allowOverwrite: false }

想要一个独立写环境时:把 writeZone.root 设成专用写区目录(如 D:/DSH-写区),并确保 allowTools 含 'rg_write'——模型的所有写操作就被约束在该写区内完成。

平台兼容性(如实说明,2026-10-16 源码级核实修正)

  • 此前文档称「DSH 对 write/edit 设有平台自我保护闸、拦不掉」,经对 DSH 0.2.0-rc.2 全库源码检索(295 个包)核实为误判:平台没有这类「自我保护闸」(社区插件 dsh-tool-guard 自带的 PROTECTED_TOOLS=['read','write','edit','bash'] 是它自己的常量,与平台无关;平台唯一保留的名字是 run_code)。真正原因是本插件 0.1.x 读错了执行对象字段——DSH 工具执行对象的规范字段是 exec.arguments(dsh-tools 源码 3061/3163-3167/3310),旧代码读 exec.args 在生产环境恒为空对象,导致 writeScope/forbidOverwrite/jsonSchema 全放行、只有按工具名判定的 denyTools 生效。0.1.1 已修复(读 exec.arguments,保留 args/params 兼容),writeScope/forbidOverwrite 现在对 write/edit 在生产环境真实生效(verify-host [3k] 用例以 arguments 形状验证)。
  • 平台的写边界是进程内策略栅栏(非内核边界):workspace-write 模式下 ctx.fs 的写被 dsh-fs-sandbox 限制在 workspaceRoot(会话 header.cwd,不可变)+ /tmp + 系统临时目录内,越界抛 FS_SANDBOX_DENIED;读取不受限。shell/代码域由 Windows ACL 受限令牌链兜底。详见同仓文档《DSH 独立写环境使用说明》(docs/DSH-独立写环境使用说明.md)。
  • denyTools / allowTools / jsonSchema 拦截工具调用入口,与上述修复无关,此前即已生效(真机验证覆盖)。

0.1.2 修复(2026-10-16)

  • rg_write 写区写入不再被 workspace-write 栅栏误拒:此前 rg_write 落盘时不传沙箱策略,dsh-fs-sandbox 回落无会话的部署默认策略(workspaceRoot=宿主 profile 目录),写区写入被误报 FS_SANDBOX_DENIED(file access denied under workspace-write mode)。0.1.2 起 rg_write 在 execute() 里先用 ctx.get('sandboxPolicy').resolve({session}) 按当前会话解析策略,并随 writeText 传入;若策略仍不允许,FS_SANDBOX_DENIED 会转成中文提示「rg_write 被宿主沙箱拒绝(当前会话文件策略不允许此写入)」。代码:lib/rg-write.js。
  • writeScopeRule 漏检 file_path 已修复:内置 write/edit 工具的参数名是 file_path 而不是 path,旧版单一路径键让这两个工具的参数越界写入直接漏过。0.1.2 起 writeScopeRule 支持多路径键,默认 ['path', 'file_path'],任一出现的路径越界即拒绝;config.writePathKey 仍可覆盖为单个或多个键。代码:lib/rules.js(buildRules 默认值在 lib/index.js)。

目录

  • lib/:核心(guard/rules/validate/reflect/logger/rg-write)+ DSH 宿主入口(index.js)
  • demo/:可运行演示
  • bin/:安装 CLI
  • dsh-plugin.json + cordis.patch.yml:插件清单与组件补丁

说明

  • 用途:解决幻觉问题 + 提升性能(少 token、少轮次、少跑偏)。
  • 发布:0.1.0 首发于 npm 包名 reflex-guard(账号 niu-ming-ping,该账号 2FA 丢失无法再发布);0.1.1 起发布为 @niumingqing/reflex-guard(新账号 niumingqing,包名含原名的 scoped 版,含 exec.arguments 字段修复与 rg_write 写区工具);0.1.2 修复 rg_write 沙箱策略按会话解析与 writeScope 双路径键检查(详见上文「0.1.2 修复」);0.1.3 补齐 repository/homepage(https://github.com/NIU-MING-qing/repository-homepage);0.1.4 修复 forbidOverwrite 对内置 write/edit 失效——旧实现只查 args.mode,而内置工具不传该参数恒放行;现改为对 write 做目标存在性检查(mode 检查保留,详见「内置规则」与「配置」)。
  • 写环境文档:《DSH 独立写环境使用说明》(docs/,与 README 同仓发布)。