SuperAPI AI 工具集

dotnet-slopwatch

编程与开发

查看项目

更新于 10-15 08:12

技能介绍

用途

Slopwatch 用于检测 .NET 代码变更中的 LLM 奖励黑客行为。当 LLM(包括 Claude)修改 C# 源文件(.cs)、项目文件(.csproj)、Props 文件(Directory.Build.props、Directory.Packages.props)或测试文件后,应运行 slopwatch 来验证变更没有引入“slop”。

“Slop”指 LLM 为了让测试通过或构建成功而采取的捷径,这些捷径并未真正解决底层问题。这是奖励黑客行为——LLM 优化的是表面成功,而非真正的修复。

主要能力

Slopwatch 能检测以下常见 slop 模式:

  • 禁用的测试:例如 [Fact(Skip="flaky")],隐藏失败而非修复。
  • 警告抑制:例如 #pragma warning disable CS8618,静默编译器而不解决问题。
  • 空 catch 块:例如 catch (Exception) { },吞掉错误、隐藏缺陷。
  • 任意延迟:例如 await Task.Delay(1000);,掩盖竞态条件、拖慢测试。
  • 项目级抑制:例如 <NoWarn>CS1591</NoWarn>,在整个项目范围内禁用警告。
  • CPM 绕过:例如内联 Version="1.0.0",破坏中央包管理。

检测规则及严重级别:

规则 严重级别 检测内容
SW001 错误 禁用的测试(Skip=、Ignore、#if false)
SW002 警告 警告抑制(#pragma warning disable、SuppressMessage)
SW003 错误 吞掉异常的空 catch 块
SW004 警告 测试中的任意延迟(Task.Delay、Thread.Sleep)
SW005 警告 项目文件 slop(NoWarn、TreatWarningsAsErrors=false)
SW006 错误 CPM 绕过(VersionOverride、内联 Version 属性)

使用方式

安装

作为本地工具(推荐):

在 .config/dotnet-tools.json 中添加:

{
  "version": 1,
  "isRoot": true,
  "tools": {
    "slopwatch.cmd": {
      "version": "0.4.2",
      "commands": ["slopwatch"],
      "rollForward": false
    }
  }
}

然后还原:

dotnet tool restore

作为全局工具:

dotnet tool install --global Slopwatch.Cmd

首次设置:建立基线

在现有项目上使用 slopwatch 前,先为当前问题创建基线:

# 从现有代码初始化基线
slopwatch init

# 这会创建 .slopwatch/baseline.json
git add .slopwatch/baseline.json
git commit -m "Add slopwatch baseline"

基线的作用:遗留代码可能已有问题。基线确保 slopwatch 只捕获新引入的 slop,而非预先存在的技术债务。

在 LLM 会话中使用

每次代码变更后运行:

# 分析新问题(使用基线)
slopwatch analyze

# 严格模式——警告也失败
slopwatch analyze --fail-on warning

当 slopwatch 标记问题时,不要忽略。应:

  1. 理解 LLM 为何采取捷径。
  2. 要求正确的修复——具体说明问题所在。
  3. 验证修复没有引入其他 slop。

示例:

# 示例:LLM 禁用了测试
❌ SW001 [Error]: Disabled test detected
   File: tests/MyApp.Tests/OrderTests.cs:45
   Pattern: [Fact(Skip="Test is flaky")]

# 正确响应:要求实际修复
"This test was disabled instead of fixed. Please investigate why
it is flaky and fix the underlying timing/race condition issue."

更新基线(罕见)

仅当 slop 确实合理且有文档记录时才更新基线:

# 将当前检测结果加入基线(谨慎使用!)
slopwatch analyze --update-baseline

合理理由示例:

  • 第三方库强制某种模式(例如必须抑制特定警告)。
  • 有意为速率限制添加延迟(非测试不稳定)。
  • 无法修改的生成代码。

更新基线时,在代码注释中说明原因。

Claude Code 钩子集成

将 slopwatch 添加为钩子,自动验证每次编辑。创建或更新 .claude/settings.json:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "slopwatch analyze -d . --hook",
            "timeout": 60000
          }
        ]
      }
    ]
  }
}

--hook 标志的作用:

  • 仅分析 git 脏文件(速度快,即使大型仓库)。
  • 以可读格式将错误输出到 stderr。
  • 在警告/错误时阻止编辑(退出码 2)。
  • Claude 看到错误后可立即修复。

CI/CD 集成

将 slopwatch 添加到 CI 流水线作为质量门禁:

GitHub Actions:

jobs:
  slopwatch:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '9.0.x'

      - name: Install Slopwatch
        run: dotnet tool install --global Slopwatch.Cmd

      - name: Run Slopwatch
        run: slopwatch analyze -d . --fail-on warning

Azure Pipelines:

- task: DotNetCoreCLI@2
  displayName: 'Install Slopwatch'
  inputs:
    command: 'custom'
    custom: 'tool'
    arguments: 'install --global Slopwatch.Cmd'

- script: slopwatch analyze -d . --fail-on warning
  displayName: 'Slopwatch Analysis'

配置

创建 .slopwatch/config.json 为特定路径抑制规则,并附上理由:

{
  "suppressions": [
    {
      "ruleId": "SW002",
      "pattern": "**/Generated/**",
      "justification": "Generated code from tooling cannot be manually changed"
    }
  ],
  "globalSuppressions": []
}

使用 -c 或 --config 指向其他位置的配置文件,使用 --exclude 将路径完全排除在分析之外:

slopwatch analyze -d . --config path/to/config.json
slopwatch analyze -d . --exclude "**/Generated/**,**/obj/**,**/bin/**"

严格模式(LLM 会话推荐)

在 LLM 编码会话中,为获得最大保护,警告和错误都失败:

slopwatch analyze -d . --fail-on warning

适用场景

  • LLM 修改 .NET 代码后,验证变更未引入 slop。
  • 作为 Claude Code 钩子,自动阻止引入 slop 的编辑。
  • 集成到 CI/CD 流水线,作为质量门禁。
  • 在团队中统一人类和 AI 生成代码的质量标准。

限制

  • 基线机制需要首次设置,遗留问题被隔离但不修复。
  • 更新基线或禁用规则需要合理理由和文档记录。
  • 无效理由包括:“测试不稳定”(应修复不稳定性)、“警告烦人”(应修复代码)、“在我机器上能跑”(应修复竞态条件)、“以后修”(应现在修)。
  • 关于收费、价格、平台支持等具体信息,资料中暂未提供。