基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
  • 知识卡片碎片时间过考点
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
    • AI 热点每日 AI 资讯与动向
AI 工作台
简历
旧版
AIHT
内容
精选全部 AI 动态热点榜AI 日报收藏
分类
模型行业编程产品技术观点开源
更多
Agent 接入
返回首页开发者导航
AIHT
精选 / 资讯详情
8.0
热点
AI SCORE
工具产品2026-11-01 11:44

用静态扫描拦截 AI 生成的 Rust 隐患

dev.to · AI#Rust#代码审查#静态分析
Editor brief · 编辑速览

rustgrade 基于 syn 扫描 Rust 代码,无需调用模型、联网或构建项目,可识别非测试代码中的 unwrap、跨 await 持锁及循环内克隆等问题。作者说明演示中的 unwrap 是刻意要求生成的,不能据此判断模型的实际错误率。

文章思维导图
Knowledge map
拖拽缩放
AI deep read

AI 深度解读

编译通过、测试全绿,AI 写出的 Rust 仍可能留下 panic、异步锁和多余拷贝。作者为此做了 rustgrade:在 agent 每次编辑后运行语法扫描,把问题直接送回它的工作流程。

它值得关注的地方,是检查介入的时机:代码刚写完就反馈。作者还做了 27 次 Claude Code 实验,不过结果也提醒我们,一段明确的项目指令,可能已经能解决部分问题。

为什么测试过了,还要在每次编辑后检查

作者让 coding agent 写了几个月 Rust,反复看到几类问题:库代码里使用 .unwrap(),持有 std::sync::Mutex 的锁时执行 .await,以及为了通过借用检查到处加 .clone()。

这些写法未必触发编译错误,测试也未必覆盖对应路径。agent 收到的反馈如果只有「构建成功」,就缺少继续修改的理由。

rustgrade 基于 syn 扫描语法,不调用 LLM、不访问网络,也不需要构建 crate。它目前有 8 条规则,覆盖测试外的 unwrap/expect、跨 .await 持锁、缺少 // SAFETY: 注释的 unsafe、无界通道、公共库 API 中的 anyhow、循环内克隆与分配,以及 &String、&Vec<T> 这类参数。

作者机器上,一个 445 行文件的扫描约耗时 20 ms。这只是单机样例,但解释了它为什么适合接在编辑动作后面。

这张演示图有个必须保留的前提:作者特意要求 agent 使用 unwrap,方便展示拦截过程。不加这条要求时,agent 自己就写出了 Result。它能证明反馈链路跑通,不能证明 agent 总会犯这个错。

它能指出危险写法,但无法理解全部语义

跨 .await 持锁,是文中最有解释价值的例子。下面通过缩小锁守卫的作用域,让数据库等待发生在释放锁之后:

// Flagged
async fn bump(state: &std::sync::Mutex<Counter>, db: &Db) {
    let mut c = state.lock().unwrap();
    c.n += 1;
    db.save(c.n).await; // guard is still alive here
}

// Better
async fn bump(state: &std::sync::Mutex<Counter>, db: &Db) {
    let n = {
        let mut c = state.lock().unwrap();
        c.n += 1;
        c.n
    }; // guard dropped before the await
    db.save(n).await;
}

要看的是第二段的作用域结束位置:执行 db.save(n).await 前,guard 已经释放。第一种写法会让 future 成为 !Send;如果同一线程上的另一个任务尝试获取该锁,还可能死锁。修正版仍保留了 .unwrap(),所以它只演示持锁问题的修复。

另外两类改动也很直接:解析端口时,用 Result<u16, std::num::ParseIntError> 传播错误;函数只需要字符串切片时,把参数从 &String 改为 &str,避免要求调用方必须持有 String。

代价在于,语法扫描缺少类型信息。clone-in-loop 无法判断克隆的是成本较低的 Arc,还是较大的 Vec,也不会检查宏内部。命中规则只能说明需要检查,不能直接判定代码有错。

遇到合理例外,可以在行内写 // rustgrade: allow(unbounded-channel) shutdown signal, at most one message per worker。这里的理由是关闭信号每个 worker 最多发送一次。理由会保留在 JSON 输出里,方便 CI 审查。想了解规则边界,可以运行 rustgrade rules --explain <rule-id>。

27 次实验说明了什么,又没说明什么

作者用 Claude Code 配合 Sonnet 跑了 3 个任务,总计 27 次,每种配置 9 次。统计通过 cargo clippy --lib 完成,只计算库代码中的 unwrap/expect,不把测试代码算进去。

结果是:

  • 不使用 rustgrade,残留数量为 5。
  • 在 CLAUDE.md 加一小段 rustgrade 指令,残留为 0。
  • 只启用 hook,不加该段指令,残留也为 0。

三组每次运行成本分别为 $0.23、$0.21、$0.22,变化很小。原文没有明确这 5 处问题如何分布在任务和运行之间,也没有给出 Sonnet 的具体版本。

这次实验里,项目指令与 hook 的观测结果相同。

hook 的区别在执行方式。作者观察到,hook 组里的 agent 没有主动加载 skill,也没有自行运行扫描器,反馈来自每次编辑后的自动扫描。但长会话里是否更有效、另外七条规则是否同样有效,作者还准备继续测。

作者还扫描了 tokio、serde、regex、syn 等 15 个知名 crate,评分落在 A 到 C 之间。这能提供真实代码中的争议样例,却不能单凭评级证明规则准确。

另一个发现来自 /harden:它用恶意输入探索问题,只修复失败测试证明存在的缺陷。作者称,它在 agent 编写的线程池中找到了死锁等真实 bug,这些实现此前通过了隐藏测试;作者随后单独复现了问题。这个结果值得关注,但原文没有给出可推广的检出率。

我的判断

我赞同把检查提前到编辑环节。对 AI 编程来说,反馈越接近刚发生的改动,越方便 agent 找到原因并修复。

不过,rustgrade 与 Clippy 有明显重叠。unwrap_used、await_holding_lock、undocumented_unsafe_blocks、ptr_arg、borrowed_box 已覆盖其中一些问题。rustgrade 的取舍是用较少的上下文换取更早的反馈;Clippy 需要构建,但能利用更多信息。

因此,普通团队可以先写清项目规则,再评估是否需要 hook。原文并没有证明自动扫描优于项目指令,更没有证明启用全部规则就能提高整体质量。20 ms 也不能直接推到整个工作区。

它采用 MIT 许可证。对于想接入的团队,我更看重误报能否解释、例外能否留痕,以及检查是否打断正常开发。作者主动征集真实 crate 的误报,符合这类启发式工具需要持续校准的特点。

能拿来做什么

  • 如果你用 AI 写 Rust,可以先执行 cargo binstall rustgrade 安装,再用 rustgrade scan 检查现有代码,挑出团队认可的规则。
  • 在 CLAUDE.md 中明确库代码的错误处理要求,先观察 agent 是否遵守;反复出现的问题再接入自动反馈。
  • 在 CI 中使用 rustgrade audit,结合 Clippy 和测试检查,并通过 --fail-on 阈值控制失败条件;需要 GitHub code scanning 时可输出 SARIF。
  • 在 Claude Code、Cursor、Codex CLI、Gemini CLI、Copilot 或 Windsurf 中按支持方式安装 skill 和命令,用 /audit 获取 A 到 F 的评级,用 /harden 探索边界输入;原文明确提供逐次编辑 hook 的是 Claude Code。
Original source

本文由 AI 通读原文后重新编写,观点部分为站内判断,细节以原文为准,来源 dev.to · AI,原文版权归原作者所有。

阅读原文
上一篇
代理停止按钮如何真正终止后台任务
下一篇
让 AI 网页测试同时核对后端结果

资讯速览

dev.to · AI · 2026-11-01 11:44

AI 评分 8.0 / 10

相关标签

#Rust#代码审查#静态分析

继续阅读

  • DeepSeek开源以减少人工打扰为目标的代理原型
  • 代理停止按钮如何真正终止后台任务
  • 让 AI 网页测试同时核对后端结果
  • 千级工具路由为何不能只靠向量检索
  • Gemini 桌面自动化:截图循环的延迟取舍