Magic Tools
Back to all briefs

Dev Breakfast · 2026-09-15

Today's headline: Migrating 35KB Prompts to Self-Hosted Ollama: It Runs, But Runs Out of Fuel in 3 Minutes. Plus 4 more: PyO3 in Action: JSON Conversion Can Be Slower Than Parsing Itself; RX 9060 XT Runs CUDA: A Reproducible Checklist for ZLUDA + HIP SDK 6.4; and more.

September 15, 202610 min readDev Breakfast

A 35KB preprompt migrated from Opus to self-hosted Ollama, the 27B local model starts going in circles in tool calls and repeated reads after 3 minutes. Being able to run doesn't mean it can handle the load; for such migrations, the first calculation should be the context budget.

🍳 Today's Headlinethe one deep dive of the day

Migrating 35KB Prompts to Self-Hosted Ollama: It Runs, But Runs Out of Fuel in 3 Minutes

What happens when you move a 35KB preprompt from Opus to self-hosted Ollama? The original answer is quite straightforward: prompts that work well on frontier APIs fall apart on local models. This isn't a conclusion that 'local models are bad,' but the start of a troubleshooting list.

First, hardware prerequisites, because this determines all subsequent phenomena. The author's machine is an AMD Ryzen AI MAX+ 395, with 128GB of RAM, of which 32GB is reserved for the host system, and the rest is allocated to inference. He targets the abliterated (refusal-removed) open-source 27B model, aiming to bypass frontier vendors' safety refusals on cybersecurity topics—according to him, these filters prevent defenders from discovering vulnerabilities because 'discovering vulnerabilities' itself is categorized as hacking-related. He wants to verify: can a local 27B handle his most context-intensive agents?

Migrating 35KB Prompts to Self-Hosted Ollama: It Runs, But Runs Out of Fuel in 3 Minutes

The answer is no, not directly. The original text records this specifically: when he moves the large preprompt that works well on frontier providers over, Ollama starts 'running out of fuel' within 3 minutes, with the agent going in circles in repetitive tool calls and re-reads. Note this 3 minutes—it's not that the model is slow to respond, but that after the context is eaten by the large prompt, there's not enough space left for dialogue and tool results, so the agent gets stuck in a loop. The usage pattern you're accustomed to on the cloud—'just stack prompts, anyway the context window is large'—becomes a different calculation locally.

There's an easily overlooked boundary here: the author is concerned not just with 'will my data be used for training,' but with session metadata—the set of intuitions you use to step-by-step force AI to solve problems is itself a scarce commodity. His original words are: the agent session is your complete record of handling the hardest problems; if someone else has a copy, what's the cost? This perspective goes deeper than 'don't upload privacy': the valuable part isn't the data, but your methodology for debugging agents. In the same article, he mentions that when asked about data retention, frontier vendors' strongest defensive statement is 'cannot rule it out,' and both retention and training pipelines are unauditable—this unauditability is itself a reason for self-hosting, regardless of model strength.

A horizontal comparison makes it clearer: the same 35KB prompt runs smoothly on Opus but stalls after 3 minutes on local 27B. The gap isn't in 'who is smarter,' but in how much context budget you can allocate to the model. On the cloud, you pay for the window; locally, you trade VRAM for the window, and with 128GB, you first carve out 32GB for the system, with every remaining GB competing with model weights. So the intuition that 'self-hosting saves money' needs to be flipped: what you save is the API bill, but what you pay is having to do context engineering yourself and accepting another failure mode beyond refusal—not refusing to answer, but starting to spin in circles while answering.

For coders, the direct implications of this matter are several layers. First, if you're considering migrating an agent to local, don't test with small prompts; use your longest one to stress-test, with the 3-minute mark as your acceptance line. Second, abliterated weights solve the refusal problem but not the context budget problem—these two are often conflated. Third, tool-call-intensive agents are the least friendly to local deployment, because each round of tool results consumes the window, and once a loop starts, it's exponential waste.

The original text doesn't say what happened later—whether he reduced the prompt, switched quantization, or added VRAM configuration to make it work. This point needs honest acknowledgment: currently, only that 'the first attempt failed, failing by exhausting within 3 minutes' is confirmed.

💡 Chef's take: What he really wants to migrate isn't the prompts, but the set of 'how to force AI to produce answers' session records—according to him, this is more valuable than the code itself. So the first hurdle for local deployment isn't model strength, but whether you're willing to manage the context budget yourself.

Sources:

🍲 Deep Dives · 2 more

PyO3 in Action: JSON Conversion Can Be Slower Than Parsing Itself

Writing a JSON parser in Rust and wrapping it into a Python library sounds like standard practice. But what really determines whether this port is worth it is the exit point: for 100,000 values, you need to create about 100,000 Python objects at the boundary, and this step's overhead can exceed the parsing itself. Writing Rust fast is the easy half; converting Rust values to Python objects is the half that decides success or failure.

The process itself has four steps: write a normal Rust module, annotate it with #[pyfunction] and #[pymodule] macros, have maturin compile it into a shared library (.so / .dylib / .dll) and drop it into a virtualenv, then import as usual. Attribute macros like #[pyfunction] are similar to Python decorators; they rewrite the function, add glue code so Python can call it, and handle type conversion and reference counting at the boundary. Pydantic v2's core, pydantic-core, is built this way; every time you do data validation, it runs this system.

The pitfall is in return values. The parser produces a Rust enum tree, invisible to Python; .into_pyobject(py) walks the entire tree, rebuilding it into native Python objects—each object becomes a dict, each array a list, each leaf a float or str, recursively completed by implementing the IntoPyObject trait. All this happens after parsing is completely finished. Errors also need translation: implement From for JsonError to convert to PyErr, and ? can turn a parsing failure with position into a ValueError with offset; std::io::Error has built-in conversion, so a nonexistent path directly throws FileNotFoundError.

So, if the Rust function you're porting returns scalars, go ahead—the boundary is small enough to ignore; if it returns large structures, conversion is the real cost, and the next optimization point after the parser speeds up. Pre-allocating PyDict only yields marginal gains; a bigger win is architectural: if callers won't touch the entire tree, don't rush to materialize the full tree—switch back to a lazy, Rust-backed view that generates Python objects on demand. The onboarding path is also provided in the original: in the #[pyfunction] signature, py: Python<'py> is the token to access the interpreter, Bound<'py, PyAny> is equivalent to PyObject on the Rust side, and PyResult<T> is Result<T, PyErr>. Before porting, profile the boundary, not just the algorithm.

Sources:

RX 9060 XT Runs CUDA: A Reproducible Checklist for ZLUDA + HIP SDK 6.4

Someone on GitHub released a Windows CUDA compatibility solution: using ZLUDA to translate CUDA calls to AMD's HIP/ROCm, paired with AMD HIP SDK 6.4, ZLUDA v6-preview.69, LibTorch 2.3.0 + cu118. It explicitly lists only one verified hardware: Radeon RX 9060 XT (gfx1200, RDNA4). Other AMD cards in the script are just marked as unverified candidates—being identifiable doesn't mean it works, and this distinction is made quite honestly.

What works is listed fairly specifically: nvcuda, cuBLAS, cuBLASLt, cuSPARSE, cuFFT all passed cuda_check; a PPO network with 2,216,347 parameters completed forward inference, PPO learning, and optimizer steps; a clean verification iteration ran 65,536 timesteps. Performance was A/B tested, with each runtime running 10 iterations and discarding the first as warmup; the upstream public path had a median of 13,278 SPS compared to a private overlay's 12,876—the overlay was actually about 3.03% slower, so the upstream is the default. Note that this is 'under this configuration,' not 'CUDA is generally available on AMD.'

The real limitation to watch is the cuDNN column: the stable Windows HIP SDK doesn't include the MIOpen AI library set, so programs relying on convolutions or cuDNN won't run; you need to switch to nightly or provide it yourself. The author also states directly that dense GEMM-based LibTorch training doesn't necessarily require cuDNN—the verification PPO ran without it. The onboarding path is git clone followed by running install.ps1—it detects the GPU's gfx target, verifies the driver and HIP SDK, downloads fixed versions of ZLUDA and about 2.66 GB of LibTorch, checks SHA-256, then generates runtime configuration and runs a cuda_check; if LibTorch isn't needed, add -SkipLibTorch. Then run-zluda.ps1 -Program xxx.exe places the compatibility DLLs next to the target program and launches it.

For coders, the significance of this isn't in the one-sentence conclusion that 'AMD can run CUDA,' but in laying bare which layers are replaced: the CUDA driver layer goes through ZLUDA, and math libraries fall to rocBLAS, hipBLASLt, rocSPARSE. If you have an NVIDIA card, you basically don't need to touch anything; if you're considering using AMD cards to save VRAM costs and happen to be stuck on CUDA dependencies, first check this coverage table to see which libraries you use—as long as you hit cuDNN, this current path must be put aside for now.

Sources:

🥢 Sides · 2 more

A Permission-Free App Can Root Devices like Samsung and Xiaomi

The original text only has a title and one line of explanation: an Android app that requires no special permissions can gain root on devices from manufacturers like Samsung and Xiaomi. No specific models, system versions, or exploitation chains are disclosed, so currently only that 'this exists' is confirmed; whether it's worth examining further awaits details. For coders, the direct implication isn't in rooting phones, but in the type of problem it hits: in manufacturer-customized system services, as long as one link treats external input as trusted data, privilege escalation is just a matter of time. When viewing such research, I habitually first check what exactly was changed and which versions are affected, before looking at the spectacle.

Sources:

AI Agent Attacks RubyGems: This Time Only One Accusation

We discussed this a few days ago, when the original text had only one accusation, and I advised not to treat it as confirmed. Looking again today, it's still the same sentence: a malicious AI agent attacked RubyGems.org. There's no attack method, no agent behavior pattern, and no numbers. So the judgment remains unchanged, the evidence is still thin—but this is worth watching, because once a package repository is poisoned, all those pulling dependencies are affected. The original text only has the title, so note this direction for now.

Sources:


Do you dare to also move your long-prompt tasks to run on local 27B, or continue burning API? See you tomorrow morning at 8.

This issue selected 5 items from 74 pieces of information in the past 24 hours from X / Hacker News / GitHub Trending (written hourly throughout the day, fact-checked, and compiled in the morning). Content was generated with LLM assistance, each item includes original source links, and important decisions should be cross-verified.

Like this brief? Get tomorrow's by email

Each morning at 8:00, 5-10 hand-picked AI items in plain language, with full context.

This page is auto-generated by LLM aggregation; please cross-check with original sources.