dsh-fail-guard
同一工具连续失败达阈值时叫停。不是再试一次,而是推送一条四部分停手指令:试过什么、完整错误原文、初判原因、需要用户做什么。判定读真实工具结果(isError 或 shell 退出码非零),通过 agent.steer 回灌,让 agent 把它当成收到的消息而不是日志。
安装
dsh plugin --profile web add dsh-fail-guard
沙箱测试结果
| 阶段 | 结果 |
|---|---|
| 1 安装 | ✓ |
| 2 列装 | ✓ |
| 3 挂载 | ✓ |
| 4 启动 | — |
四阶段在隔离沙箱里跑:安装(有网)→ 列装 → 挂载 → 启动(后三步断网)。
README
dsh-fail-guard
[English](README.md) | 中文
同一工具连续失败 N 次之后叫停,推一条四段式停手指令(试过什么 / 完整错误原文 / 初判原因 / 需要用户做什么),让它来报告,而不是再试第四种命令写法。
为什么需要外部打断
思考里的复读(「做。做。做。」)一般不是模型退化,是连续试错留下的:同一件事失败、换参数、再失败,没有新信息,同一个「该动手了」被反复重下。
提示词层的规则(「连续失败两次就停手」)在这种状态下无效——那时候模型读的不是提示词,是它自己的 thinking。 所以打断必须来自外部。
实测依据:一份 74 轮的会话里,前 67 轮短句行占比在 7–48% 波动,从连续十几步失败那一刻断崖跳到 81.6%,之后 85.9% / 89.1% / 91.4%。
安装
dsh plugin --profile desktop add dsh-fail-guard
重启一次。cordis.patch.yml 通过 dsh.bundle manifest 自动应用,不用手写 profile 配置。
配置
在 插件 → dsh-fail-guard → 详情 里改。字段标了 .volatile(),保存即生效,不用重启。
键 · 默认 · 含义
threshold · 2 · 连续失败几次后叫停
sameToolOnly · true · 按工具分别计数;关掉则所有工具共用一个计数
stopText · 内置 · 推给模型的那条指令
stopSummary · 内置 · 界面上显示的一行摘要
debug · false · 把事件、计数、叫停写进日志文件
logFile · <插件目录>/fail-guard.log · 日志路径
也可以直接写 cordis.patch.yml:
- id: dsh-fail-guard
config:
threshold: 3
判定
一条 tool/result 满足任一条件就算失败:message.isError === true,或 meta.opsShell.exitCode 存在且非零。两条都要看——退出码为 1 的 shell 命令不会被标 isError,而有些工具级错误不带退出码。计数按「会话 + 工具」分组,任何一次成功都清零。
边界
- 不中止刚失败的那次调用(已经发生了)
- 不判断「算不算真失败」,任何非零退出都算
- 不重置对话,停手指令只是多一条用户消息
- 不是限流器:叫停后继续失败会重新计数,再达阈值会再叫停一次
许可证
MIT
以上内容来自 npm 上的 README,我们只做格式化,不改内容。
版本
npm 上共发布:6,最后更新 2026-11-01