dsh-tool-normalizer
Đã xác minhdsh-tool-normalizer · v0.3.3 · MIT · Giao diện web
Auto-healing, argument normalization, Code-Mode bridging and execution diagnostics for DeepSeek Harness
Cài đặt
dsh plugin add dsh-tool-normalizer Xác nhận layer đã áp bằng dsh --profile default --dump-config — xem hướng dẫn cài plugin.
Mã nguồn
Thẻ
Tác giả
Readme
dsh-tool-normalizer (中文文档)
DeepSeek Harness (DSH) 工具调用自愈、参数自动归一化、Code-Mode 透明桥接与可视化诊断面板插件。
English Documentation (README.md)
📖 前因后果与数据驱动背景
在 DeepSeek Harness 的自主 Agent 循环中,工具调用的鲁棒性直接决定了任务的成功率与流畅度。通过对 111 个真实持久化会话(共包含 11,176 次工具调用)进行全量统计与诊断,发现共有 543 次 Tool Call 错误(整体错误率 4.86%,影响了 53.2% 的会话)。
深层归因分析揭示了 四大结构性错误根因:
INVALID_ARGS参数契约错位 (13.6%, 74 次):- 模型在调用
run_code时常套用 bash 惯性,传递{"command": "..."}而非{"description": "...", "code": "..."}。 - 模型常漏传
description必填字段。
- 模型在调用
UNKNOWN_TOOLCode-Mode 认知惯性冲突 (12.3%, 67 次):- 当配置启用 Code-Mode 时,系统仅向模型暴露
run_code单一入口。但模型常习惯性直接发起read、bash、write、grep等独立工具调用,导致直接报UNKNOWN_TOOL失败。
- 当配置启用 Code-Mode 时,系统仅向模型暴露
CODE_RUN_FAILED沙箱内执行异常 (46.8%, 254 次):- 模型在 JS 模板字符串中嵌套生成复杂多行 shell 脚本或 Python 脚本时,因反引号未转义或换行破裂导致 JS 语法解析失败。
- 文件系统安全策略门禁 (5.5%, 30 次):
- 未遵循先读后改策略(
FS_NOT_OBSERVED)、编辑器view_range行号超界、或者使用了相对路径。
- 未遵循先读后改策略(
🎯 dsh-tool-normalizer 想解决的问题
本插件基于 Cordis 的 tools/execute 瀑布流扩展点构建,作为低开销、确定性的前置中间件对模型生成的工具调用进行自动纠偏与自愈,并配套提供 Web UI 诊断与统计看板:
模型发起的 Tool Call
│
▼
┌────────────────────────────────────────────────────────┐
│ dsh-tool-normalizer 插件 │
│ │
│ 1. run_code 自动归一化 (command ➔ code, 补全描述) │
│ 2. 直接调用安全恢复 (保留上下文的嵌套派发) │
│ 3. 编辑器路径与范围修正 (相对路径、倒置/越界范围) │
│ 4. 动态精简提示词注入 (按需挂载, 零冗余 Token) │
│ 5. 实时运行遥测与统计分析追踪器 (Tracker) │
└────────────────────────────────────────────────────────┘
│
▼
尽量恢复可修复错误
│
▼
[Web UI] 设置面板 ➔ 工具自愈与统计 (实时图表与日志)
核心功能
- 🛠️
run_code参数智能自愈:- 自动识别并转换
{"command": "git status"}/{"cmd": "..."}为标准的run_codeJavaScript 调用。 - 自动补全缺失或为空的
description字段。 - 自动剥离误包含的 Markdown 代码块标记(如
typescript ...)。 - 仅当内层目标工具的当前 schema 将
description标记为必填时才补全;read、glob、grep等开放参数工具保持原始参数不变。
- 自动识别并转换
- 🌉 Code-Mode 透明工具桥接:
- 当
UNKNOWN_TOOL已经进入tools/execute且目标工具在当前 Agent 作用域中可见时,插件通过宿主的tools.execute()重新以嵌套调用派发,保留 Agent、会话、取消信号、上下文和终结状态。 - 适用范围说明:在 PTC(
code)折叠模式下,宿主可能在任何监听器之前拒绝直调;这条路径插件无法仅靠自身拦截。插件也不会直接调用工具定义的execute()方法。
- 当
- 📐 编辑器参数与边界纠偏:
- 自动将相对路径转换为当前会话工作目录下的绝对路径。
- 先做结构性范围修正;当
str_replace_editor返回包含文件行数的越界错误时,按真实行数嵌套重试,并保留-1到文件末尾的语义。
- 🩹 文件观察后重试:
- 仅当编辑/写入返回
FS_NOT_OBSERVED时读取目标文件,再通过宿主标准派发重试一次;正常调用不会预先增加一次读取。
- 仅当编辑/写入返回
- 📊 可视化运行与诊断面板 (Web UI):
- 无缝挂载至 DSH 的 设置面板(
settings.section)。 - 实时呈现核心 KPI 指标:拦截总数、成功纠正数、纠正尝试成功率 %、未恢复错误数。
- 工具维度与问题类别的可视化分布进度条。
- 支持按状态(全部 / 仅看纠偏 / 仅看失败)筛选的实时运行流水明细表,直观对比纠偏前后的输入差异。
- 无缝挂载至 DSH 的 设置面板(
🧭 UI 页面放置位置与设计考量
挂载位置:DeepSeek Harness 设置导航页(settings.section,ID 为 tool-normalizer,序号 25)。
选址考量:
- 符合 DSH 官方架构规范:在 DeepSeek Harness 的 Web UI 规范中,所有系统监控、用量统计(如
dsh-usage-atlas)、模型配置与插件管理均统一收纳于设置抽屉(Settings Panel)内。 - 保持主对话界面纯净:将诊断与统计收纳于设置页,既不干扰 Agent 主对话流与工作区画布,又可通过侧边栏左下角齿轮图标一键直达。
- 运维与排障一体化:开发者可在同一设置视窗内完成模型切换、插件开关以及工具自愈率观察。
🚀 安装与快速上手
在 DeepSeek Harness 中,插件是按 组合 Profile(如 web, headless, tui 等)进行隔离与依赖管理的。
第一步:安装插件至目标 Profile
使用全局 dsh 命令(或在源码仓库下使用 pnpm dsh):
# 1. 安装至 Web UI 模式(含设置面板可视化看板)
dsh plugin --profile web add dsh-tool-normalizer
# (若在 deepseek-harness 源码仓库下开发调试)
pnpm dsh plugin --profile web add dsh-tool-normalizer
# 2. 安装至 Headless 自动化模式
dsh plugin --profile headless add dsh-tool-normalizer
# 3. 安装至 TUI 终端交互模式
dsh plugin --profile tui add dsh-tool-normalizer
本地开发模式链接(可选)
如果你正在本地修改或测试插件源码:
pnpm dsh plugin --profile web add ./plugins/dsh-tool-normalizer
第二步:启动并查看效果
# 启动 Web 界面
dsh web
# (或源码启动)
pnpm dsh web
打开浏览器进入 Harness 界面,点击左下角 设置 (⚙️) ➔ 「工具自愈与统计」,即可实时查看所有工具调用拦截流水、纠偏统计与成功率图表!
⚙️ 配置项说明
你可以在工作区的 cordis.patch.yml 中自定义插件的运行参数:
- insert:
- id: tool-normalizer
name: dsh-tool-normalizer
config:
autoWrapRunCode: true
autoBridgeDirectTools: true
autoObserveFiles: true
autoClampRanges: true
injectPrompt: true
estimatedRetryTokenCost: 8000
persistPassthrough: false
| 配置字段 | 类型 | 默认值 | 作用说明 |
|---|---|---|---|
autoWrapRunCode |
boolean |
true |
自动转换 command 属性为 code,自动补全描述,剥离 Markdown 标记 |
autoBridgeDirectTools |
boolean |
true |
仅对已进入 tools/execute 的 UNKNOWN_TOOL 结果尝试安全嵌套恢复;宿主提前拒绝的调用插件无法拦截 |
autoObserveFiles |
boolean |
true |
仅在收到 FS_NOT_OBSERVED 后读取目标并重试一次编辑/写入 |
autoClampRanges |
boolean |
true |
修正编辑器范围并将相对路径转为当前会话目录下的绝对路径 |
injectPrompt |
boolean |
true |
动态向 systemPrompt 注册极简工具最佳实践提示词(静态文本,不影响前缀缓存命中) |
estimatedRetryTokenCost |
number |
8000 |
单次避免失败重试的估算 input token 成本;驱动看板的"预估节省Token"指标(明确标注为估算值) |
persistPassthrough |
boolean |
false |
是否将未修改且成功的正常放行调用逐条写入 JSONL;默认仅保留聚合计数,失败和自愈事件仍保留明细 |
成功率只计算实际发生修复/恢复尝试的调用:healedSuccess / (healedSuccess + healedFailed)。正常成功放行不会进入详细 JSONL,以避免日志被高频健康调用淹没;其计数写入同目录的 tool-normalizer-summary.json。
流水明细对长参数只保留首尾预览,并额外显示实际修改的字段或恢复路径,避免新增字段位于截断区域时看起来没有变化。
📦 发版与发布指南 (Release & Publishing)
方式一:基于 GitHub Actions 自动化发版(推荐)
- 在 GitHub 仓库设置中配置 npm Token:
- 进入 GitHub 仓库 Settings ➔ Secrets and variables ➔ Actions ➔ New repository secret。
- Secret 名称:
NPM_TOKEN,值为开启了 2FA Bypass 权限的 npm Token。
- 升级版本号并推送 Tag:
# 升级小版本(patch / minor / major) npm version patch # 推送分支与 Tags 到 GitHub git push origin main --tags - 在 GitHub 页面基于新推送的 Tag 发布 Release,GitHub Actions 流程(
.github/workflows/publish.yml)将自动运行全套测试、打包并将新版本发布至 npm 官方镜像源!
方式二:本地手动发布到 npm
# 1. 执行全量测试与打包编译检查
npm run check
# 2. 登录 npm 账号(若未登录)
npm login
# 3. 执行发布
npm publish --access public
🧪 单元测试与验证
# 运行单元测试
pnpm test
# 运行测试并打包产物
pnpm run check
📄 开源许可
MIT © merenguesL