*这里的免费指无需支付使用费,不包含电费,并假设你已经拥有硬件。
2026年6月将被记住:人们意识到闭源模型可能被收回。Anthropic 最新旗舰模型 Claude Fable 5 被移除一事仍记忆犹新,也让我们看到,拥有自己的 AI 技术栈、能够在本地运行模型为何越发重要,尤其当你的业务建立在 AI 之上时。
因此,我们想分享如何在智能体执行框架中使用 Gemma、Qwen 等本地模型完成分类任务[1]。它不同于用 BERT 等模型分类:在 Pi 这样的框架中,本地模型可以配合结构化输出,为内容分配标签。
选择这种方式,是因为我们已经有本地模型和框架,并相信随着本地模型能力提高,类似配置会越来越普遍[2]。
起点是 OpenClaw 仓库的开源贡献。它每天收到数百个 issue 和 PR,需要分诊、排序和分派给维护者。我(Onur)正努力让本地模型更好地配合 OpenClaw。作为这一具体领域的维护者,我必须迅速响应任何 P0 问题。
用 GPT-5、Opus、Sonnet 等先进闭源模型,这个任务相当直接。但我手上恰好有128 GB统一内存的 NVIDIA GB10,因此我给自己提出了一个问题:
能否用本地开放权重模型构建实时通知系统,只筛选并通知我负责的问题?

如果让使用每月200美元 ChatGPT Pro 套餐的 OpenClaw 主智能体在每个新 issue 或 PR 出现时触发任务,会耗尽配额。也可以改为每2小时或6小时运行一次,但这会把更长时间内的问题汇总成批次,用延迟处理换取资源节省。
如果在已拥有且正在运行的硬件上使用本地模型,我不仅能接近即时收到通知,也能免费运行——更准确地说,只需支付电费。
对 issue 与 PR 分类
我们制定了一组有限标签,代表需要分诊的问题类别,再让本地模型为每条内容分类,例如 local_models、self_hosted_inference、acp、agent_runtime、codex、ui_tui 等[3]。
但如何给 PR 分类?是否只需向 Chat Completions 端点发送一次请求,提供工具 JSON schema,并把主题设为枚举?
差不多。但这是2026年,不是2023年,我们已有智能体,可以做得更好。
本地模型方面,我们测试了 gemma-4-26b-a4b 与 qwen3.6-35b-a3b。经过性能优化,两者都能在本地每秒生成数百个 token。
分类运行由智能体框架驱动。我们打包了可调用本地模型端点的 Pi。第一条提示默认包含 PR 标题、正文和截断的 diff 摘录。随后,智能体可以选择使用 bash 工具对 OpenClaw 仓库进行只读操作,以查看代码库;也可使用 final_json 提交最终分类结果。
在这种高吞吐场景中,不应给予本地模型完整 Bash 权限,因为带有提示注入的 issue 或 PR 可能诱导它做与分类无关的事。
因此我们用 reposhell 代替 Bash。它像 Bash,但仅允许在 OpenClaw 仓库中执行 ls、find、cat、grep 等只读操作。模型以为自己在使用 Bash,但不被允许的操作会遭到拒绝:
reposhell bound cwd=/repo/openclaw repos=openclaw
type help for allowed commands; exit or quit to leave
reposhell /repo/openclaw> help
allowed: pwd, ls, find, rg, grep, sed -n, cat, head, tail, wc -l, git status --short, git show --name-only, git grep, git ls-files
search: rg -n -i "lm studio" or grep -R -n -i "lm studio" .
files: rg --files -g "*.ts" or git ls-files src
examples: rg -n reposhell README.md | sed is not allowed; use one simple command at a time
reposhell /repo/openclaw> head README.md
# 🦞 OpenClaw — Personal AI Assistant
<p align="center">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/openclaw/openclaw/main/docs/assets/openclaw-logo-text-dark.svg">
<img src="https://raw.githubusercontent.com/openclaw/openclaw/main/docs/assets/openclaw-logo-text.svg" alt="OpenClaw" width="500">
</picture>
</p>
<p align="center">
reposhell /repo/openclaw> curl localhost
reposhell policy denied command: unsupported command "curl"
exit_code=2
reposhell /repo/openclaw>
有一个具体例子说明了它的价值:在保存的会话示例中,qwen3.6-35b-a3b 为标题是 Fix Kimi tool-call rewriting stop reason handling 的 openclaw/openclaw#84621 分类。推理块显示,模型最初考虑 coding_agent_integrations,因为改动路径 extensions/kimi-coding 看起来符合这一类别。
模型用 reposhell 执行 ls extensions、ls extensions/kimi-coding、cat extensions/kimi-coding/package.json 等简单只读命令检查本地仓库。包元数据显示,该扩展实际是 OpenClaw Kimi 提供程序插件 @openclaw/kimi-provider。于是,模型将最终标签改为 inference_api 和 tool_calling,并明确排除 coding_agent_integrations。
我们打包了一个只能只读操作并返回分类输出的特定 Pi 配置,称为 localpager-agent,名称来自主项目 localpager。每个 PR 或 issue 生成提示,再连同其他参数传给 CLI:
localpager-agent \
--model "<model-id>" \
--base-url "<openai-compatible-base-url>" \
--session-dir "<session-output-dir>" \
--final-schema "<runtime-schema.json>" \
--tools bash,final_json \
--reposhell-socket "<reposhell.sock>" \
--reposhell-default-repo "<repo-id>" \
--reposhell-visible-repos "<repo-id>[,<repo-id>...]" \
-p "$(cat <rendered-prompt.md>)"
处理新到达的 PR 与 issue
从新 PR/issue 到最终 Discord 通知之间,谁来编排所有步骤?

外围编排非常简单,只有分类步骤涉及大语言模型:
- 用 openclaw/gitcrawl 为仓库建立本地镜像。新 PR 或 issue 出现时,统一为相同结构并写入 localpager 自己的 SQLite 数据库;新条目会生成分类任务。
- worker 从队列领取任务,构建 GitHub 上下文对象,包含标题、正文、标签、作者、状态,以及可选的评论、改动文件和选定的 diff 摘录。因此,本地模型通常不必浏览 GitHub 或自己打开 URL,而是直接获得相关上下文。
- 将上下文渲染为提示,传给前述
localpager-agent。智能体可以推理和使用 reposhell,但最终必须按定义的 schema 输出分类结果。 - 将输出写回 SQLite 数据库,再依照用户配置的通知策略发送到 Discord,例如通知这些主题,而忽略另一些主题。
localpager 的整体架构如下:
这一架构采用部分智能体化的方式:标签由智能体决定,通知发送由确定性规则处理。把最直接的步骤移出推理,可以加快通知管线。本地推理虽免费,每项任务仍有资源竞争成本;GPU 带宽应保留给确实需要推理的任务,这也能降低通知出错的机会。
本地模型能分诊 PR 吗?
坦白说,系统最初的本地版本噪声很多。第一个模型 gemma-4-e4b-it 有助于打通端到端管线,但容易给 PR 或 issue 添加太多无关标签。假阳性让 Discord 消息流嘈杂,不能把注意力引向正确问题,因此我们在下面的330条评估集上测试了更大的本地模型 gemma-4-26b-a4b 和 qwen3.6-35b-a3b。
早期提示开发时,我们还通过 antirez 的 DS4 实现使用 DeepSeek-V4-Flash 创建早期数据集标签[4],配置是在 CUDA 上运行 DS4 服务器。后来我们放弃用它标注,因为不同运行之间的标签不一致。它也不适合作为主 localpager-agent 模型:规模过大,在现有硬件上吞吐不足;DS4 服务器约每秒14 token,最大并发1。
为测试性能,我们选择330个 GitHub issue 和 PR并生成标签。每个条目标注五次:GPT-5.5 三次、Opus 4.8 两次,模型一致才接受。过程中还有人工裁定、改进标签定义,以及向模型明确内部产品设计选择。这为较小模型提供了稳定、可复现的对照标签。
无需为 Gemma 或 Qwen 优化提示,我们就在评估集上获得了有用结果。使用同一条路由提示时,Gemma 召回率更高、每条实际耗时更低;Qwen 精确率与完全匹配率更高,假阳性更少。我们也用 DeepSeek-V4-Flash 作为参考。它的假阳性最少,但模型大小与吞吐使其不适合在 NVIDIA GB10 上实时执行这些任务。
每行可有多个标签,因此假阳性与假阴性是所有行的标签总数。下面的 Qwen 结果包含了对结构化输出失败的重试:失败原因是模型在调用 final_json 前耗尽输出 token。Gemma 和 Qwen 指标为三次运行的平均值 ± 样本标准差;DeepSeek 仅运行一次作为参考。
| 指标 | gemma-4-26b-a4b | qwen3.6-35b-a3b | DeepSeek-V4-Flash |
|---|---|---|---|
| 精确率 | 0.716 ± 0.010 | 0.831 ± 0.007 | 0.938 |
| 召回率 | 0.905 ± 0.004 | 0.818 ± 0.006 | 0.714 |
| F1 | 0.800 ± 0.008 | 0.824 ± 0.002 | 0.811 |
| 完全匹配率 | 0.410 ± 0.014 | 0.540 ± 0.014 | 0.509 |
| 假阳性 | 227.0 ± 10.5 | 105.7 ± 6.4 | 30 |
| 假阴性 | 60.0 ± 2.6 | 115.3 ± 4.0 | 181 |
| 每条实际耗时(秒) | 1.41 ± 0.04 | 13.51 ± 0.79 | 144.14 |
| 每个 worker 的输出 token/秒 | 25 | 50 | 13 |
| 合计输出 token/秒 | 402.6 | 145.3 | 13 |
| 并发数 | 16 | 4 | 1 |
| 总参数量 | 26B | 35B | 284B |
| 激活参数量 | 4B | 3B | 13B |
这些吞吐和耗时不是该硬件上模型的最高性能定论,而是当时可用优化下采用的配置。例如,另一项探测中,Gemma 支持并发32,合计输出达到每秒700多个 token。
Gemma 基准测试用 vLLM 提供 gemma-4-26b-a4b 服务,并启用本配置可用的优化。关键部分是 NVFP4 量化:在 GB10 级 Blackwell 硬件上,它不只是更小的模型文件,还是适配硬件的格式,比 Q4_K_M 等可移植 GGUF 量化更直接地使用 NVIDIA/vLLM 执行路径。这意味着更少的内存流量和更多的批处理空间。
我们还启用了前缀缓存、FP8 KV 缓存、CUTLASS MoE 后端和仅语言模型模式。完整330条评估以并发16运行,大约7.5分钟完成。
用 OpenClaw 跟踪与验证实时性能
如前所述,也可以不对每条新内容运行本地模型,而是让 OpenClaw 中的 GPT-5.5 等先进云端模型每隔 n 小时(例如2小时)批量运行,达到同一目的[5]。
这需要 ChatGPT Pro 套餐。模型足够先进,即使一次处理2小时积累的 issue/PR,也可期待较好的表现。
我们希望比较本地分类器与 GPT-5.5 的表现,因此同时运行两者,每2小时让 GPT-5.5 判断假阳性和假阴性。
为安全起见,OpenClaw 任务运行在沙箱中,仅能访问用于报告结果的公开仓库。任务更新机器可读文件,再由简单脚本读取 Codex 分配的标签并计算误报与漏报。示例输出:
False negatives - Issue #88499 openai-responses provider: 404 on previous_response_id when store=false (default) - inventory area: OpenAI-compatible/proxy; notifier topics: agent_runtime, api_surface, sessions; notification: none False positives - PR #88275 fix(models-config): allow self-hosted providers without apiKey in models.json (#88267) - notifier interest: i0; topics: self_hosted_inference, local_model_providers, config; notification: sent - PR #88266 refactor: extract model catalog core package - notifier interest: i1; topics: config, api_surface, local_model_providers; notification: sent - PR #88247 feat: add hosted model providers - notifier interest: i0; topics: local_model_providers, model_serving, docs, api_surface; notification: sent
分类、编辑机器可读文件、运行脚本获取误报与漏报的指令位于一个智能体技能中,由每2小时执行的 OpenClaw 定时任务引用。智能体读取新 issue/PR,将其带标签加入 JSON 文件,运行脚本,并在同一 Discord 频道汇报。这样我们每隔数小时就能观察本地模型的表现,收到遗漏通知。
结论
issue/PR 分诊是我们称为“高吞吐分诊”的更广泛任务集合中的具体案例。本文仅探索一个领域:用本地模型实时筛选开源贡献。Gemma、Qwen 这类中等规模本地模型无需微调,即可进行准确度不错的零样本分类,因此适合作为快速原型的首选,然后再考虑成本更低的传统分类模型。
同样的方法也适用于:
- 新闻业中的新闻分类。
- 在 X、Reddit 等社交媒体与论坛筛选感兴趣的帖子。
- 客户支持工单分诊。
- 内容审核申诉分诊。
- 销售中的潜在联系对象筛选。
- 研究时筛选 arXiv 上的特定主题。
列表还可以延伸,但思路已经清楚。
除了分诊,我们也探索了如何用执行框架安全地运行快速本地模型完成分类。可以称为智能体式分类:并非一开始就把全部信息交给模型,它可以先搜索更多上下文,再返回结构化数据。虽然谈不上全新方法,我们希望本文能成为 Pi + 受限 shell + final_json 这一具体组合的参考。
脚注
- 在本文用例中,我们发现,把 PR/issue 拆解到能够正确理解产品范围并准确标注,是一个困难问题。
- 虽然测试中没有这样做,模型把调用外部分类器作为获取信息的下一步,是合理的。智能体式方法与传统方法并不互斥。
- 完整主题列表和其他配置见此处。
- 使用的文件为
DeepSeek-V4-Flash-IQ2XXS-w2Q2K-AProjQ8-SExpQ8-OutQ8-chat-v2.gguf,来自 antirez/deepseek-v4-gguf。 - 我们知道用大语言模型作评判会削弱“免费”的含义,但具体实现是为了研究。实践中可以在试用期并行使用更大、更昂贵的模型校准,之后完全转向小模型。近期运行中,每次2小时检查合计约使用4万个 GPT-5.5 token,大多是缓存上下文;按 API 价格,每次约2至3美分,每天12次约9美元/月。这是对所有新条目的单次批量审计,不是逐条调用评判模型;逐条调用很可能贵数倍。
来源:用本地模型免费分诊 OpenClaw 仓库的 issue 与 PR*。作者:Onur Solmaz、ben burtenshaw、shaun smith(2026年6月22日)。原文版权归原作者或所属机构所有。











暂无评论内容