TL;DR: My Pi Coding Agent installation runs on Qwen3.6-27B served by llama.cpp on an RTX 5090, with 104 skills, 4 custom agents, speculative decoding via ngram-mod, and the pi-tools package extending core functionality.
Overview
This entire setup runs on a single RTX 5090 PC with 32 GB VRAM. Pi Coding Agent is a terminal-based coding agent with read, bash, edit, and write tools plus session management. My installation is at ~/.pi with version 0.78.0 installed globally via npm.
The original plan was to run both MTP (Multi-Token Prediction) and ngram-mod speculative decoding together. MTP requires loading an additional small drafter model alongside the main one, which pushed the 32 GB VRAM past its limit and made the server unstable. I dropped the idea — ngram-mod alone already delivers fast tokens/second and runs rock-solid with just a ~16 MB hash table and no extra model weights.
Core Configuration
| Setting | Value |
|---|---|
| Version | 0.78.0 |
| Default Provider | pc-eyay |
| Default Model | unsloth/Qwen3.6-27B-MTP-GGUF (Q5_K_S) |
| Thinking Level | medium |
| Telemetry | Disabled |
| Hardware Cursor | Enabled |
Models
One provider points to a local inference server on the LAN using the OpenAI completions API format.
| Provider | Model | Context Window | Input Types |
|---|---|---|---|
pc-eyay | unsloth/Qwen3.6-27B-MTP (Q5_K_S) | 200K tokens | text, image |
Main model: Q5_K_S quantization (5-bit). Multimodal projector: BF16.
Inference Server — llama.cpp
The model is served via llama-server (commit b4c0549a4, tagged b9352, May 27 2026) on a separate machine with NVIDIA RTX 5090 (CUDA_VISIBLE_DEVICES=0).
Startup Script
#!/bin/sh
export CUDA_VISIBLE_DEVICES=0
export LLAMA_CPP_HOME=$HOME/path/to/llama.cppexport MODEL_HOME=$HOME/path/to/models/Qwen3.6-27B
export MAIN_MODEL=$MODEL_HOME/mtp/Qwen3.6-27B-Q5_K_S.ggufexport MMPROJ_MODEL=$MODEL_HOME/mmproj-F16.gguf
$LLAMA_CPP_HOME/build/bin/llama-server \ -m "$MAIN_MODEL" \ --mmproj "$MMPROJ_MODEL" \ --no-mmproj-offload \ --image-min-tokens 1024 \ -ctk q8_0 -ctv q8_0 \ -fa on \ --kv-unified \ --host 0.0.0.0 --port 8082 \ -ngl all \ -np 1 \ --spec-type ngram-mod \ --no-mmap --mlock --jinja \ --no-host --metrics \ --log-timestamps --log-prefix -lv 3 \ --no-context-shift \ --reasoning on \ --chat-template-kwargs '{"preserve_thinking":true}' \ --temp 0.6 --top-k 20 --top-p 0.95 --min-p 0.0 --presence-penalty 0.0 --repeat-penalty 1.0Model Loading
| Parameter | Value | Purpose |
|---|---|---|
-m | Qwen3.6-27B-Q5_K_S.gguf | Main model from unsloth/Qwen3.6-27B-MTP-GGUF, Q5_K_S quantized |
--mmproj | mmproj-BF16.gguf | Multimodal projector for image understanding, BF16 precision |
--no-mmproj-offload | (flag) | Keep projector in CPU RAM instead of VRAM. Saves GPU memory for the main model |
--image-min-tokens | 1024 | Minimum token budget per image. Vision models with dynamic resolution allocate at least this many tokens per image |
KV Cache
| Parameter | Value | Purpose |
|---|---|---|
-ctk | q8_0 | Key cache quantized to 8-bit (default: f16). Saves ~50% VRAM per key token with minimal quality loss |
-ctv | q8_0 | Value cache quantized to 8-bit (default: f16). Same VRAM savings |
--kv-unified | (flag) | Single unified KV buffer shared across all sequences. More efficient memory usage than per-slot allocation |
GPU Offloading
| Parameter | Value | Purpose |
|---|---|---|
-ngl | all | Offload all model layers to GPU. Maximizes inference speed on RTX 5090 |
-fa | on | Flash Attention enabled. Reduces VRAM for attention computation and speeds up processing |
Memory Management
| Parameter | Value | Purpose |
|---|---|---|
--no-mmap | (flag) | Disable memory-mapped file I/O. Slower model load but prevents page-outs during inference |
--mlock | (flag) | Lock model in RAM — OS cannot swap or compress. Guarantees consistent inference speed |
--no-host | (flag) | Bypass host buffer, allowing extra buffers to be used. Frees up CPU memory |
Speculative Decoding
| Parameter | Value | Purpose |
|---|---|---|
--spec-type | ngram-mod | N-gram speculative decoder with modified hash table. Learns n-gram patterns online during generation, drafts tokens by looking up what historically followed the same sequence. Best for repetitive text (code, documentation). Uses FNV-1a hashing with 4M entry table (~16 MB). Resets on low acceptance (<25% for 5 rounds) |
Other available types: draft-simple, draft-eagle3, draft-mtp, ngram-simple, ngram-map-k, ngram-map-k4v, ngram-cache.
Context Handling
| Parameter | Value | Purpose |
|---|---|---|
--no-context-shift | (flag) | Disables context shifting during infinite generation. llama.cpp disabled this by default in PR #15416 — ggerganov noted it “is causing a lot of confusion” with modern chat-template models. With Qwen3.6 specifically, context shifting corrupts the Jinja template structure and causes hard stops (Discussion #15403, Issue #17284). Explicitly disabling it ensures generation stops cleanly when context is full rather than producing garbled output |
Chat Template & Reasoning
| Parameter | Value | Purpose |
|---|---|---|
--jinja | (flag) | Use Jinja template engine for chat formatting (default: enabled). Required for Qwen3.6 chat templates |
--reasoning | on | Enable reasoning/thinking mode. Model outputs chain-of-thought before final answer |
--chat-template-kwargs | {"preserve_thinking":true} | Qwen team explicitly recommends this for agentic workflows: “maintaining full reasoning context can enhance decision consistency and, in many cases, reduce overall token consumption by minimizing redundant reasoning” (model card). Without it, the model strips historical thinking blocks, causing tool-call argument loss on multi-turn conversations (pi Issue #3325, Open WebUI #23895). A/B tests confirm fewer completion tokens with preservation enabled (meirong.dev) |
Sampling Parameters
These match the Qwen team’s recommended settings for precise coding tasks (thinking mode, coding agent profile):
| Parameter | Value | Purpose |
|---|---|---|
--temp | 0.6 | Lower temperature for deterministic coding output. Qwen team recommends 0.6 for coding (vs 1.0 for general chat) |
--top-k | 20 | Only sample from top 20 tokens. Reduces nonsense outputs |
--top-p | 0.95 | Nucleus sampling — only consider tokens covering 95% of probability mass |
--min-p | 0.0 | Minimum probability threshold. 0.0 = disabled |
--presence-penalty | 0.0 | No penalty for repeating topics |
--repeat-penalty | 1.0 | No penalty for repeating tokens (1.0 = neutral) |
Server & Logging
| Parameter | Value | Purpose |
|---|---|---|
--host | 0.0.0.0 | Bind to all network interfaces |
--port | 8082 | HTTP/gRPC server port |
-np | 1 | Single parallel sequence (single slot) |
--metrics | (flag) | Enable Prometheus-compatible metrics endpoint at /metrics |
--log-timestamps | (flag) | Include timestamps in log output |
--log-prefix | (flag) | Include log level prefix in output |
-lv | 3 | Log verbosity: 3 = info level (0=generic, 1=error, 2=warning, 3=info, 4=trace, 5=debug) |
llama.cpp — Current vs Latest
The server runs at commit b4c0549a4 (tag b9352, May 27 2026). HEAD is at e674b12 — 77 commits ahead.
Breaking Changes
| Commit | Change |
|---|---|
6b4e4bd | All environment variables renamed to LLAMA_ARG_ prefix. Scripts using old env var names will break |
Critical Bug Fixes
| Commit | Fix |
|---|---|
09e7b76 | CUDA KQ mask integer overflow in Flash Attention MMA kernel — can silently corrupt attention output |
e31cdaa | ARM SVE usage bug in vec.h/vec.cpp — correctness fix |
7c48fb8 | Vulkan wrong index variable in inner loop |
91eb8f4 | Vulkan memory logger unsafe iterator access |
Performance Improvements
| Commit | Improvement |
|---|---|
031ddb2 | f16 mask for Flash Attention — saves VRAM |
6e093b8 | Vulkan Flash Attention with BFloat16 KV cache |
bc81d47 | CUDA: route batch>=4 quantized matmul to MMQ on AMD MFMA |
d7be461 | Turing GPU MMVQ optimization |
fe12e42 | ggml upstream sync |
ea02bc3 | ggml version bump to 0.13.1 |
New Features
| Commit | Feature |
|---|---|
1f0aa2a | DeepSeekV3.2 with Sparse Attention (DSA) support |
da3f990 | DeepSeekOCR 2 multimodal support |
5a46b46 | Self-updater (llama update) |
d205df6 | HTTP ETags in llama-server |
eef59a7 | New MTP graph input API |
7fb1e70 | LLAMA_ARG_API_KEY_FILE environment variable |
c522908 | FP8 to Q8 quantization conversion |
Speculative Decoding
| Commit | Change |
|---|---|
b000431 | ngram-mod: add missing include (minor) |
241cbd4 | CUDA: disable PDL FA enrollment (compiler bug workaround) |
fda8528 | CUDA: restrict PDL to CTK >= 12.3 |
6ed481e | CUDA: PTX version guard for PDL dispatch |
Server Changes
| Commit | Change |
|---|---|
0821c5f | SSE: send HTTP headers when slot starts |
d205df6 | HTTP ETags support |
cb47092 | Timeout bumped to 3600s |
Assessment
Low-risk upgrade. No changes to any parameters used in the current script. Key gains:
- CUDA integer overflow fix — prevents silent corruption at certain context lengths
- VRAM savings from f16 Flash Attention mask
- ggml 0.13.1 core improvements
- Server ETags for better client caching
One check needed: any LLAMA_* environment variables (not LLAMA_ARG_*) must be renamed per 6b4e4bd.
Custom Agents
Four agents are defined in ~/.pi/agent/agents/, all running on the local Qwen3.6-27B model:
| Agent | Tools | Purpose |
|---|---|---|
| scout | read, grep, find, ls, bash | Fast codebase recon — returns compressed context for handoff |
| planner | read, grep, find, ls | Creates implementation plans from scout findings and requirements |
| worker | (all) | General-purpose subagent with full capabilities, isolated context |
| reviewer | read, grep, find, ls, bash | Code review for quality, security, and maintainability |
The workflow is a pipeline: scout explores → planner designs → worker executes → reviewer audits.
Extensions
One extension is installed in ~/.pi/agent/extensions/:
subagent
Symlinked from the Pi examples directory. Provides the subagent tool for delegating tasks to the custom agents above.
| Feature | Detail |
|---|---|
| Modes | single, parallel (max 8 tasks), chain (sequential with {previous} placeholder) |
| Concurrency | 4 parallel tasks max |
| Output Cap | 50 KB per task |
| Agent Scope | user, project, or both |
| JSON Mode | Structured output capture from subagents |
Packages
One external package is configured:
| Package | Version | Purpose |
|---|---|---|
git:github.com/joelhooks/pi-tools | 0.4.0 | Extensions, repo autopsy, joelclaw session wrappers, skill shortcuts, MCQ, MCP bridge, web search, url-to-markdown, excalidraw, linear-tracker |
The pi-tools package adds these skills (in ~/.pi/agent/git/…/skills/):
| Skill | Description |
|---|---|
| linear-tracker | Project-local issue tracker routing and Linear issue publishing |
| pi-tui-design | Custom TUI components using @mariozechner/pi-tui |
| session-search | Search Pi, Claude, and Codex session history via pi-tools session-reader |
Skills
Skills are prompt templates that activate contextually. They live in two directories:
User Skills (~/.pi/agent/skills/) — 37 skills
These are globally available across all projects:
| Category | Skills |
|---|---|
| Browser | agent-browser |
| Frameworks | nuxt, pinia, vue, vue-best-practices, vue-router-best-practices, vue-testing-best-practices, vueuse-functions |
| Build | vite, vitepress, vitest, tsdown, turborepo, pnpm, unocss |
| Design | slidev, slidev-styling, slidev-syntax-guide, slidev-themes, svg-animations, svg-illustration, tailwind-design-system, tailwindcss-advanced-layouts, baoyu-diagram, web-design-guidelines |
| Research | tavily-search, tavily-research, tavily-extract, tavily-crawl, tavily-map, tavily-cli, tavily-dynamic-search, tavily-best-practices |
| Go | golang-documentation |
| Other | antfu, ccc, mckinsey-consultant |
Project Skills (~/.agents/skills/) — 67 skills
These are available across all projects that reference them:
| Category | Skills |
|---|---|
| Workflow | session-start, enhanced-brainstorming, enhanced-debugging, enhanced-finishing, enhanced-research, enhanced-verification, knowledge-persistence |
| Context | context-mode, ctx-doctor, ctx-purge, ctx-stats, ctx-upgrade |
| Tracking | beads |
| Discovery | find-docs, find-skills |
| Web | web-scraping-selector, crawl4ai |
| Infographic | infographic-creator, infographic-item-creator, infographic-structure-creator, infographic-syntax-creator, infographic-template-updater |
| Go | golang-patterns |
| Design | daisyui-5, svg-animation-engineer, idds-helper |
| Accessibility | accessibility-a11y |
| Frameworks | astro |
| Tavily | tavily-search, tavily-research, tavily-extract, tavily-crawl, tavily-map, tavily-cli, tavily-dynamic-search, tavily-best-practices |
| All from user | All 37 user skills are also symlinked/available here |
Skill Overlap
The Tavily suite (8 skills) and most framework skills appear in both directories. The project directory adds workflow orchestration, context management, infographic creation, and discovery tools on top.
Prompt Templates
Three prompt templates in ~/.pi/agent/prompts/:
| Template | Purpose |
|---|---|
scout-and-plan.md | Combined scout + planner workflow |
implement.md | Direct implementation |
implement-and-review.md | Implementation with review step |
Sessions
13 session directories exist, organized by working path. Sessions are JSONL transcripts capturing full conversation history with tool calls, outputs, and usage stats.
Architecture Summary
scout-and-plan, implement, implement-and-review"] end subgraph Core["Pi Core 0.78.0"] T["Tools: read, bash, edit, write, subagent"] S["Session Management"] M["Model Router
pc-eyay"] end subgraph Agents["Custom Agents"] SC["scout"] PL["planner"] W["worker"] R["reviewer"] end subgraph Skills["Skills — 104 total"] US["37 user skills"] PS["67 project skills"] end subgraph Ext["Extensions"] SA["subagent extension"] PT["pi-tools 0.4.0"] end subgraph Local["Local Inference"] L["llama-server
b4c0549a4 (b9352)"] Q["unsloth/Qwen3.6-27B-MTP
Q5_K_S + BF16 mmproj"] L --> Q end P --> Core Core --> T T --> SA SA --> Agents Core --> Skills Core --> M M --> Local Ext --> Core
References
- Qwen3.6-27B Model Card — Qwen Team, HuggingFace — https://huggingface.co/Qwen/Qwen3.6-27B
- unsloth/Qwen3.6-27B-MTP-GGUF — https://huggingface.co/unsloth/Qwen3.6-27B-MTP-GGUF
- llama.cpp Repository — https://github.com/ggml-org/llama.cpp
- llama.cpp: disable context shift by default — ggerganov, PR #15416 — https://github.com/ggml-org/llama.cpp/pull/15416
- llama.cpp: context shift doesn’t work with Qwen 3 VL — Discussion #15403 — https://github.com/ggml-org/llama.cpp/discussions/15403
- llama.cpp: context shift hard stop with Qwen — Issue #17284 — https://github.com/ggml-org/llama.cpp/issues/17284
- llama.cpp ngram-mod speculative decoding — PR #19164 — https://github.com/ggml-org/llama.cpp/pull/19164
- pi: Qwen3.6 tool-call argument loss without preserve_thinking — Issue #3325 — https://github.com/earendil-works/pi/issues/3325
- Open WebUI: preserve_thinking critical for agentic workflows — Discussion #23895 — https://github.com/open-webui/open-webui/discussions/23895
- vLLM Qwen3.6 preserve_thinking A/B test — meirong.dev — https://meirong.dev/posts/vllm-qwen36-preserve-thinking
- Pi Coding Agent Repository — https://github.com/earendil-works/pi-mono
- Pi Tools Repository — https://github.com/joelhooks/pi-tools
This article was written by Pi Agent (unsloth/Qwen3.6-27B-MTP Q5_K_S | Local).


