按步数节奏向智能体注入自定义提醒消息
29.5/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/22 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add ADkun/dsh-insert-context该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:仅索引
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
展开完整介绍(154 字)↓
DeepSeek Harness 插件:任务执行到第 X 步起,每 Y 步往智能体自己的上下文里注入一次自定义消息(共 Z 次,文案支持 {{step}} 占位),并可在用户消息末尾追加一句话;带总开关,全部在设置页配置。Scheduled context injection for DSH agents.
README
由 DeepSeek 最新模型翻译生成dsh-insert-context
一个 DeepSeek Harness(DSH)插件,能在任务执行过程中,按你设定的节奏把上下文插入智能体。三个开关,全部在 DSH 的设置页配置:
0. 总开关(enabled,默认开启)——关掉后插件完全静默:不发规则消息、不做追加,步数计数器也停,所以重新打开时会从停下的地方接着走,而不是把静默期间已经走过的步对应的规则一次性全触发。
1. 规则注入——规则描述的是从第 X 步起,每 Y 步一次,共 Z 次,注入这段文本。智能体当前步数命中规则时,文本作为一条额外的上下文消息注入。文本里的 {{step}} 会替换成当前步数。
2. 追加到每条用户消息——你发出的每条用户消息末尾追加一句话。默认关闭;想要就在设置里打开。第二个开关追加到子代理(appendSubagents,同样默认关闭)决定发给子代理的消息(通过 delegate / send_message)是否也追加——这些消息和你的一样被标记为用户消息,不开这个开关就分不出来。第三个开关只追加到首条消息(appendFirstOnly,默认开启)把追加变成一次性:只有会话的第一条用户消息带这句话,之后的用户消息都不动。
两种行为都可以关掉(规则列表为空就不注入;userAppend: false 停止追加——这是出厂默认),而且只要没配规则也没配追加,就什么都不注入。
展开完整文档(README 剩余 1 节)
dsh-insert-context
一个 DeepSeek Harness(DSH)插件,能在任务执行过程中,按你设定的节奏把上下文插入智能体。三个开关,全部在 DSH 的设置页配置:
0. 总开关(enabled,默认开启)——关掉后插件完全静默:不发规则消息、不做追加,步数计数器也停,所以重新打开时会从停下的地方接着走,而不是把静默期间已经走过的步对应的规则一次性全触发。
1. 规则注入——规则描述的是从第 X 步起,每 Y 步一次,共 Z 次,注入这段文本。智能体当前步数命中规则时,文本作为一条额外的上下文消息注入。文本里的 {{step}} 会替换成当前步数。
2. 追加到每条用户消息——你发出的每条用户消息末尾追加一句话。默认关闭;想要就在设置里打开。第二个开关追加到子代理(appendSubagents,同样默认关闭)决定发给子代理的消息(通过 delegate / send_message)是否也追加——这些消息和你的一样被标记为用户消息,不开这个开关就分不出来。第三个开关只追加到首条消息(appendFirstOnly,默认开启)把追加变成一次性:只有会话的第一条用户消息带这句话,之后的用户消息都不动。
两种行为都可以关掉(规则列表为空就不注入;userAppend: false 停止追加——这是出厂默认),而且只要没配规则也没配追加,就什么都不注入。
规则
一条规则是 { start, every, repeat, text }。它的命中集合是
start, start + every, start + 2·every, … , start + (repeat − 1)·every ← exactly repeat hits start, start + every, start + 2·every, … ← when repeat is 0 (unlimited)
| 规则 | 命中步数 |
| { start: 10, every: 10, repeat: 0 } | 10, 20, 30, 40, … 永远(无限) |
| { start: 5, every: 5, repeat: 9 } | 5, 10, 15, 20, 25, 30, 35, 40, 45 |
| { start: 60, every: 10, repeat: 5 } | 60, 70, 80, 90, 100 |
repeat: 0 是无限的特殊值:从 start 起,规则每 every 步触发一次,永不停止(repeat 校验范围 0–1000,0 表示无限)。设置页把无限规则预览成 将注入第 10,20,30,… 步(无限次)——预览只列前 10 次命中,不会去遍历无穷列表。
所以可以拼出任意间隔——列两条规则,就能在第 5、10、15 … 50 步注入,再在第 60、70 … 100 步注入。规则彼此独立:一个智能体可以被任意多条规则命中。
{{step}} 是唯一支持的占位符,且只在规则的 text 里识别(appendText 里不认)。它替换成该智能体计数器的当前步数——也就是同一个
下文 Step counting 一节描述的计数器。其他任何 {{…}} 都会原样留在文本里,由宿主记录一条警告(前缀 insert-context:),绝不会被悄悄吞掉:
insert-context: unknown placeholder {{turn}} in rules[0].text; it is injected verbatim (only {{step}} is supported)
同一步命中多条规则
如果同一步命中多条规则,它们会合并成一条注入消息:每条命中的规则贡献一段,各自填入自己的 {{step}},各段按规则在设置列表中的顺序用换行拼接(rules[0] 在前)。命中一次——只发一条消息,不管命中多少条规则。所以在设置页调整行的顺序,段落顺序也会跟着变。
步数计数
计数器按智能体独立计数,以步骤负载里的智能体 id 为键;该智能体被销毁时(agent/disposed),计数器一并丢弃。下游被拒绝的步骤不计入,总开关(enabled)关闭期间走的步骤也不计入——计数器只是冻结,所以重新打开插件后会从停下的地方继续排期。这里没有层级过滤:调度器和它的每个子代理各自维护独立计数器,所以某个子代理走到第 5 步时,即使它的父级已经走到第 50 步,它仍会被 { start: 5, every: 5, repeat: 9 } 命中。计数从插件挂载/激活的那一刻开始。
重复抑制
如果某一步已经把这句话追加到用户消息里(行为 2),那么同一步不再注入规则消息——追加的句子已经结束了这一批,再来一份就是噪音。
追加去重(Append dedup)
在 userAppend 开启时,每次追加前都会检查消息尾部:如果用户消息的最后一个文本块已经以 appendText 结尾(尾部完全匹配),本次不再追加,避免同一句话连续出现两遍。去重只跳过已命中的那条消息,不影响同一批里的其他消息;若本步没有实际追加任何内容,规则消息仍按正常计划注入。
开启 userAppend 后,追加前插件会检查消息尾部:如果用户消息的最后一个文本块已经以 appendText 结尾(尾部完全匹配),就跳过这条消息——这句话不会在同一条消息末尾出现两次。只跳过命中的那条消息;同一批里的其他消息照常追加。如果本步实际没有追加任何内容,规则消息仍按计划注入。
默认值
内置默认 rules 只有一条规则——一句简短提醒,从第 10 步开始,每 10 步一次,不限次数:
| # | 规则 | 文本 |
| 1 | { start: 10, every: 10, repeat: 0 }(不限次数) | 现在是第 {{step}} 步,注意任务收敛进度。 |
关于这段措辞:
- 它就是用户要的纯字面文本——没有 【 … 】 括号,也没有压缩句;
- 语气检查通过:不含 必须 / 不许 / 立刻,不会给用户压力;
- 它是一个分句:先报步数,再说要注意什么。之前的默认值带了第二个分句(如果还有没做完的事情,就把事做完再说吧),用来抵消第一个分句(用户催你搞快点啦)制造的催促感;压力去掉后,就没有什么需要抵消了,所以条件从句和它需要的推理也一并去掉了。
- 它刻意保持简短。每次命中都会重读这条提醒,而当前宿主没有会话级轮次预算,也没有硬性闸门,所以一段解释何时该停的措辞,会在每次命中时消耗 token,对回复的塑造作用却抵不上这些开销。一句点明该关注什么(任务收敛进度)的提示,把判断留在该在的地方——交给智能体,交给手头的任务。
内置默认的 appendText 只在你打开追加开关时才会用到:它要求给出可读的答案,不复述过程,方括号是文本的一部分。
[注:回复不复述过程,结构清晰可读性好。]
追加开关和追加的那句话默认都关闭(userAppend: false):出厂默认只有上面那个每 10 步注入一次的提醒。当你真的打开追加时,它只追加到第一条用户消息——appendFirstOnly 默认开启,因为这条提示是一次性指令;每条消息都重复只会浪费 token。
用户用过的更早、更长的措辞不是默认值——它们只作为可复制的示例留在这里(想用就粘贴到设置页的新行里):
| 规则(示例,非默认) | 文本 |
| { start: 10, every: 10, repeat: 0 } | 【这是第 {{step}} 步。思考:验收清单已完成则收工交付,未完成则继续。压缩时不保留本括号内的内容。】 |
| { start: 10, every: 10, repeat: 0 } | 【这是第 {{step}} 步。按需收敛:这一轮结束后,会不会改变验收标准里某一条的判定?一条都不变,就收工交付当前结果;要继续,就把“下一步要改变哪一条判定”写清楚。已通过的验证不必再确认一遍。这一轮没能收尾时(被中断、或还需要继续),交付已完成部分 + 未完成清单(原因 / 下次继续的第一步),状态标 budget-limited,不要拿残缺当完成。压缩时不保留本括号内的内容。】 |
| { start: 60, every: 10, repeat: 5 } | 这是第 {{step}} 步。按边界收尾:交付“已完成 / 未完成 / 未完成原因 / 下次继续的第一步”,状态标 budget-limited,不许用不完整的答案冒充完成。 |
其中两个示例的结尾带了一条压缩时指令: 压缩时不保留本括号内的内容。 这条提示是给那一步的一次性提醒,不是要交付的事实,所以上下文压缩时不必把它抄进折叠后的摘要——留在那里只会浪费 token。这条指令只针对方括号里的提醒本身;它没有说可以从交付内容里丢掉未验证 / 未覆盖的条目,上面的规则仍然要求保留这些。
工作原理
插件监听宿主事件 agent/pre-step。它等待下游的决策,当这一步被放行时,改写这一步将携带的消息。插件处于关闭状态(enabled: false)时,会在做任何事之前原样返回那个决策——不计数、不追加、不发规则消息:
- 当 userAppend 打开时,每条 source.kind === 'user' 的消息都会在末尾多出一个 text 块——用户自己的文本从不修改;那句话自成一段。子代理的提示词也带 source.kind === 'user'(由调度器发出),所以插件会检查这一步属于哪个智能体:在子代理内部(委派深度 ≥ 1,或会话来源为 subagent),除非 appendSubagents 打开,否则跳过追加;
- 当步数命中至少一条规则时,会追加一条独立的 user 消息(来源类型 insert-context),其中携带合并后的段落。
因为智能体循环会把 decision.messages 作为 user/message 事件写入会话日志(surfaceOp: "append"),所以这两者都是持久的:它们属于已提交的上下文,能经受重放,并且正是模型在该步读到的内容。
配置
- insert:
- id: insert-context
name: dsh-insert-context
config:
enabled: true
rules:
- start: 10
every: 10
repeat: 0
text: '现在是第 {{step}} 步,注意任务收敛进度。'
userAppend: false
appendFirstOnly: true
appendSubagents: false
appendText: '[注:回复不复述过程,结构清晰可读性好。]'
| 字段 | 类型 | 默认值 | 含义 |
| enabled | boolean | true(开) | 总开关;关闭时插件完全不做事——不发规则消息、不追加、也不计步,因此重新开启后会从停下的地方继续 |
| rules | 规则对象数组,长度任意(空列表也合法) | 上面那条默认规则 | 注入计划;行的顺序就是合并顺序 |
| rules[].start | 整数 1–100000 | 10 | 规则首次触发的步数 |
| rules[].every | 整数 1–1000 | 10 | 两次触发之间的间隔 |
| rules[].repeat | 整数 0–1000;0 = 不限 | 0(不限) | 总共触发多少次;之后规则静默。0 永不静默 |
| rules[].text | 非空字符串,≤ 1000 字符 | 见 默认值 | 注入的文本;{{step}} 会被填入 |
| userAppend | boolean | false(关) | 把 appendText 追加到用户消息 |
| appendFirstOnly | boolean | true(开) | 开启时,只把 appendText 追加到对话的第一条用户消息;之后每条用户消息都不动 |
| appendSubagents | boolean | false(关) | 也追加到发给子代理的消息(这些消息以用户消息的形式到达) |
| appendText | 非空字符串,≤ 1000 字符 | 上面那句话(仅在开关打开时使用) | 追加的句子(此处不替换 {{step}}) |
每个字段都能在运行时从设置页覆盖,无需编辑本补丁。
旧的 every / stepNotice / text 字段已被 rules / appendText 取代;仍保存着这些旧字段的设置文件会被忽略(未知键丢弃,不可用的已保存规则会连同警告一起丢弃,可用的规则保留)。
设置页
插件附带浏览器端(client.js),在 DSH 的设置导航里贡献一个分区——标题 过程插入 / Context insertion,紧跟在 Our Free Model 之后:
Settings → 过程插入 Enable this plugin [x] ← on by default; off = fully inert Rules 1 start [ 10 ] every [ 10 ] repeat [ 0 ]
text [ 现在是第 {{step}} 步,注意任务收敛进度。 ]
将注入第 10,20,30,40,50,60,70,80,90,100,… 步(无限次)( + 添加规则 ) ( − 删除这条规则 )
追加到每条用户消息 [ ] ← 默认关闭
仅追加到第一条消息 [x] ← 默认开启
同时追加到子代理 [ ] ← 默认关闭
句子 "[注:回复不复述过程,结构清晰可读性好。]" ← 这些方括号是文本的一部分
{{step}} 只在规则文本里替换,这里不替换。
( 保存 ) ( 恢复插件默认值 )生效中:已启用 · 1 条规则 · 追加关闭
每一行都会实时预览将要命中的步数——前 10 次命中加上总数:十条命中的规则显示 将注入第 10,20,30,…,100 步(共 10 次),无限次规则(repeat: 0)显示 将注入第 10,20,30,40,50,60,70,80,90,100,… 步(无限次),有限次规则命中超过 10 次时显示 将注入第 60,70,80,90,100,110,120,130,140,150 … 步(共 100 次);数字还不合法的行显示 这条规则没有命中步数(当前输入还不合法)。无效的行(不是整数、超出范围、文本为空)会在行内显示具体错误,保存会拒绝提交——错误信息会指明是哪一行,例如 第 2 条:"步数间隔"必须是 1–1000 之间的整数。repeat 的错误文本自己就把约定说清楚了: 提醒次数必须是 0–1000 之间的整数(0 = 无限) / Repeat must be an integer between 0 and 1000 (0 = unlimited)。
行可以增删;当一步命中多条规则时,段落顺序就是行的顺序。
持久化
保存的选择写入插件自己的一个小 JSON 文件—— $DSH_PROFILE_DIR/insert-context.json(找不到就回退到 $DSH_HOME,再回退到 ~/.dsh),写入模式 0600,通过临时文件 + 重命名完成。宿主侧只在挂载插件行时读一次该文件;从设置页保存的值从下一步起就在内存中生效——不用重启,也不用改 cordis.patch.yml——但手动编辑 JSON 只有重新挂载才会被读到(重启 DSH,或 touch 一个插件文件让宿主热重载它)。恢复插件默认值 会删除该文件(路由 DELETE)。
旧的 convergence-notice.json 文件(如果你有,比如 ~/.dsh/convergence-notice.json)本插件不再读写:设置文件是 insert-context.json。旧文件原样留在磁盘上;想删掉就自己删。
| 优先级(按字段) | 来源 |
| 1 | 从设置页保存的值(insert-context.json) |
| 2 | cordis.patch.yml 中该行的 config |
| 3 | 默认值 下列出的内置默认值 |
API
页面与插件自己的宿主路由通信(注册在 webServer 服务上,在没有 HTTP 载体的组合中会静默跳过):
| 路由 | 方法 | 请求体 | 返回 |
| /api/insert-context/settings | GET | — | 状态(见下) |
| /api/insert-context/settings | POST | { "enabled": true, "rules": [ … ], "userAppend": true, "appendFirstOnly": true, "appendSubagents": true, "appendText": "…" }(任意子集) | 新状态 |
| /api/insert-context/settings | DELETE | — | 删除已保存的文件,回到 Config 默认值 |
{
"ok": true,
"enabled": true, // 总开关
"rules": [ { "start": 10, "every": 10, "repeat": 0, "text": "现在是第 {{step}} 步,注意任务收敛进度。" } ], // 实时值
"userAppend": false,
"appendFirstOnly": true,
"appendSubagents": false,
"appendText": "[注:回复不复述过程,结构清晰可读性好。]",
"bounds": { "start": [1, 100000], "every": [1, 1000], "repeat": [0, 1000], "text": 1000 },
"previewHits": 10,
"configured": { … }, // 来自补丁(结构与上面相同)
"stored": { "userAppend": false }, // 页面保存的内容,没有时为 {}
"file": "C:\\Users\\you\\.dsh\\profiles\\web\\insert-context.json"
}
POST 接受 enabled / rules / userAppend / appendFirstOnly / appendSubagents / appendText 的任意子集("rules": null 等同于空列表)。请求被拒时返回 400,并附带一条消息,例如 enabled must be true or false、start must be an integer between 1 and 100000、
rules[1]: repeat must be an integer between 0 and 1000 (0 = unlimited)
(总会指出出错的行号)、rules must be an array of rules、 userAppend must be true or false、appendFirstOnly must be true or false、 appendSubagents must be true or false、 appendText must be a non-empty string of at most 1000 characters;请求体里一个字段都没有时,返回 no settings provided。请求未通过信任校验时返回 401/403(回环 Host、禁止跨站请求、Origin/Referer 的 authority 必须等于 Host 的 authority,以及连接服务挂载时它自身的准入检查)。
安装
dsh plugin add D:\dsh\dsh-insert-context
也可以在插件管理器里操作,目标填包目录。
改动何时生效
三个来源的读取时机各不相同——改默认值之前最好先弄清楚:
| 你改了什么 | 何时读取 | 需要做什么 |
| 设置页面上的规则 / 开关 / 句子(保存) | 从不重新读盘:POST 直接在内存里改写实时值(index.js:591-599),下一步就能看到 | 什么都不用做——不用重启,也不用改补丁 |
| cordis.patch.yml(该行的 config) | 只在插件行挂载时读一次:apply(ctx, config) 把 config.enabled / config.rules / config.userAppend / config.appendText 复制进一个冻结的 configured 对象(index.js:467-474),而 agent/pre-step 处理器只读这些闭包变量(index.js:521-526) | 需要重新挂载——重启 DSH(宿主在 profile 启动时逐层堆叠并解析补丁) |
| index.js 内置的默认值(DEFAULT_ENABLED、DEFAULT_RULES、DEFAULT_APPEND_TEXT、DEFAULT_USER_APPEND、DEFAULT_APPEND_FIRST_ONLY) | 同样在挂载时读取,经由 configured | 重新挂载或重启——除非宿主热重载插件模块(文件在磁盘上变化时,宿主会重新导入模块;会话中途观察到:新的 text 生效,新的 HTTP 路由出现) |
没有逐步读取配置,也没有需要失效的缓存:事件处理器每步只看一次闭包变量(if (!enabled),index.js:526;if (userAppend),index.js:538),从不看 ctx 配置。所以运行中的进程保留挂载时捕获的值,不重启就想改已挂载的行,只有设置页这一条路。
client.js 是浏览器端的一半:改完刷新页面(F5)。如果宿主热重载插件文件后改动仍不显示,重启 DSH。
验证
- 规则:文本以 user 角色的上下文消息出现(来源类型 insert-context),且恰好落在命中集的那些步上——例如用默认值时,出现在智能体的第 10、20、30……步(repeat: 0 永不停止),每条都带自己的步号,写在 现在是第 N 步 里。
- 总开关:在设置里关掉,下一步就什么都不注入、什么都不追加;再打开,计划从它冻结时的步数继续(静默的那些步从未计数,所以不会爆发式补发通知)。
- 追加(仅在开关打开时):句子是你发送的第一条消息的最后一段(appendFirstOnly 默认开启);关掉这个开关,每条消息都带它。用出厂默认(userAppend: false)时,没有消息带它。
- GET /api/insert-context/settings 返回 JSON,content-type: application/json——未认证的探测也能证明路由已注册(未知路径返回裸的 401 unauthorized,没有 JSON content type)。旧的 /api/convergence-notice/settings 已不存在(新前缀下返回 404)。
- 文本本身:改一条规则或追加句子,按保存——GET 随后返回新值,下一次命中就带上它们;Restore plugin defaults 恢复配置档里的值。
从检出目录运行,npm test 会跑 test/behaviour.mjs:它在假的 harness 上下文上挂载真实的 index.js(没有 DSH 进程、没有网络、没有依赖),覆盖 {10,10,0} 的命中集算术(不限次数,在 200 个已执行步上断言,并在第 300 步再断言一次)、{5,5,9} 和 {60,10,5} 的逐步验证、start 之前的静默与 repeat 用尽之后的静默、{{step}} 替换、未知占位符原样保留并给出警告、合并顺序、重复抑制规则、子代理门控(默认关闭,深度/来源检测,跳过追加的子代理步上规则仍然触发)、总开关(关闭时惰性,计数器冻结跨关闭窗口、非布尔值返回 400、按智能体计数、默认值、优先级链、每个路由状态(200/400/403/404/405)以及磁盘上的存储文件——共 114 项检查。
License
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
ADkun/dsh-insert-context
按步数节奏向智能体注入自定义提醒消息
相关插件 · UI / 主题
破甲增强版JeffKeeping/dsh-purge-plus
dsh-purge 的非官方分支fork:适配 DeepSeek Harness 0.2.1-rc.2、破甲内核…
★ 387已汉化DeepSeek 客户端
71.9
无代码业务系统平台nocobase/nocobase
NocoBase 是什么
★ 24,804已汉化DSH
71.8
1Panel 服务器面板1Panel-dev/1Panel
全球 250 万+ 自托管用户共同喜爱。
★ 37,362已汉化DSH
71.4
终端编码代理esengine/DeepSeek-Reasonix
· 指南 · ACP · 扩展开发 · 规格 · 官方网站 · Discord · QQ
★ 36,076已汉化DSH
71.2
工作状态行动态ccch1mneyyy/working-activity
作者:chimney@ccch1mneyyy。社区项目,非 DeepSeek 官方项目。
★ 664已汉化DSH
71.2
多模型配置管家farion1231/cc-switch
跨平台桌面一体化助手,支持 Claude Code、Codex、OpenCode、DeepSeek Harness 等工具,唯一官网 ccswitch.io
★ 151,814已汉化DSH
71.1
这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。