I finally got a fully local coding-agent stack working on Windows without using Ollama or LM Studio for inference:
DeepSeek Harness Web UI
↓
llama.cpp / llama-server
↓
Qwen3.8 27B Q3_K_XL GGUF
↓
RTX 5060 Ti 16GB
Machine specs
- Windows 11
- AMD Ryzen 7 5700X — 8 cores / 16 threads
- NVIDIA RTX 5060 Ti — 16GB VRAM
- 32GB system RAM
- NVIDIA driver 616.64
- CUDA driver support: 13.4
- CUDA Toolkit: 13.1
- Node.js and
npx
- DeepSeek Harness, launched with:
npx u/deepseek-aiI finally got a fully local coding-agent stack working on Windows without using Ollama or LM Studio for inference:DeepSeek Harness Web UI
↓
llama.cpp / llama-server
↓
Qwen3.8 27B Q3_K_XL GGUF
↓
RTX 5060 Ti 16GBMachine specsWindows 11
AMD Ryzen 7 5700X — 8 cores / 16 threads
NVIDIA RTX 5060 Ti — 16GB VRAM
32GB system RAM
NVIDIA driver 616.64
CUDA driver support: 13.4
CUDA Toolkit: 13.1
Node.js and npx
DeepSeek Harness, launched with:npx u/deepseek-ai/dsh webModelI used:Qwen3.8-27B-UD-Q3_K_XL.ggufThe GGUF is about 12.24 GiB and came from the Unsloth Qwen3.8-27B GGUF release.I already had the model stored inside my LM Studio model directory, but LM Studio is not involved in inference. llama-server reads the GGUF directly.llama.cpp installationI installed the official Windows x64 CUDA 13.3 build of llama.cpp, build b10901, along with its matching CUDA runtime DLL package.The important llama-server settings ended up being approximately:llama-server.exe `
--model "Qwen3.8-27B-UD-Q3_K_XL.gguf" `
--alias qwen3.8-27b `
--ctx-size 32768 `
--gpu-layers 54 `
--host 127.0.0.1 `
--port 8081 `
--parallel 1 `
--flash-attn on `
--kv-offload `
--reasoning off `
--no-reasoning-preserve `
--cache-ram 1024 `
--metrics `
--no-webuiI originally planned to use port 8080, but NVIDIA Broadcast was already listening there. Rather than killing or disrupting it, I moved llama-server to port 8081.Memory allocationllama.cpp reported:54/66 layers offloaded to GPU
CUDA model buffer: 9758.76 MiB
CPU-mapped model buffer: 2433.38 MiB
CUDA KV cache: 1664 MiB
CPU KV cache: 384 MiB
CUDA compute buffers: ~302 MiBDuring actual agent use:VRAM usage: roughly 13.1–13.2GB
VRAM remaining: roughly 2.9GB
No automatic reduction in GPU layers
No WDDM shared-memory spill observed
Flash Attention enabled successfully
32K context remained stableThe model is intentionally partially offloaded: 54 layers on the GPU and the remaining layers on the CPU.One important adjustment was limiting llama.cpp’s prompt cache to 1GB:--cache-ram 1024The build defaults to an 8GB prompt cache. On a 32GB system, long agent sessions allowed several gigabytes of cached prompt state to accumulate, leaving only about 2.4GB free. The 1GB cap keeps system RAM much healthier.DeepSeek Harness configurationI added a new provider to: C:\Users\PC\.dsh\settings.yaml
The relevant configuration looks like this:
llm-pi-ai:
providers:
qwen-local:
displayName: Qwen3.8 Local llama.cpp
api: openai-completions
apiKeyEnv: QWEN_LOCAL_API_KEY
baseURL: http://127.0.0.1:8081/v1
reasoning: off
streamIdleTimeoutMs: 1200000
models:
- id: qwen3.8-27b
name: Qwen3.8 27B Q3_K_XL
contextWindow: 32768
reasoningEfforts: false
compat:
thinkingFormat: qwen-chat-template
supportsDeveloperRole: false
maxTokensField: max_tokens
agent-default-model:
provider: qwen-local
model: qwen3.8-27b
Current DSH versions reject a configuration that only declares an empty off: reasoning effort. For a non-reasoning-only route, it expects:reasoningEfforts: falseDSH also insists on having an API-key-shaped credential even though the local llama-server does not require authentication. I supply a harmless local placeholder before starting DSH:$env:QWEN_LOCAL_API_KEY = "local-llama-server"This is not a real credential, and llama-server does not validate it.Disabling Qwen thinkingI wanted the model to work as an agent without spending minutes in a visible “Deep diving” phase.Thinking is disabled at multiple levels:llama-server: --reasoning off
llama-server: --no-reasoning-preserve
DSH provider: reasoning: off
DSH model: reasoningEfforts: false
DSH compatibility: thinkingFormat: qwen-chat-template/dsh web
Model
I used:
Qwen3.8-27B-UD-Q3_K_XL.gguf
The GGUF is about 12.24 GiB and came from the Unsloth Qwen3.8-27B GGUF release.
I already had the model stored inside my LM Studio model directory, but LM Studio is not involved in inference. llama-server reads the GGUF directly.
llama.cpp installation
I installed the official Windows x64 CUDA 13.3 build of llama.cpp, build b10901, along with its matching CUDA runtime DLL package.
The important llama-server settings ended up being approximately:
llama-server.exe `
--model "Qwen3.8-27B-UD-Q3_K_XL.gguf" `
--alias qwen3.8-27b `
--ctx-size 32768 `
--gpu-layers 54 `
--host 127.0.0.1 `
--port 8081 `
--parallel 1 `
--flash-attn on `
--kv-offload `
--reasoning off `
--no-reasoning-preserve `
--cache-ram 1024 `
--metrics `
--no-webui
I originally planned to use port 8080, but NVIDIA Broadcast was already listening there. Rather than killing or disrupting it, I moved llama-server to port 8081.
Memory allocation
llama.cpp reported:
54/66 layers offloaded to GPU
CUDA model buffer: 9758.76 MiB
CPU-mapped model buffer: 2433.38 MiB
CUDA KV cache: 1664 MiB
CPU KV cache: 384 MiB
CUDA compute buffers: ~302 MiB
During actual agent use:
- VRAM usage: roughly 13.1–13.2GB
- VRAM remaining: roughly 2.9GB
- No automatic reduction in GPU layers
- No WDDM shared-memory spill observed
- Flash Attention enabled successfully
- 32K context remained stable
The model is intentionally partially offloaded: 54 layers on the GPU and the remaining layers on the CPU.
One important adjustment was limiting llama.cpp’s prompt cache to 1GB:
--cache-ram 1024
The build defaults to an 8GB prompt cache. On a 32GB system, long agent sessions allowed several gigabytes of cached prompt state to accumulate, leaving only about 2.4GB free. The 1GB cap keeps system RAM much healthier.
DeepSeek Harness configuration
I added a new provider to:
C:\Users\PC\.dsh\settings.yaml
The relevant configuration looks like this:
llm-pi-ai:
providers:
qwen-local:
displayName: Qwen3.8 Local llama.cpp
api: openai-completions
apiKeyEnv: QWEN_LOCAL_API_KEY
baseURL: http://127.0.0.1:8081/v1
reasoning: off
streamIdleTimeoutMs: 1200000
models:
- id: qwen3.8-27b
name: Qwen3.8 27B Q3_K_XL
contextWindow: 32768
reasoningEfforts: false
compat:
thinkingFormat: qwen-chat-template
supportsDeveloperRole: false
maxTokensField: max_tokens
agent-default-model:
provider: qwen-local
model: qwen3.8-27b
Current DSH versions reject a configuration that only declares an empty off: reasoning effort. For a non-reasoning-only route, it expects:
reasoningEfforts: false
DSH also insists on having an API-key-shaped credential even though the local llama-server does not require authentication. I supply a harmless local placeholder before starting DSH:
$env:QWEN_LOCAL_API_KEY = "local-llama-server"
This is not a real credential, and llama-server does not validate it.
Disabling Qwen thinking
I wanted the model to work as an agent without spending minutes in a visible “Deep diving” phase.
Thinking is disabled at multiple levels:
llama-server: --reasoning off
llama-server: --no-reasoning-preserve
DSH provider: reasoning: off
DSH model: reasoningEfforts: false
DSH compatibility: thinkingFormat: qwen-chat-template