用 dsh-stream-rules 按需给 Agent 注入引导规则

前言

给编码 Agent 加约束,最常见的做法是把规则写进系统提示:不要直接 pip install、访问 GitHub API 请用 gh、读 PDF 走指定 skill。规则一多,每一步都要带着这些文字进上下文,真正触发的场景却很少。上下文被占着,模型还不一定记得住。

DeepSeek Harness(dsh)的核心理念是「一切皆插件」:模型、工具、会话、UI 都可以用插件增删替换。社区里因此出现了不少按这个思路做的扩展。dsh-stream-rules 做的事情比较窄:平时不往系统提示里塞规则,只在工具调用匹配到模式时,才注入一条 steering 引导。需要时给提醒,平时不占上下文。

需要先说明:本文写的是社区插件。DeepSeek Harness 本身由 DeepSeek 开源,插件目录站点 deepseek-harness-plugin.com 是独立的社区索引,与 DeepSeek / 幻方没有官方从属关系,也不是官方应用商店。安装前应自己看源码和许可证。

这是什么

dsh-stream-rules 是一款 DeepSeek Harness 的「工具与能力」插件,由 jiesou 维护,仓库在 jiesou/dsh-stream-rules,许可证为 MIT。npm 包名是 @jiesou/dsh-stream-rules。截至 2026-08-18,GitHub 与目录页均显示 4 个 star;仓库 package.json 与 npm 上的版本均为 0.1.7

作者把它定位为 jiesou/opencode-stream-rules 到 DSH 的移植。README 里写思路类似 oh-my-pi 的 Time-traveling stream rules:规则平时休眠,匹配后再注入,避免每轮都付上下文税。实现上两者并不相同。oh-my-pi 会在流式输出中途打断并重试;dsh-stream-rules 挂在 DSH 的 tools/pre-execute 上,匹配对象是「工具名 + 序列化后的参数」,代码集中在单个 src/index.ts(约 60 行),没有改 Harness 核心,也没有 monkey-patch。

装上之后默认不会生效。你需要自己写规则文件,插件才会在匹配时注入引导。

工作原理

插件监听 tools/pre-execute。这是 DSH 文档里的允许 / 拒绝 / 询问瀑布流:工具真正执行前,插件可以放行、拒绝,或往后续步骤排队一段模型可见的上下文。官方说明里,agent.inject() 追加的是下一次模型请求能看到的上下文,它不是唤醒空闲 Agent 的接口。

一次工具调用进来后,插件大致按下面的顺序处理。

  1. 把工具名和参数展平成一段字符串,对规则列表做 match。命中的是第一条返回 true 的规则。
  2. agentId + 规则下标 做去重。同一条规则在每个会话、每个 agent 上最多触发一次,和上游实现里的 notified 去重一致。
  3. 若规则带 reject: true,第一次命中时返回 { kind: 'deny', reason: prompt },这次工具调用被拒绝;同一条规则再次命中则放行。
  4. 若未设置 reject,则通过 agent.inject() 注入一条 SYSTEM NOTICE: … 引导,然后 next() 放行当前这次调用。引导进入下一次 pre-step 的模型可见上下文。

这两条路径要分开看。README 把整体效果概括成「注入引导后 agent 从同一位置重试」,更贴近 reject: true 的行为:第一次拦住,模型看到拒绝原因后再试。默认路径不会拦住当前这次调用,只是把提示排进后续上下文。如果目标是「第一次就不准执行」,需要显式写 reject: true

匹配用的是普通函数,不是正则引擎。match 的入参是扁平化后的字符串,里面同时包含工具名和参数里的文本,因此示例里用 v.includes('pip') && v.includes('install') 这种写法就能工作。

安装与启用

社区目录页给出的安装命令如下,在 DeepSeek Harness 终端里运行即可:

dsh plugin add github:jiesou/dsh-stream-rules

如需可复现安装,目录页建议固定 commit 哈希:

dsh plugin add github:jiesou/dsh-stream-rules#<commit>

仓库 README 还提供了指定 profile 的写法,并推荐从 npm 安装预构建产物:

dsh plugin --profile <name> add @jiesou/dsh-stream-rules

从 GitHub 安装时:

dsh plugin --profile <name> add github:jiesou/dsh-stream-rules

也可以在 profile 的 cordis.patch.yml 里加一行:

- id: stream-rules
  name: '@jiesou/dsh-stream-rules'

当前仓库里已经包含 lib/ 编译结果,package.jsonmain 指向 lib/index.js。README 写 GitHub 安装会跑 prepare 做构建,但写作时看到的 package.json 并未声明 prepare 脚本;若选择 GitHub 安装,以当时仓库里的构建产物和 DSH 对 git 依赖 prepare 的提示为准。官方文档也说明:从 git 安装等于执行第三方代码,pnpm 高版本可能要求你显式允许构建脚本。只安装你审查过的来源,并尽量钉死 commit。

插件以当前 dsh 进程的权限运行,安装时可能执行代码。安装前请检查源代码仓库和 MIT 许可证。

编写规则

安装只是把插件挂进 profile。规则要自己写。仓库 rules/ 目录里目前只有 rules.js.example,以 _ 开头的文件会被跳过。

先找到插件目录。$DSH_HOME 默认是 ~/.dsh

$DSH_HOME/profiles/<name>/node_modules/@jiesou/dsh-stream-rules

然后把示例改名为本地规则文件:

mv rules/rules.js.example rules/rules.local.js

rules/*.local.js 已被仓库 .gitignore 忽略,适合放本机规则。直接改 node_modules 里的文件,升级插件时容易被覆盖。更稳妥的做法是把规则放到自己的目录,再用 config.rules 指过去:

- id: stream-rules
  name: '@jiesou/dsh-stream-rules'
  config:
    rules: /path/to/your/rules

示例规则来自仓库 README,可以直接作为起点:

// rules/rules.local.js
export default [
  {
    match: (v) =>
      v.includes('pip') &&
      v.includes('install') &&
      !v.includes('uv pip') &&
      !v.includes('uvx'),
    reject: true,
    prompt: 'Use `uvx` or `uv venv` + `uv pip` instead of `pip install` directly',
  },
  {
    match: (v) => v.includes('curl') && v.includes('api.github.com'),
    prompt: 'Prefer using `gh` cli over `curl https://api.github.com/...`. gh offers more requests limits.',
  },
  {
    match: (v) => v.includes('pdf'),
    prompt: 'Use the `markitdown` skill to read PDF files.',
  },
  // add your rules here
]

字段含义如下。

  • match:必填。(v: string) => boolean。每次工具调用都会被扁平化成字符串再匹配。
  • prompt:必填。注入给模型的引导文本;reject: true 时同时作为拒绝原因。
  • reject:可选。为 true 时,第一次命中拒绝该次工具调用,之后同一条规则再命中会放行。

第一条示例把裸 pip install 拦住,提示改用 uvx / uv pip,但又排除了已经走 uv 的调用。reject: true 只拦第一次,后续重试会放行,README 给的理由是:引导边界,但不要把模型锁死,例如环境已经在容器里时,仍允许它完成安装。第二条、第三条只有 prompt,匹配后注入引导,不拒绝当前这次调用。

规则文件可以是 .js.ts,默认导出一个数组。加载失败时插件会在控制台打出 [dsh-stream-rules] failed to load …,不会把整个工具调用打掉。

适用场景与注意事项

适合已经在用 DeepSeek Harness、希望用少量本地规则约束工具习惯的人。例如统一包管理器、引导用 gh 而不是手写 curl、提醒走某个 skill 读 PDF。它不是权限系统,也不是沙箱:reject: true 只对「该 agent 上这条规则的第一次命中」生效,之后会放行;默认路径甚至不会拦住当前这次调用。需要硬拦截的策略,应使用 DSH 自己的 tools/pre-execute 权限门、ctx.tools.guard() 或沙箱插件,而不是只靠这个轻量引导。

匹配是子串函数,不是结构化 schema 校验。工具名和参数被拼成一段文本,规则写得太宽容易误伤,写得太窄又可能漏掉。每条规则每个 agent 只触发一次,同一会话里模型若换一种写法再次违规,这条规则不会再响。

实现上它依赖 @deepseek-ai/cordis@deepseek-ai/dsh-llm@deepseek-ai/schemastery 等 peer 依赖,并声明需要 toolsagents 两个服务。DeepSeek Harness 仍在 developer preview,扩展点若有不兼容变更,社区插件也可能要跟着改。以当时安装的 dsh 版本和插件源码为准。

再次强调:插件以当前 dsh 进程权限运行。安装社区插件等于在本机执行第三方代码,请先看仓库、许可证和 cordis.patch.yml,需要可复现环境时固定 commit。

小结

dsh-stream-rules 把「行为边界」从系统提示里拿出来,改成工具调用上的按需注入。规则自己写,匹配才说话,不匹配就不占上下文。实现小,扩展点也是 DSH 文档里已有的 tools/pre-executeagent.inject()

目录页:https://deepseek-harness-plugin.com/zh-CN/plugins/dsh-stream-rules/

GitHub:https://github.com/jiesou/dsh-stream-rules

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜