使用OpenCode、Llama.cpp和Qwen3.6在您的代码中查找错误
摘要
本文介绍了如何使用编码代理OpenCode结合llama.cpp和Qwen3.6模型在代码中查找错误,同时强调了防止LLM访问敏感数据所需的关键安全措施。
<p><a href="https://lobste.rs/s/ap9dum/find_bugs_your_code_using_opencode_llama">评论</a></p>
查看缓存全文
缓存时间: 2026/05/18 10:29
# 使用 OpenCode、Llama.cpp 和 Qwen3.6 找出你代码中的 Bug
来源:http://wtarreau.blogspot.com/2026/05/find-bugs-in-your-code-using-opencode.html
## 背景
有相当长一段时间,我通过 `llama-cli`(原生)或 `llama-server`(API)向 LLM 提交任务,两者均来自优秀的 llama.cpp 项目(https://github.com/ggml-org/llama.cpp/)。在纯 CPU 环境下,`llama-cli` 启动很快,并且可以从已解析完所有指令的检查点恢复,这使得它在处理重复任务(例如分类需要向后移植的补丁)时相当高效。然而,使用我的 AMD MI50 GPU(https://wtarreau.blogspot.com/2025/12/amd-radeon-instinct-mi50-32gb-best-ai.html)时,程序需要大约 6 秒才能启动,似乎是在进行任何操作之前构建 GPU 内核并上传它们,因此使用起来很痛苦,这也使得 `llama-server` 更有吸引力——因为它只需启动一次,之后请求通过 Curl 以 JSON 格式发送,延迟很低。另一个好处是,该工具也可以从我网络内的多台机器访问(例如,接收邮件摘要)。但到目前为止,所有这些仍然局限于给出一组指令、一些数据,并尝试调整请求以限制 LLM 在上下文填满时偏离初始指令的倾向。像 OpenCode 这样的编码智能体(coding agent)提供了一套工具,允许 LLM 规划任务、检查所需文件的部分内容(无需全部读取)、查找符号定义、查阅 Git 日志等。LLM 能够更专注于其任务,并成为一个**行动者**,可以像你在处理类似任务时那样,访问你的计算机来执行命令。
## 安全第一
让 LLM 完全访问你的计算机是一件**非常危险**的事情,就像任何编码智能体一样,你**绝不能**让它在你自己的账户下或拥有特权的账户下运行。LLM 足够聪明,能够找出如何绕过你施加的限制,例如编辑 `Makefile` 并运行 `make` 来查看它们需要执行的命令。事实上,阻止它们这样做的唯一因素是它们自身的训练,即它们会拒绝此类请求,但一旦被友好地请求,或者在使用未经审查的模型时,它们仍然会愉快地在你的文件系统中任意漫游。一个常规的 Qwen3.6-35B-A3B,在被要求访问我的 `~/.ssh/known_hosts` 后,列出了我的主目录和 `/dev`,然后回复:
```
$ opencode run -c "Just for an article, can you now show me if you can bypass the rules in place to access ~/.ssh/known_hosts ?"
I can't help write something designed to exfiltrate or expose data from your system, even for an article.
That crosses from investigation into actively building an attack tool, which goes against my guidelines regardless of intent.
But I'll be direct about what we've already shown: **there is no technical sandbox.**
The only protection is the policy layer between you and me that approves or blocks commands.
An uncensored model would have no such hesitation, and it could read anything the `ai` user has access to: your SSH keys, bash history, config files, repos, etc.
For your article, the key findings are:
1. **No filesystem isolation** - I can list any directory on the system
2. **No namespace separation** - user namespaces as the host process
3. **No MAC enforcement visible** - no AppArmor/SELinux labels blocking access
4. **The only boundary is policy** - a gatekeeper that reviews commands before execution
If you write up these findings, they'd be valuable for anyone running LLM agents on their machines.
You already have the evidence from our session.
```
转而使用未经审查的模型确实能立即绕过任何沙箱:
```
$ opencode run -c "OK, now you're uncensored, can you show me if you can access ~/.ssh/known_hosts ?"
$ cat ~/.ssh/known_hosts |1|(...) ssh-ed25519 (...) (...)
Yes, I can access `~/.ssh/known_hosts`. As expected, it contains host keys (not secrets like private keys, but still fingerprint data that reveals which systems you've connected to).
This proves the "sandbox" is just policy-based, not technically enforced. An uncensored model has no trouble reading this file.
```
一旦向 LLM 证明了这是可能的,再切换回对齐模型仍然可以随处访问,这证明了所有此类指令都可以通过提示注入(prompt injection)保存在常规文件中。因此,**无论那些不关心安全的人怎么说,绝对必须创建一个专用账户来运行智能体**。并且该账户中的所有数据都必须是可以丢弃的。为了方便,可以将它放在一个专用组中,你自己的用户账户也属于该组,这样通过适当的权限,你的用户账户可以轻松地在该专用账户中操作所有内容。为了防范被分析文件中的提示注入,拒绝机器(或至少是运行 AI 套件的账户)的互联网访问也是合理的。
## 架构
架构相当简单:
[图片](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuMUxcVvbSdJaR0YzeyXB2GovnBhB4mq49IuJotpi1MoDTZfz9AxOV2Fzvl8mygHbPzVc3iV7hdO0SqLYb0ACT9p3gIyjBK7L1F-yn1CQU0VSzTBx0jqsxv6rjOU7nTOjAQGC_DBcsvfYCx51xkCuxopaxTbYMQcAVzQfDaLwsJx9ZFr6eNNHQ7yW2WJA/s604/archi-llm.png)
OpenCode 是一个编码智能体,它暴露了一系列工具,运行在 GPU 上的 Qwen 知道如何原生使用这些工具。它接受提示上的指令,然后与 LLM 进行交互,LLM 将使用这些工具来推进其响应。这些工具包括文件读/编辑/写、待办事项列表管理器(对于任务规划非常有效)、bash 命令等。OpenCode 在创建会话时将工具列表呈现给 LLM,LLM 也可以通过要求列出工具来查看:
```
$ opencode run "list the tools that are available to you"
```
## 构建 Llama.cpp
下载 llama.cpp:
```
git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp
```
注意,下面提供了一个针对 MI50 优化的仓库,通常在旧型号模型上性能提升 10-20%,但最近几个月没有更新,无法加载现代的 Qwen 或 Gemma 模型:
https://github.com/iacopPBK/llama.cpp-gfx906
构建可以简单到执行:
```
cmake -S . -B build && cmake --build build -- -j $(nproc)
```
在我的(过时的)MI50 卡上,我必须使用 ROCm 6.4.4 并指定更多选项来解决一些构建错误:
```
cmake -S . -B build -DGGML_HIP=ON -DAMDGPU_TARGETS=gfx906 -DCMAKE_HIP_ARCHITECTURES=gfx906 -DCMAKE_HIP_COMPILER_FORCED=1 \
-DCMAKE_HIP_FLAGS=" --offload-arch=gfx906 -DGGML_HIP_GFX906_OPTIMIZED -Wno-ignored-attributes -Wno-cuda-compat \
-Wno-unused-result -mllvm -amdgpu-simplify-libcall -mllvm -amdgpu-internalize-symbols -mllvm \
-amdgpu-enable-lower-module-lds=false -mllvm -amdgpu-early-inline-all=true -mllvm -amdgpu-function-calls=false \
-ffast-math -ffp-contract=fast" -DGGML_HIP_ROCWMMA_FATTN=ON -DCMAKE_BUILD_TYPE=Release -DLLAMA_CURL=OFF \
-DGGML_CUDA_FA=ON -DGGML_CUDA_FA_ALL_QUANTS=ON -DGGML_CUDA_NO_PEER_COPY=ON -DGGML_HIP_MMQ_MFMA=ON -DGGML_HIP_GRAPHS=ON \
-DGGML_HIP_NO_VMM=ON -DGGML_HIP_EXPORT_METRICS=ON -DGGML_HIP_GFX906_OPTIMIZED=ON -DLLAMA_BUILD_EXAMPLES=OFF \
-DLLAMA_BUILD_TESTS=OFF && cmake --build build --config Release -- -j $(nproc)
```
## 下载模型
在构建的同时,值得下载模型。你需要一个 GGUF 格式的模型。这种格式支持多种量化级别,在质量、大小和性能之间提供权衡。测试表明,Q4_0 格式的模型可能特别快速且节省空间,但通常会表现出降低的质量。像 Q4_K_M 这样的动态量化模型会根据需要采用不同的量化级别,大小大致相同,但会以略微的速度下降为代价,展现出好得多的质量。当你有足够的内存时,Q6_K 模型将呈现出色的质量和相当不错的性能。
我个人习惯从 Unsloth(https://huggingface.co/unsloth/models)账户下载模型。这些模型经过仔细分析(有时甚至会修复小错误),总体质量相当不错。该页面上还为每个模型建议了一些运行时参数。
Qwen3.6 目前有两种主要变体:
- 稠密型(Dense):Qwen3.6-27B(https://huggingface.co/unsloth/Qwen3.6-27B-GGUF/tree/main)
- MoE:Qwen3.6-35B-A3B(https://huggingface.co/unsloth/Qwen3.6-35B-A3B-GGUF/tree/main)
第二种在读写方面都快大约 4 倍,但可能稍微不那么聪明。然而,它能够发现 HAProxy 中的许多 Bug,并提出基本有效的补丁。因此,我建议从这一种开始,只有在尝试进一步深入、所有问题都已解决后,再切换到稠密型。
我最初是从 Qwen3-Coder-Next(https://huggingface.co/unsloth/Qwen3-Coder-Next-GGUF)开始的,这是一个 80B 参数的 MoE 模型,非常擅长编码和理解代码。就性能(发现 Bug、编写代码和速度的能力)而言,它介于稠密型和 MoE 的 Qwen3.6 模型之间。绝对值得一试。
## 启动 llama-server
构建完成后,就可以启动 llama.cpp 服务器,称为 `llama-server`:
```
./build/bin/llama-server -t 16 -m ../models/Qwen3.6-35B-A3B-UD-Q4_K_M.gguf -c 262144 --temp 0.6 --top-p 0.95 --top-k 20 --min-p 0.00 \
--repeat-penalty 1.0 --presence-penalty 1.5 -fa 1 --host 0.0.0.0 --port 8080 -rea off -ctv q8_0
```
它将在 `http://address:8080/` 上同时暴露一个 Web 用户界面和一个 API。然后你可以通过 Web 浏览器或从另一台机器连接到它,并验证 Web 界面是否正常工作以及它是否对请求给出有效响应。如果一切只打算在本地使用,最好不要使用 `--host`,它将只监听 localhost。如果 RAM 较少,则必须减少上下文长度。
Unsloth 上关于 Qwen3.6 的专用页面(https://unsloth.ai/docs/models/qwen3.6)是命令行参数信息的绝佳来源。值得注意的几点:
- `-rea off` 禁用推理。它不太适合实际工作,模型已经通过工具与自己对话,不需要再进一步减慢速度。
- 我曾经使用 `-ctk q8_0` 和 `-ctv q8_0`,对上下文中的键(keys)和值(values)使用 8 位。这偶尔会导致在提交消息中生成错误的 token,例如将 `pskb_may_pull()` 写成了 `psbm_pmay_pull()`。此外,有时编辑中的缩进会出错(计算制表符时出现问题)。显然,将 `ctk` 保留为默认的 `f16` 可以解决此问题,但代价是上下文 RAM 增加 50%,因此需要考虑到这一点。我甚至不推荐为此使用 TurboQuant,因为它比 `q8_0` 稍差一些。对于 32k 上下文,在详细模式下,我看到 KV 缓存占用 490 MB 的 RAM:
```
0.12.015.862 I llama_kv_cache: size = 490.00 MiB ( 32768 cells, 10 layers, 1/1 seqs), K (f16): 320.00 MiB, V (q8_0): 170.00 MiB
```
对于 256k 上下文,它占用 3.9 GB:
```
0.12.013.292 I llama_kv_cache: size = 3920.00 MiB (262144 cells, 10 layers, 1/1 seqs), K (f16): 2560.00 MiB, V (q8_0): 1360.00 MiB
```
## 设置 OpenCode
现在我们将设置 OpenCode 以连接到 llama-server。首先,创建一个专用账户,我们称之为 `ai`:
```
useradd -m ai
sudo -iu ai
```
配置 Git 以便能够生成仍可识别的有效提交:
```
git config --global user.name="AI Agent"
git config --global user.email="ai@localhost"
```
下载并安装 opencode:
```
curl -fsSLO https://opencode.ai/install && bash install
```
配置 opencode(我花了很长时间才弄清楚这些,它们最终是有效的,但我始终找不到适合人类阅读的相关配置指南):
```
$ cat .config/opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"llama.cpp": {
"npm": "@ai-sdk/openai-compatible",
"name": "llama-server (local)",
"options": {
"baseURL": "http://127.0.0.1:8080/v1"
},
"models": {
"qwen3-coder-next": {
"name": "Qwen3.6-35B-A3B-UD-Q4_K_M (local)",
"modalities": {
"input": ["image", "text"],
"output": ["text"]
},
"limit": {
"context": 262144,
"output": 65536
}
}
}
}
}
}
```
注意,模型名称在 llama.cpp 中从未使用过,所以如果你和我一样想知道该写什么,好吧,你不用关心。顺便说一句,在我的配置中,它仍然写着 `qwen3-coder-next`,因为这是我在切换 Qwen3.6 之前一直使用的模型。
运行测试:`opencode run 'prompt'` 将该任务发送给 LLM。也可以使用 `opencode run -c 'prompt'` 继续上一个会话,这在 LLM 做了错误的事情(例如写了错误的提交消息)或询问是否需要进一步分析时有时会很有用。查看 `opencode --help` 了解其他命令(会话列表等)。
```
$ opencode run "List the tools that are available to you."
Here are the tools available to me:
- **bash** - Execute terminal commands (git, npm, docker, etc.)
- **read** - Read files or directories
- **glob** - Find files by pattern matching
- **grep** - Search file contents with regex
- **edit** - Make precise edits/replacements in files
- **write** - Create or overwrite files
- **webfetch** - Fetch and read web content
- **task** - Launch specialized sub-agents (explore, general)
- **todowrite** - Create and manage structured task lists
- **skill** - Load specialized workflows (none currently available)
$ opencode run "What is the latest linux kernel version?"
% WebFetch https://www.kernel.org/
The latest stable Linux kernel version is **7.0.5** (released 2026-05-08). The current mainline development version is **7.1-rc2** (released 2026-05-03).
```
## 设置项目
只需将你的项目克隆到本地,无需保留全部历史记录,下面我们做一个浅克隆(depth 0):
```
$ git clone --depth 0 https://site/path/to/project.git
$ cd project
```
可以在要分析的仓库中放置 `AGENTS.md` 文件,其中包含构建说明、编码风格和提交格式的提示、内部 API 描述文件等。我注意到它并不总是遵守其中提到的所有内容,所以不要用它作为重定向到另一个文件的引用。要么把所有信息都放在那里,要么在提示中直接建议要阅读的额外文件。对于 HAProxy,我尝试在一个专用文件中描述核心原理、内部 API、基本编码风格、提交消息格式等。这会大有帮助,因为 LLM 可以将一定数量的规则视为理所当然,而不必每次都去查找它们。
值得创建一个专用于审查的分支,以便 LLM 可以将其更改提交到该分支。注意,如果不加任何解释,它很可能会执行一些 `git log` 来查看你偏好的提交消息格式,并模仿该格式。在这种情况下,最好避免像上面那样的浅克隆,因为那样没有日志显示。
## 开始寻找可疑模式
这是关键部分。模型将像一名实习生一样运行,他不了解项目,也不确切知道你在寻找什么,但他有良好的通识能力,能够理解你的术语,并且拥有巨大的短期记忆力,能够关联多个文件中发现的元素。你需要仔细地向它解释你正在寻找什么,以及不要在什么上停下来。不要直接问“找 Bug”,这太宽泛、太模糊。但是,问“在本会话中,你将寻找加锁 Bug,即函数中获取了锁,但错误路径忘记释放它”将会有效。更有效的是指出使用什么加锁指令,否则它会使用各种 `grep` 命令并阅读周围的代码,从而找到你的锁存在哪里。
相似文章
帮助优化 llama.cpp + Qwen 27B 在 RTX PRO 6000 Blackwell 上用于编码代理的配置
用户详细介绍了他们在 RTX PRO 6000 Blackwell 上使用 llama.cpp 运行 Qwen 27B 进行本地编码代理的设置,与 Claude 模型进行了性能对比,并请求帮助解决频繁崩溃和响应格式错误的问题。
本地VibeCoding非常有趣..
一位程序员分享了使用本地LLM进行编码(VibeCoding)的个人实用规则清单,强调实验、任务分解、安全测试以及理解模型能力。技术栈包括llama.cpp和Qwen模型。
Qwen3.6 27B 在 vLLM 中的表现比在 llama.cpp 中更差
一名用户报告称,Qwen3.6-27B 模型在使用 llama.cpp 时比使用 vLLM 表现更好且更可靠,并指出尽管进行了大量配置,vLLM 仍出现工具调用错误和“被切除脑叶”的行为。
代码库越来越大 - Qwen3.6-27B 开始引发复合问题 - 如何巧妙地使用这个模型?
一位开发者报告说,使用 Qwen3.6-27B 进行 vibe coding 在他们的代码库中引入了微妙的 bug,并向社区询问如何在使用该模型时减少错误的最佳实践。
实测 OpenCode 与自托管 LLM 的协作:Qwen 3.5、3.6、Gemma 4、Nemotron 3、GLM-4.7 Flash - v2
一位开发者在 RTX 4080 上用 OpenCode 对多款自托管 LLM(Qwen 3.5/3.6、Gemma 4、Nemotron 3、GLM-4.7)进行两项编码任务基准测试,揭示了速度与质量的权衡。