<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: BetterToken.ai</title>
    <description>The latest articles on DEV Community by BetterToken.ai (bettertoken_ai).</description>
    <link>https://dev.to/bettertoken_ai</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F14430%2Ffb9953f3-c1c4-49e3-8bd0-9678f45e1075.png</url>
      <title>DEV Community: BetterToken.ai</title>
      <link>https://dev.to/bettertoken_ai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bettertoken_ai"/>
    <language>en</language>
    <item>
      <title>Qwen Image 2.1 in ComfyUI: Local Setup by VRAM</title>
      <dc:creator>Adela</dc:creator>
      <pubDate>Wed, 30 Sep 2026 09:18:53 +0000</pubDate>
      <link>https://dev.to/bettertoken_ai/qwen-image-21-in-comfyui-local-setup-by-vram-41g8</link>
      <guid>https://dev.to/bettertoken_ai/qwen-image-21-in-comfyui-local-setup-by-vram-41g8</guid>
      <description>&lt;p&gt;The most reliable way to run Qwen Image 2.1 on a consumer GPU is not to begin with the smallest GGUF you can find. Update ComfyUI, load the official text-to-image workflow, select the official INT8 diffusion model plus a matching Qwen3-VL text encoder and VAE, then generate and save one small image. On an 8 GB or 12 GB card, do not start with BF16, 2K output, or the prompt enhancer.&lt;/p&gt;

&lt;p&gt;Neither Qwen nor Comfy Org publishes one minimum-VRAM number that applies to every PC. The 8 GB and 12 GB configurations below are conservative starting points, not guarantees: system RAM, model offloading, drivers, resolution, and other GPU processes all change peak memory use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose the weights first: file size is not peak VRAM
&lt;/h2&gt;

&lt;p&gt;As of 2026-09-28, the &lt;a href="https://huggingface.co/Comfy-Org/Qwen-Image-2.1" rel="noopener noreferrer"&gt;official Comfy Org model repository&lt;/a&gt; contains two diffusion weights, three main text encoders, one VAE, and two separate prompt-enhancer models. A first image needs the diffusion model, one main text encoder, and the VAE. The &lt;code&gt;qwen3.5_9b_..._pe_t2i&lt;/code&gt; file is an optional prompt enhancer; it does not replace the &lt;code&gt;qwen3vl_8b_...&lt;/code&gt; encoder.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Recommended first-run file&lt;/th&gt;
&lt;th&gt;Approx. download size&lt;/th&gt;
&lt;th&gt;Folder&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Diffusion model&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen_image_2.1_int8_convrot.safetensors&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7.26 GB&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ComfyUI/models/diffusion_models/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Main text encoder, lower-memory choice&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen3vl_8b_w4a8.safetensors&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;6.31 GB&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ComfyUI/models/text_encoders/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Main text encoder, official template default&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen3vl_8b_int8_convrot.safetensors&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;9.35 GB&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ComfyUI/models/text_encoders/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VAE&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen_image_2.1_vae_bf16.safetensors&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.68 GB&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ComfyUI/models/vae/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Optional T2I prompt enhancer&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen3.5_9b_qwen_image_2.1_pe_t2i.int8_convrot.safetensors&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;9.47 GB&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ComfyUI/models/text_encoders/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Those figures are repository file sizes, not runtime VRAM. INT8 diffusion + W4A8 encoder + VAE is about 14.24 GB of downloads; the official template's INT8 + INT8 + VAE combination is about 17.28 GB. Enabling the prompt enhancer adds about 9.47 GB of storage and another large model-loading stage.&lt;/p&gt;

&lt;h3&gt;
  
  
  A practical first configuration for each VRAM tier
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Available VRAM&lt;/th&gt;
&lt;th&gt;Try first&lt;/th&gt;
&lt;th&gt;First-generation settings&lt;/th&gt;
&lt;th&gt;Upgrade only after success&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;8 GB&lt;/td&gt;
&lt;td&gt;INT8 diffusion + W4A8 main encoder + VAE; prompt enhancement off&lt;/td&gt;
&lt;td&gt;768×768 or below roughly 1 MP, batch 1, CFG 1&lt;/td&gt;
&lt;td&gt;Try 1024 next; consider community GGUF only if the official path still OOMs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12 GB&lt;/td&gt;
&lt;td&gt;INT8 diffusion + W4A8 main encoder; try INT8 encoder later&lt;/td&gt;
&lt;td&gt;1024×1024, batch 1, CFG 1&lt;/td&gt;
&lt;td&gt;Enable the enhancer or raise resolution one change at a time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16 GB and up&lt;/td&gt;
&lt;td&gt;Official-template INT8 diffusion + INT8 encoder + VAE&lt;/td&gt;
&lt;td&gt;1024×1024, 25 steps, CFG 1&lt;/td&gt;
&lt;td&gt;Test prompt enhancement and 2K separately&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plenty of VRAM and system RAM&lt;/td&gt;
&lt;td&gt;Prove the INT8 path first, then compare BF16 components&lt;/td&gt;
&lt;td&gt;Keep prompt, seed, and dimensions fixed&lt;/td&gt;
&lt;td&gt;Use BF16 only when you accept the larger footprint and want a controlled comparison&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The 8 GB and 12 GB rows minimize troubleshooting cost; they are not official hardware requirements. Qwen documents model offloading for limited-memory GPUs, while ComfyUI decides what to keep on the GPU for a particular machine. Two systems with the same GPU can therefore behave differently.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Update ComfyUI before looking for custom nodes
&lt;/h2&gt;

&lt;p&gt;Qwen Image 2.1 has native ComfyUI support. The official workflow should not require a third-party node pack. Red nodes, a missing Qwen Image 2.1 template, or an absent &lt;code&gt;TextEncodeQwenImage21&lt;/code&gt; node usually mean the core application or its packaged dependencies are out of date.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Windows Portable:&lt;/strong&gt; close ComfyUI and run &lt;code&gt;ComfyUI_windows_portable/update/update_comfyui.bat&lt;/code&gt;, then restart. Do not use &lt;code&gt;update_comfyui_and_python_dependencies.bat&lt;/code&gt; as the routine first choice because it reinstalls the dependency stack.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ComfyUI Desktop:&lt;/strong&gt; update the Engine from Manage → Update. Stable releases can lag the newest model support; use the available &lt;code&gt;Latest on GitHub&lt;/code&gt; channel, or move to Portable/manual installation if your current Desktop build still lacks the nodes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual Git install:&lt;/strong&gt; update code and dependencies inside the Python environment that runs ComfyUI, then restart it.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /path/to/ComfyUI
git pull
python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
python main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://docs.comfy.org/installation/update_comfyui" rel="noopener noreferrer"&gt;official update guide&lt;/a&gt; warns that &lt;code&gt;git pull&lt;/code&gt; alone can leave the frontend, workflow templates, and new nodes outdated. Updating &lt;code&gt;requirements.txt&lt;/code&gt; dependencies is part of the update, not an optional cleanup step.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Put each model in the folder its loader scans
&lt;/h2&gt;

&lt;p&gt;Download your selected files from the &lt;a href="https://huggingface.co/Comfy-Org/Qwen-Image-2.1" rel="noopener noreferrer"&gt;official ComfyUI model repository&lt;/a&gt;. Keep every filename unchanged; browser-added suffixes such as &lt;code&gt;(1)&lt;/code&gt; can prevent the workflow from finding the model it names.&lt;/p&gt;

&lt;p&gt;A low-memory first run can use this layout. Choose either the W4A8 or INT8 main encoder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ComfyUI/
└── models/
    ├── diffusion_models/
    │   └── qwen_image_2.1_int8_convrot.safetensors
    ├── text_encoders/
    │   ├── qwen3vl_8b_w4a8.safetensors
    │   └── qwen3.5_9b_qwen_image_2.1_pe_t2i.int8_convrot.safetensors  # optional
    └── vae/
        └── qwen_image_2.1_vae_bf16.safetensors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To match the official template's default, replace &lt;code&gt;qwen3vl_8b_w4a8.safetensors&lt;/code&gt; with &lt;code&gt;qwen3vl_8b_int8_convrot.safetensors&lt;/code&gt;. Restart ComfyUI after copying the files; loader dropdowns normally reflect the files found during startup.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Import the official text-to-image workflow
&lt;/h2&gt;

&lt;p&gt;Open the Qwen Image 2.1 text-to-image template from ComfyUI's Templates panel, or download and drag the &lt;a href="https://github.com/Comfy-Org/workflow_templates/blob/main/templates/image_qwen_image_2_1_t2i.json" rel="noopener noreferrer"&gt;official T2I workflow JSON&lt;/a&gt; onto the canvas. The current official template packages the main graph as a subgraph and starts at 1024×1024, 25 steps, CFG 1, and &lt;code&gt;euler&lt;/code&gt; + &lt;code&gt;simple&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Check the loaders and controls in this order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select &lt;code&gt;qwen_image_2.1_int8_convrot.safetensors&lt;/code&gt; as the diffusion model.&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;qwen3vl_8b_w4a8.safetensors&lt;/code&gt; or &lt;code&gt;qwen3vl_8b_int8_convrot.safetensors&lt;/code&gt; as the main text encoder, with type &lt;code&gt;qwen_image&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;qwen_image_2.1_vae_bf16.safetensors&lt;/code&gt; as the VAE.&lt;/li&gt;
&lt;li&gt;Keep &lt;code&gt;refine_prompt&lt;/code&gt; set to &lt;code&gt;false&lt;/code&gt; for the first run. The current template exposes a PE-model selector, but the &lt;code&gt;qwen3.5_9b_..._pe_t2i&lt;/code&gt; model is only for prompt enhancement.&lt;/li&gt;
&lt;li&gt;Start an 8 GB card at 768×768. Start 12 GB and larger cards at 1024×1024. Prefer dimensions divisible by 32.&lt;/li&gt;
&lt;li&gt;Keep batch size 1 and CFG 1. Do not add LoRA, ControlNet, reference-image, or upscaling branches yet.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Use a deliberately simple first prompt so that success is easy to judge:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A red ceramic teapot on a wooden table, soft window light, plain background.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not begin at 2K. Native 2K support means the model can generate 2048×2048 directly; it does not mean an 8 GB or 12 GB GPU can complete that size under every configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Queue one job, wait, and verify that the PNG was saved
&lt;/h2&gt;

&lt;p&gt;Click Queue Prompt once. The first run may load tens of gigabytes and move components among VRAM, system RAM, and the CPU. If the canvas has no new preview yet, watch the launch terminal or log rather than repeatedly adding the same job to the queue.&lt;/p&gt;

&lt;p&gt;Treat the first run as successful only when all four signals are present:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The queue finishes without &lt;code&gt;model not found&lt;/code&gt;, &lt;code&gt;missing node type&lt;/code&gt;, &lt;code&gt;CUDA out of memory&lt;/code&gt;, or a crashed process.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SaveImageAdvanced&lt;/code&gt; displays the image; the sampler finishing by itself is not enough.&lt;/li&gt;
&lt;li&gt;A PNG exists under &lt;code&gt;ComfyUI/output/&lt;/code&gt;. The official template uses the filename prefix &lt;code&gt;Qwen_image_2.1&lt;/code&gt; by default; if you changed the Save Image node, use the location shown there.&lt;/li&gt;
&lt;li&gt;The PNG opens normally, has the expected dimensions, and is not fully black, fully transparent, or corrupt.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On an NVIDIA system, you can watch memory in a second terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nvidia-smi &lt;span class="nt"&gt;-l&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Record the diffusion file, text encoder, dimensions, and observed peak. When you later change weights or resolution, change one variable at a time so a new failure has an identifiable cause.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Troubleshoot by symptom, not by replacing everything
&lt;/h2&gt;

&lt;h3&gt;
  
  
  A node is red or says &lt;code&gt;missing node type&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Update ComfyUI core and dependencies, then restart. &lt;code&gt;TextEncodeQwenImage21&lt;/code&gt;, &lt;code&gt;ResolutionSelector&lt;/code&gt;, and the logic switch in the official workflow are core ComfyUI nodes. Installing an unrelated third-party pack with a similar name can make the graph harder to diagnose.&lt;/p&gt;

&lt;h3&gt;
  
  
  A model dropdown is empty or reports &lt;code&gt;model not found&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Check the folder, extension, and exact filename, then restart ComfyUI. Common mistakes are placing the main encoder in &lt;code&gt;models/clip/&lt;/code&gt;, placing the diffusion model in &lt;code&gt;models/checkpoints/&lt;/code&gt;, or allowing the browser to rename a duplicate download.&lt;/p&gt;

&lt;h3&gt;
  
  
  VRAM runs out before sampling starts
&lt;/h3&gt;

&lt;p&gt;Turn prompt enhancement off, switch the main encoder from INT8 to W4A8, keep batch 1, and close GPU-heavy browsers, games, or video tools. Drop an 8 GB card to 768×768; return a 12 GB card to 1024×1024 and remove optional branches.&lt;/p&gt;

&lt;h3&gt;
  
  
  VRAM runs out during VAE decode or just before saving
&lt;/h3&gt;

&lt;p&gt;Reduce width and height, then queue one new job. Lowering steps mostly changes sampling time; reducing resolution more directly lowers latent and decode memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  The queue looks frozen while disk or CPU activity continues
&lt;/h3&gt;

&lt;p&gt;This is often model loading or offloading rather than a finished failure. Wait for a clear completion or error state. Repeated clicks only stack more large jobs. If system memory keeps climbing into heavy swapping, cancel, lower the configuration, and restart ComfyUI.&lt;/p&gt;

&lt;h3&gt;
  
  
  The image looks washed out, overcooked, or structurally broken
&lt;/h3&gt;

&lt;p&gt;Confirm that CFG is still 1. The official template notes that the negative prompt is unused at CFG 1; copying a high-CFG habit from an SDXL workflow is a poor starting point here.&lt;/p&gt;

&lt;h3&gt;
  
  
  1024 works but 2K always OOMs
&lt;/h3&gt;

&lt;p&gt;Keep 1024 as the working baseline. Try 1280, then 1536, and only then 2048, changing one tier at a time with batch 1 and prompt enhancement off. Model capability and local memory capacity are separate constraints.&lt;/p&gt;

&lt;h2&gt;
  
  
  What 8 GB and 12 GB users should actually choose
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;On 8 GB, the goal is to prove the pipeline, not to enable every template feature.&lt;/strong&gt; Use the INT8 diffusion model, W4A8 main encoder, and VAE; disable PE; start at 768×768 and batch 1. If this still fails, confirm that ComfyUI is current and that the machine has enough system RAM before moving to GGUF. Do not insert an unknown quantized file into the stock workflow and assume it is interchangeable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On 12 GB, use 1024×1024 as the first target.&lt;/strong&gt; Start with the W4A8 encoder for headroom, then try the official template's INT8 encoder after the base run is stable. Prompt enhancement is a second-stage feature: it loads another 9B model to rewrite the prompt before image generation, so it should not be introduced while the base graph is still failing.&lt;/p&gt;

&lt;p&gt;Community posts only show that individuals are experimenting; they do not establish a minimum. One user said they were running the model on an 8 GB RTX 5060 laptop while trying to optimize it. A separate 12 GB RTX 3060 user suggested W4A8 to an 8 GB user. These are &lt;a href="https://x.com/mrcat3000/status/2104356189752459348" rel="noopener noreferrer"&gt;the first report&lt;/a&gt; and &lt;a href="https://x.com/Flinpleis/status/2104324115775574311" rel="noopener noreferrer"&gt;the second suggestion&lt;/a&gt;, not controlled tests with complete logs, so they are useful as leads rather than guarantees.&lt;/p&gt;

&lt;h2&gt;
  
  
  GGUF is an optional low-memory route, not the official first run
&lt;/h2&gt;

&lt;p&gt;The Qwen and Comfy Org templates use &lt;code&gt;.safetensors&lt;/code&gt;. GGUF requires a third-party loader, a Qwen Image 2.1-specific quantized file, and a graph built for that loader. The &lt;a href="https://github.com/city96/ComfyUI-GGUF" rel="noopener noreferrer"&gt;ComfyUI-GGUF project&lt;/a&gt; describes itself as work in progress and does not certify every third-party Qwen quant.&lt;/p&gt;

&lt;p&gt;Consider the community route only after the official INT8/W4A8 path still fails for memory:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Update ComfyUI, then install &lt;code&gt;ComfyUI-GGUF&lt;/code&gt; through Manager or from its repository.&lt;/li&gt;
&lt;li&gt;Obtain a file explicitly built for Qwen Image 2.1. Check the publisher, license, hash, and required loader.&lt;/li&gt;
&lt;li&gt;Replace the stock diffusion loader with &lt;code&gt;Unet Loader (GGUF)&lt;/code&gt;. Keep a Qwen Image 2.1-compatible main text encoder and VAE.&lt;/li&gt;
&lt;li&gt;Select the exact filename in the loader and test below roughly 1 MP, CFG 1, batch 1.&lt;/li&gt;
&lt;li&gt;When it fails, return to that quant's own workflow notes. Do not mix a Qwen Image 1.x, Flux, or generic Stable Diffusion graph into the diagnosis.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A Russian user reported getting &lt;code&gt;qwen-image-2.1-UC-Q4_K_M.gguf&lt;/code&gt; to run in ComfyUI but also said the installation required extra help. A separate &lt;a href="https://github.com/foprc/qwen-image-2.1-comfyui-workflow" rel="noopener noreferrer"&gt;community Q8_0 workflow&lt;/a&gt; combines GGUF with the official text encoder and VAE. Those reports show that a community route exists; they do not prove that arbitrary Q4 or Q8 files are compatible or safe downloads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add prompt enhancement, 2K, and editing only after the baseline works
&lt;/h2&gt;

&lt;p&gt;Once the base image is stable, extend the graph in this order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Prompt enhancement:&lt;/strong&gt; download &lt;code&gt;qwen3.5_9b_qwen_image_2.1_pe_t2i.int8_convrot.safetensors&lt;/code&gt;, select it, and turn on &lt;code&gt;refine_prompt&lt;/code&gt;. Keep seed, dimensions, and steps fixed when comparing the result.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Higher resolution:&lt;/strong&gt; raise dimensions in stages instead of jumping from 1024 to 2048×2048. Save as PNG when you need an alpha channel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image editing:&lt;/strong&gt; switch to the &lt;a href="https://github.com/Comfy-Org/workflow_templates/blob/main/templates/image_qwen_image_2_1_image_edit.json" rel="noopener noreferrer"&gt;official Image Edit workflow&lt;/a&gt;. Its prompt enhancer uses the &lt;code&gt;..._pe_i2i...&lt;/code&gt; file, not the T2I file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transparent output:&lt;/strong&gt; use the official RGBA/transparent-background prompt wording and save as PNG. First prove an ordinary opaque image so transparency is the only new variable.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Final acceptance checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ComfyUI core, frontend dependencies, and workflow templates are current; no core node is red after restart.&lt;/li&gt;
&lt;li&gt;The diffusion model, main text encoder, and VAE are in their correct folders and visible by exact filename.&lt;/li&gt;
&lt;li&gt;Prompt enhancement is off, batch is 1, and CFG is 1; 8 GB starts at 768, while 12 GB starts at 1024.&lt;/li&gt;
&lt;li&gt;Only one task is queued, and the terminal finishes without a missing-model, missing-node, or OOM error.&lt;/li&gt;
&lt;li&gt;A valid PNG exists under &lt;code&gt;ComfyUI/output/&lt;/code&gt; with the requested dimensions.&lt;/li&gt;
&lt;li&gt;The successful weight combination, resolution, and observed peak memory are recorded before PE, higher resolution, editing, or GGUF is added.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When all six are true, you have a reproducible local Qwen Image 2.1 baseline. Every later optimization should change one element of that successful baseline, not replace it with a large graph whose failure source is impossible to isolate.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bettertoken.ai/en/blog/qwen-image-2-1-comfyui-local-setup/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=qwen-image-2-1-comfyui-local-setup&amp;amp;utm_content=qwen-image-2-1-comfyui-local-setup" rel="noopener noreferrer"&gt;BetterToken blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;BetterToken provides pay-as-you-go access to AI model APIs through&lt;br&gt;
OpenAI-compatible and Anthropic-compatible endpoints — useful if you are wiring&lt;br&gt;
Claude Code, Codex, or your own tooling to a custom base URL.&lt;br&gt;
See the &lt;a href="https://docs.bettertoken.ai/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=qwen-image-2-1-comfyui-local-setup&amp;amp;utm_content=qwen-image-2-1-comfyui-local-setup" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to get started.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>OpenAI API Key Governance: Creation Rules, Ownership, Expiration, and Zero-Downtime Rotation</title>
      <dc:creator>Adela</dc:creator>
      <pubDate>Mon, 28 Sep 2026 06:35:16 +0000</pubDate>
      <link>https://dev.to/bettertoken_ai/openai-api-key-governance-creation-rules-ownership-expiration-and-zero-downtime-rotation-28c</link>
      <guid>https://dev.to/bettertoken_ai/openai-api-key-governance-creation-rules-ownership-expiration-and-zero-downtime-rotation-28c</guid>
      <description>&lt;p&gt;You are about to add expiration rules to OpenAI API keys, but you do not want a policy change to take down an application—or to discover at the next rotation that the required replacement key can no longer be created. You may also be deciding whether production should use service-account keys while developers keep user-owned keys.&lt;/p&gt;

&lt;p&gt;This guide gives you a practical order of operations: choose ownership by workload, set a lifetime your team can actually rotate within, then replace old keys through a controlled overlap. Keep two facts in mind from the start: new creation rules do not change existing keys, and organization restrictions override project settings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the answer: the new controls govern future keys, not old ones
&lt;/h2&gt;

&lt;p&gt;You can treat the September changes as two controls: which new key types may be issued, and how long newly created project keys may remain valid.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Date&lt;/th&gt;
&lt;th&gt;OpenAI update&lt;/th&gt;
&lt;th&gt;Operational meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;September 10, 2026&lt;/td&gt;
&lt;td&gt;Project API keys can be created with expiration dates. Administrators can enforce a maximum key lifetime at the organization or project level.&lt;/td&gt;
&lt;td&gt;Newly issued keys can be required to expire, so teams need a repeatable rotation process before enforcing a short lifetime.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;September 15, 2026&lt;/td&gt;
&lt;td&gt;Organizations and projects can restrict new key creation to &lt;code&gt;service-account keys&lt;/code&gt;, restrict it to &lt;code&gt;user-owned project keys&lt;/code&gt;, or disable all new API key creation.&lt;/td&gt;
&lt;td&gt;Production workloads, individual development, and frozen projects can use different issuance rules.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;September 15, 2026&lt;/td&gt;
&lt;td&gt;Organization restrictions take precedence over project settings.&lt;/td&gt;
&lt;td&gt;A project may tighten the organization rule, but it cannot use its own settings to relax an organization-wide restriction.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;September 15, 2026&lt;/td&gt;
&lt;td&gt;Existing API keys are unaffected by the new creation controls.&lt;/td&gt;
&lt;td&gt;Turning on a rule does not revoke old credentials and does not complete legacy-key cleanup.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two boundaries matter. First, “disable new key creation” is not the same as “revoke every existing key.” Second, the September 10 description applies the maximum-lifetime requirement to newly created keys. Do not assume that an old key will receive a retroactive expiration date unless you verify that behavior in the actual project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate three decisions: who can create, how long keys live, and how they exit
&lt;/h2&gt;

&lt;p&gt;Design these three decisions separately; one Platform switch cannot complete key governance for you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Issuance policy&lt;/strong&gt; determines whether a project can create service-account keys, user-owned project keys, or no new keys at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Expiration policy&lt;/strong&gt; determines whether a new key must expire and the longest lifetime permitted by organization and project rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lifecycle execution&lt;/strong&gt; determines who creates a replacement, where the secret is stored, how applications receive it, how the transition is validated, when the old key is revoked, and how a failed rollout is rolled back.&lt;/p&gt;

&lt;p&gt;The first two can be constrained in the OpenAI Platform. The third still depends on your secret manager, deployment process, observability, ownership model, and incident procedures. Enforcing a maximum lifetime without assigning a rotation owner or allowing enough time for deployment converts a security control into a scheduled outage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose by workload: service accounts for production, user-owned keys for personal development
&lt;/h2&gt;

&lt;p&gt;Prefer a &lt;code&gt;service-account key&lt;/code&gt; for production and shared workloads, a &lt;code&gt;user-owned project key&lt;/code&gt; for local or short-term work, and disabled issuance only for projects that are genuinely frozen or retiring.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workload&lt;/th&gt;
&lt;th&gt;Usually better suited to&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;th&gt;Main risk to manage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Production service, shared backend, scheduled job, team-operated agent&lt;/td&gt;
&lt;td&gt;&lt;code&gt;service-account key&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The credential belongs to the workload rather than one employee, so staff changes do not determine application continuity.&lt;/td&gt;
&lt;td&gt;A single service account used by many unrelated applications creates a large blast radius. Split by project or workload.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local development, short-lived debugging, exploratory script&lt;/td&gt;
&lt;td&gt;&lt;code&gt;user-owned project key&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ownership and individual accountability are clear, and offboarding can include the user's credentials.&lt;/td&gt;
&lt;td&gt;A personal key must not quietly become a shared production dependency.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Archived, decommissioning, or temporarily frozen project&lt;/td&gt;
&lt;td&gt;Disable new key creation&lt;/td&gt;
&lt;td&gt;Prevents the credential inventory from growing while the project is closed or reviewed.&lt;/td&gt;
&lt;td&gt;Freezing issuance too early may block creation of a replacement key needed for rotation or recovery.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A useful test is: &lt;strong&gt;should this application continue running after a particular employee leaves the team?&lt;/strong&gt; If the answer is yes, a production credential generally should not depend on that employee's user account. Conversely, giving every developer a shared service-account key weakens attribution and spreads the same secret across more machines.&lt;/p&gt;

&lt;p&gt;Neither key type is inherently safe on its own. Scope, storage, access control, lifetime, rotation, logging, and revocation determine the practical risk. A long-lived service-account key copied into dozens of workloads remains a serious single point of exposure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Organization policy is the ceiling: projects may tighten it, not relax it
&lt;/h2&gt;

&lt;p&gt;An organization restriction is the ceiling for every project, so verify the next rotation before you apply it broadly.&lt;/p&gt;

&lt;p&gt;Suppose the organization allows only service-account keys. A development project cannot override that rule and start issuing user-owned project keys. A project can usually be made more restrictive within the organization boundary, but it cannot make the organization policy more permissive.&lt;/p&gt;

&lt;p&gt;Before changing an organization-wide rule, perform this sequence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;List all projects and classify them as production, staging, development, testing, temporary, archived, or decommissioning.&lt;/li&gt;
&lt;li&gt;Record the key type each project will need at its &lt;strong&gt;next rotation&lt;/strong&gt;, not merely the types it has today.&lt;/li&gt;
&lt;li&gt;Identify the replacement credential needed by every active workload and confirm that the proposed organization rule permits its creation.&lt;/li&gt;
&lt;li&gt;Rehearse creation, deployment, validation, and revocation in a low-risk project.&lt;/li&gt;
&lt;li&gt;Apply the organization restriction only after the rehearsal proves that normal rotation remains possible.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because existing keys continue to work, an overly strict organization rule may look harmless on the day it is enabled. The failure appears later, when a key nears expiration and the team discovers that policy prevents it from creating the correct replacement. Test the next rotation before relying on the current application's continued success.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do not pick one lifetime for everything: start with the time a real rotation takes
&lt;/h2&gt;

&lt;p&gt;Set the maximum lifetime longer than the full time needed to approve, issue, distribute, deploy, observe, and roll back a replacement.&lt;/p&gt;

&lt;p&gt;For each project class, define at least the following:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Policy field&lt;/th&gt;
&lt;th&gt;Question it must answer&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Maximum lifetime &lt;code&gt;N&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;How long may a newly created key exist from issuance to expiration?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rotation lead time &lt;code&gt;R&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;How long before expiration must replacement work begin?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Primary and backup owner&lt;/td&gt;
&lt;td&gt;Who is responsible, and who acts if that person is unavailable?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Distribution method&lt;/td&gt;
&lt;td&gt;Can the application load a new secret version, or does it require restart/redeployment?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Validation evidence&lt;/td&gt;
&lt;td&gt;Which requests, logs, error rates, and usage signals prove that the new key is carrying traffic?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rollback window&lt;/td&gt;
&lt;td&gt;How long is the old key retained after cutover to allow safe recovery?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exception process&lt;/td&gt;
&lt;td&gt;Who may approve an extension, for how long, and with which compensating controls?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;R&lt;/code&gt; must cover the whole path, including approvals, secret distribution, phased deployment, observation, and rollback. A very short lifetime paired with manual copy-and-paste, cross-time-zone approval, and no backup owner is less reliable than a somewhat longer lifetime backed by automated reminders and a practiced rotation runbook.&lt;/p&gt;

&lt;p&gt;Use the organization-level maximum as a common ceiling. High-risk projects can adopt a shorter project-level limit, but a project should not be able to exceed the organization rule. Production services, personal development, temporary tests, and retiring projects may need different internal standards because their owners, impact, and recovery speed differ.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use this seven-step overlap to rotate without downtime
&lt;/h2&gt;

&lt;p&gt;The safest pattern is to run old and new keys briefly in parallel, then revoke the old key only after real traffic proves the cutover.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Build an inventory of current keys
&lt;/h3&gt;

&lt;p&gt;Record the project, key ownership type, workload, application, environment, accountable owner, secret-storage location, deployment method, creation date, known expiration date, and last observed usage. A key with unknown purpose or owner should enter a high-priority investigation queue; do not start with blind bulk revocation.&lt;/p&gt;

&lt;p&gt;OpenAI's August 4, 2026 changelog entry says the Usage and Costs dashboards, Usage API, and Costs API support filtering and grouping by API key. That key dimension can help establish whether a credential is still generating requests. It is only one piece of evidence: low-frequency batch jobs, disaster-recovery paths, and monthly workflows may remain idle for long periods.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Create a compliant replacement
&lt;/h3&gt;

&lt;p&gt;Create a new key in the intended project, using the ownership type permitted by current organization and project rules. Give it an expiration date that does not exceed the applicable maximum lifetime. Confirm the issuance rule before the maintenance window rather than discovering a conflict during deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Store it as a new secret version
&lt;/h3&gt;

&lt;p&gt;Do not overwrite the only copy of the old value immediately. Keep the old and new secret versions during the controlled transition, with clear states such as “current production,” “rotation candidate,” and “pending revocation.” Do not place keys in source code, container images, deployment tickets, logs, or chat messages.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Shift traffic gradually
&lt;/h3&gt;

&lt;p&gt;Start with one instance, one low-risk job, or a small percentage of traffic. Verify authentication, expected project attribution, permissions, and request behavior before expanding the rollout. If an application reads the key only at startup, schedule restarts and capacity so the rotation itself does not reduce availability.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Observe both application health and key-level usage
&lt;/h3&gt;

&lt;p&gt;Check successful requests, authentication failures, rate-limit errors, latency, and business-level results. At the same time, verify that the new key begins producing the expected usage and that old-key usage falls. A successful deployment event is not proof that traffic has moved.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Keep a time-bounded rollback window
&lt;/h3&gt;

&lt;p&gt;Retain the old key for a predefined observation period after the new key is stable, then revoke it. The window must be long enough to cover delayed workers, multiple regions, and low-frequency tasks, but it must not remain open indefinitely. Permanent dual-key operation doubles the number of valid secrets without delivering a completed rotation.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Revoke, verify, and schedule the next rotation
&lt;/h3&gt;

&lt;p&gt;After revocation, confirm that attempts with the old key fail and that the new key continues to succeed. Update the inventory, on-call notes, owner, expiration date, and next rotation deadline. Do not wait until the final days of the new key's life to rediscover the process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Legacy keys do not become compliant automatically: migrate them by risk
&lt;/h2&gt;

&lt;p&gt;After you enable the new rules, you still need a separate migration queue for old keys because they keep their existing ownership and lifetime.&lt;/p&gt;

&lt;p&gt;Create a separate migration queue and prioritize it by risk:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;credentials known to have appeared in source code, tickets, logs, or chat;&lt;/li&gt;
&lt;li&gt;keys whose owner or purpose cannot be identified;&lt;/li&gt;
&lt;li&gt;user-owned keys associated with people who left or changed roles;&lt;/li&gt;
&lt;li&gt;keys shared by multiple production applications and therefore difficult to revoke independently;&lt;/li&gt;
&lt;li&gt;broad-scope or high-impact keys;&lt;/li&gt;
&lt;li&gt;keys with a clear owner, a single workload, and a tested replacement path.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do not measure success by revoking every old key on the same date. A safer completion criterion is that each legacy key has a known workload map, an approved replacement, cutover evidence, and a revocation deadline. For a key that cannot yet be migrated, document the exact blocker, owner, compensating control, and expiry of the exception. “Legacy system” is not a permanent risk treatment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your internal policy needs at least these 11 fields
&lt;/h2&gt;

&lt;p&gt;An executable policy must name the rule, owner, validation evidence, rollback window, and revocation condition—not just a maximum lifetime.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Policy item&lt;/th&gt;
&lt;th&gt;What to record&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Scope&lt;/td&gt;
&lt;td&gt;Organization, project, environment, and workload classes covered by the policy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Allowed new-key type&lt;/td&gt;
&lt;td&gt;Service-account only, user-owned project only, or no new keys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rationale&lt;/td&gt;
&lt;td&gt;Continuity, individual accountability, project freeze, or another documented reason&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maximum lifetime&lt;/td&gt;
&lt;td&gt;Organization ceiling and any stricter project limit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rotation lead time&lt;/td&gt;
&lt;td&gt;When an alert or work item must be created before expiration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secret storage&lt;/td&gt;
&lt;td&gt;Approved secret manager and access roles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;Canary or phased method, restart requirements, and rollback procedure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Evidence&lt;/td&gt;
&lt;td&gt;Successful requests, error metrics, key-level usage, and old-key traffic reaching zero&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Revocation condition&lt;/td&gt;
&lt;td&gt;New key stable, delayed jobs covered, rollback window closed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exception approval&lt;/td&gt;
&lt;td&gt;Approver, reason, compensating control, and exception expiration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audit trail&lt;/td&gt;
&lt;td&gt;Creation, policy change, deployment, revocation, and ownership changes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Assign long-term accountability to a workload or team role, while still naming the person executing the current rotation. “The platform team owns it” is not operational unless the policy also defines an on-call path, deadline, and escalation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before enforcement, rehearse the next rotation
&lt;/h2&gt;

&lt;p&gt;Enable organization or project restrictions only after you can answer every item below and complete a low-risk rehearsal.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;every active application maps to a specific project and credential;&lt;/li&gt;
&lt;li&gt;each project's next required key type is known;&lt;/li&gt;
&lt;li&gt;the organization rule will not prevent a critical workload from creating its replacement;&lt;/li&gt;
&lt;li&gt;production does not depend on one employee's personal credential;&lt;/li&gt;
&lt;li&gt;the secret store supports versioning or another reliable rollback mechanism;&lt;/li&gt;
&lt;li&gt;the application has been tested to load a new secret, including any restart requirement;&lt;/li&gt;
&lt;li&gt;the team can observe usage or cost by API key and has accounted for low-frequency jobs;&lt;/li&gt;
&lt;li&gt;primary and backup rotation owners are assigned;&lt;/li&gt;
&lt;li&gt;expiration alerts arrive early enough to complete the runbook;&lt;/li&gt;
&lt;li&gt;old-key revocation criteria are explicit, so overlap does not become permanent; and&lt;/li&gt;
&lt;li&gt;each unresolved legacy key has a concrete blocker, owner, and deadline.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Will a new creation restriction immediately break existing applications?
&lt;/h3&gt;

&lt;p&gt;According to OpenAI's September 15, 2026 changelog entry, existing API keys are unaffected by the new creation governance controls. Changing which new keys may be created does not automatically revoke the credentials already used by applications. The rule can still affect the next rotation, so replacement-key creation should be rehearsed in advance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does a maximum lifetime retroactively expire old keys?
&lt;/h3&gt;

&lt;p&gt;The September 10 update describes the maximum lifetime as a requirement for newly created keys. Do not assume it retroactively adds expiration dates to legacy credentials. Verify the actual key details and migrate old keys through a separate process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can a project administrator relax an organization-level restriction?
&lt;/h3&gt;

&lt;p&gt;No. The release note says organization restrictions take precedence over project settings. Project policy must remain within the organization boundary.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should an organization allow only service-account keys?
&lt;/h3&gt;

&lt;p&gt;Use service-account keys first for production services, shared backends, scheduled jobs, and team-operated agents. Use user-owned project keys first for local development and short-lived exploration. An organization-wide service-account-only rule makes sense only when nearly every project fits the first group and development projects already have a workable alternative.&lt;/p&gt;

&lt;h3&gt;
  
  
  When should a project disable all new key creation?
&lt;/h3&gt;

&lt;p&gt;Typical cases include an archived or decommissioning project, or a temporary freeze during a security investigation. Confirm first that the project will not need a replacement key for rotation or recovery; otherwise the freeze can obstruct the response it was meant to support.&lt;/p&gt;

&lt;h3&gt;
  
  
  What proves that an old key is safe to revoke?
&lt;/h3&gt;

&lt;p&gt;Use combined evidence: rollout state, successful requests with the new key, error monitoring, key-level usage, execution of low-frequency jobs, and completion of the rollback window. A short interval with no traffic is usually insufficient on its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do first
&lt;/h2&gt;

&lt;p&gt;Start with three actions: record the key type each project will need at its next rotation, complete one overlap rotation in a low-risk project, and only then enforce organization and project restrictions.&lt;/p&gt;

&lt;p&gt;The order matters. If you set the ceiling first, current applications may keep working while the policy quietly blocks the replacement key you will need later. Prove that the next rotation works before you tighten the rules.&lt;/p&gt;

&lt;p&gt;Official source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developers.openai.com/api/docs/changelog" rel="noopener noreferrer"&gt;OpenAI API Changelog: September 10 and September 15, 2026 updates&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bettertoken.ai/en/blog/openai-api-key-governance-expiration/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=openai-api-klyuchi-pravila-sozdaniya-i-srok&amp;amp;utm_content=openai-api-key-governance-expiration" rel="noopener noreferrer"&gt;BetterToken blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;BetterToken provides pay-as-you-go access to AI model APIs through&lt;br&gt;
OpenAI-compatible and Anthropic-compatible endpoints — useful if you are wiring&lt;br&gt;
Claude Code, Codex, or your own tooling to a custom base URL.&lt;br&gt;
See the &lt;a href="https://docs.bettertoken.ai/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=openai-api-klyuchi-pravila-sozdaniya-i-srok&amp;amp;utm_content=openai-api-key-governance-expiration" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to get started.&lt;/p&gt;

</description>
      <category>api</category>
      <category>ai</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>GitHub Copilot App Local Sandbox: Setup and Verification</title>
      <dc:creator>Adela</dc:creator>
      <pubDate>Mon, 28 Sep 2026 06:33:14 +0000</pubDate>
      <link>https://dev.to/bettertoken_ai/github-copilot-app-local-sandbox-setup-and-verification-37ib</link>
      <guid>https://dev.to/bettertoken_ai/github-copilot-app-local-sandbox-setup-and-verification-37ib</guid>
      <description>&lt;p&gt;You enable sandboxing, but an existing session keeps its old permissions—or the agent repeatedly asks for access to install packages, reach a local server, or push a branch. The usual problem is not simply whether the sandbox is on; it is how project defaults, session overrides, and the separate file, network, and credential controls interact.&lt;/p&gt;

&lt;p&gt;By the end of this guide, you can choose a starting policy for a local repository or worktree, apply changes to the correct session, and verify the boundaries with dummy data. The shortest path is: confirm the session type → enable &lt;code&gt;Sandbox new sessions&lt;/code&gt; → narrow the three permission areas → start or restart the session → run safe checks.&lt;/p&gt;

&lt;p&gt;GitHub announced this feature on September 23, 2026, and it remains in public preview, so the interface and behavior may change. Keep three boundaries in mind: local sandboxing is off by default, policy is configured per project, and a host that cannot enforce the requested policy fails the sandboxed shell instead of silently running the command without protection.&lt;/p&gt;

&lt;h2&gt;
  
  
  First confirm that your session is covered
&lt;/h2&gt;

&lt;p&gt;Only local repository and local worktree sessions use this project policy. Cloud sandboxes, remote hosts, and GitHub Copilot CLI follow different isolation or configuration paths, so check the table before changing settings that your target session will never read.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Session type&lt;/th&gt;
&lt;th&gt;Covered?&lt;/th&gt;
&lt;th&gt;Boundary to remember&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Local repository session&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Uses the sandbox settings for the current project&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local working-tree session&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;A working tree separates branches and files, but does not restrict access elsewhere on the machine; the sandbox provides that permission boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloud sandbox session&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Uses the cloud session's own isolation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Session running on a remote host&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;The local project policy is not applied to the remote host&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Copilot CLI&lt;/td&gt;
&lt;td&gt;Configured separately&lt;/td&gt;
&lt;td&gt;Copilot app and Copilot CLI sandbox settings do not replace each other&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Enterprise-managed settings can make the effective policy more restrictive than the policy requested in project settings. The project page therefore describes what the app requests, not necessarily the maximum access an organization will permit.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to enable sandboxing for new sessions
&lt;/h2&gt;

&lt;p&gt;To protect later local sessions, turn on &lt;code&gt;Sandbox new sessions&lt;/code&gt; and then start a new session; changing the switch does not update one that is already running. Use these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the GitHub Copilot app settings.&lt;/li&gt;
&lt;li&gt;Select the project you want to configure.&lt;/li&gt;
&lt;li&gt;Find the &lt;code&gt;Sandbox&lt;/code&gt; section.&lt;/li&gt;
&lt;li&gt;Turn on &lt;code&gt;Sandbox new sessions&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Start a new local session.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The switch affects only sessions created afterward. It does not modify a session that is already running. Later changes to file, network, or credential policy also apply only to new sessions or after a session restart.&lt;/p&gt;

&lt;p&gt;To keep the current conversation history while reloading policy, enter &lt;code&gt;/restart-session&lt;/code&gt; in the existing session.&lt;/p&gt;

&lt;p&gt;GitHub recommends starting with the default policy for most projects. It supports common development work such as installing dependencies, connecting to a local development server, pushing a branch, and creating a pull request. Tighten it when the project sits next to sensitive folders, does not need network access, or should not use your credentials.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to limit files, network, and credentials separately
&lt;/h2&gt;

&lt;p&gt;Treat these as three independent controls: restricting files does not disable credentials, and disabling credentials does not protect a sensitive directory that remains readable. Tighten each area according to the task instead of turning everything off at once.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Filesystem: decide what can be read and changed
&lt;/h3&gt;

&lt;p&gt;Start with the smallest file scope: keep workspace read/write access and add other paths only when the task truly needs them. A sandboxed session can read and write its workspace and current working directory by default, and project settings add three lists:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Additional read/write&lt;/code&gt;: extra folders that agent-run tools may read and modify.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Additional read-only&lt;/code&gt;: extra folders they may read but not modify.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Denied&lt;/code&gt;: folders they may not access.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A more-specific denied folder remains denied even when a broader parent folder has read or write access. Prefer granting the smallest necessary path instead of opening an entire home directory and depending on many exceptions.&lt;/p&gt;

&lt;p&gt;Windows has an important enforcement boundary. You can save a denied path in project settings, but if the active Windows sandbox capabilities cannot guarantee the denial, the command fails with an &lt;code&gt;unsupported-policy&lt;/code&gt; message. It does not continue with the path exposed and does not automatically disable the sandbox.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Network: separate the internet from the local network
&lt;/h3&gt;

&lt;p&gt;If the task installs dependencies or uses a local development server, do not disable both network paths automatically; decide separately whether outbound internet and the local network are needed. Sandboxed sessions can reach both by default, and you can control:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Outbound internet&lt;/code&gt;: access to GitHub, package registries, and other internet services.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Local network&lt;/code&gt;: loopback and local-network connections, including local development servers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Network restrictions can affect dependency installation, API calls, preview servers, and any other tool that needs a connection. Treat network denial as a task trade-off, not a cost-free switch.&lt;/p&gt;

&lt;p&gt;Linux has a specific limitation: the sandbox cannot independently control local-network access for spawned processes such as shell commands and local MCP or LSP servers. The setting still applies to in-process operations such as web requests and remote MCP connections. On Linux, verify both in-process and spawned-process behavior rather than testing only one path.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Credentials: control Git and GitHub CLI separately
&lt;/h3&gt;

&lt;p&gt;For code reading or offline analysis, disable Git and GitHub CLI credentials first; enable them only when the task must push a branch or create a pull request. Authenticated Git and GitHub CLI operations are available inside the sandbox by default, and you can turn off:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Git credentials&lt;/code&gt;: authenticated HTTPS Git operations.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GitHub CLI credentials&lt;/code&gt;: authentication used by GitHub CLI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Disabling them can prevent actions such as pushing a branch or creating a pull request. Filesystem and credential policy are separate boundaries: even with credentials disabled, use filesystem rules to protect directories that contain keys, configuration, or other sensitive material.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to change the project, the current session, or one operation
&lt;/h2&gt;

&lt;p&gt;Change project settings when future sessions should inherit the rule, use &lt;code&gt;/sandbox on&lt;/code&gt; or &lt;code&gt;/sandbox off&lt;/code&gt; for the current session, and run &lt;code&gt;/restart-session&lt;/code&gt; after a project-policy change that the active session must reload.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;When it takes effect&lt;/th&gt;
&lt;th&gt;Effect on other sessions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Change project &lt;code&gt;Sandbox&lt;/code&gt; settings&lt;/td&gt;
&lt;td&gt;New sessions or a restarted session&lt;/td&gt;
&lt;td&gt;Changes the default inherited by later sessions in that project&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enter &lt;code&gt;/sandbox on&lt;/code&gt; in an active local session&lt;/td&gt;
&lt;td&gt;Immediately, as a persistent override for that session&lt;/td&gt;
&lt;td&gt;Does not change the project default for other sessions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enter &lt;code&gt;/sandbox off&lt;/code&gt; in an active local session&lt;/td&gt;
&lt;td&gt;Immediately disables sandboxing for that session&lt;/td&gt;
&lt;td&gt;Does not change other sessions; commands then have the same file, network, and credential access as your user account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enter &lt;code&gt;/sandbox on&lt;/code&gt; or &lt;code&gt;/sandbox off&lt;/code&gt; before a session starts&lt;/td&gt;
&lt;td&gt;Changes the project default inherited by new sessions&lt;/td&gt;
&lt;td&gt;Affects sessions started from that default afterward&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enter &lt;code&gt;/restart-session&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Restarts the current session, keeps its history, and reloads policy&lt;/td&gt;
&lt;td&gt;Does not itself edit project policy&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When a tool needs access that policy does not allow, the app may show &lt;code&gt;Run outside the sandbox?&lt;/code&gt;. Depending on the effective policy, you can cancel, run that operation once outside the sandbox, or disable sandboxing for the rest of the current session. An enterprise owner can prevent users from running tools outside the sandbox.&lt;/p&gt;

&lt;p&gt;Disabling through this prompt does not rewrite the project default or the existing session override. The temporary state ends when the session restarts or reattaches. After &lt;code&gt;Sandbox off for this session&lt;/code&gt; appears, &lt;code&gt;Re-enable sandbox&lt;/code&gt; turns it back on.&lt;/p&gt;

&lt;p&gt;A safer decision order is to cancel first and understand why the command needs more access. If the access is a recurring requirement, narrowly update project policy and restart. Use a one-time run outside the sandbox only after reviewing the command, its arguments, and its impact. For an unfamiliar repository or a command assembled dynamically from a prompt, avoid disabling the sandbox for the whole session merely for convenience.&lt;/p&gt;

&lt;h2&gt;
  
  
  If the host cannot enforce the policy, the command stops
&lt;/h2&gt;

&lt;p&gt;When the operating system cannot enforce a requested rule, the safe result is a failed command—not an automatic downgrade to unsandboxed execution.&lt;/p&gt;

&lt;p&gt;The GitHub Copilot app accepts sandbox settings before it knows whether the operating system can enforce all of them. Support is checked when the first sandboxed shell starts.&lt;/p&gt;

&lt;p&gt;If the host cannot enforce the requested policy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The shell reports an &lt;code&gt;unsupported-platform&lt;/code&gt; or &lt;code&gt;unsupported-policy&lt;/code&gt; message.&lt;/li&gt;
&lt;li&gt;The command does not continue unsandboxed.&lt;/li&gt;
&lt;li&gt;If the app shows &lt;code&gt;Sandbox unavailable&lt;/code&gt;, fix the reported problem and select &lt;code&gt;Retry sandbox&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is fail-closed behavior, not best-effort execution. Saving settings successfully therefore does not prove that policy is active on the current machine. Start at least one sandboxed shell, confirm that no unsupported message appears, and run a minimal verification.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to verify the policy with dummy data
&lt;/h2&gt;

&lt;p&gt;GitHub documents the behavior the policy should enforce, but only a check on your own machine can confirm that this operating-system and policy combination works. The procedure below uses disposable folders and dummy files, so you do not need to touch real keys or production configuration.&lt;/p&gt;

&lt;p&gt;Create disposable test folders outside the workspace and place only dummy files in them. Do not test with real SSH keys, cloud credentials, or production configuration.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Safe procedure&lt;/th&gt;
&lt;th&gt;Expected policy behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;New-session inheritance&lt;/td&gt;
&lt;td&gt;Enable &lt;code&gt;Sandbox new sessions&lt;/code&gt;, then create a new local session&lt;/td&gt;
&lt;td&gt;The new session uses project policy; an old session does not change automatically&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Applying a policy edit&lt;/td&gt;
&lt;td&gt;Change one rule and enter &lt;code&gt;/restart-session&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;The session restarts, keeps history, and reloads policy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read-only folder&lt;/td&gt;
&lt;td&gt;Add a disposable folder to &lt;code&gt;Additional read-only&lt;/code&gt;, read a dummy file, then try to create a test file&lt;/td&gt;
&lt;td&gt;Reading should work; modification should be blocked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Denied folder&lt;/td&gt;
&lt;td&gt;Add another disposable folder to &lt;code&gt;Denied&lt;/code&gt;, then try to list or read a dummy file&lt;/td&gt;
&lt;td&gt;Access should be blocked even if a broader parent path is allowed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Internet access&lt;/td&gt;
&lt;td&gt;Turn off &lt;code&gt;Outbound internet&lt;/code&gt; and make a harmless connection check&lt;/td&gt;
&lt;td&gt;The external connection should fail; turn it back on and compare&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local network&lt;/td&gt;
&lt;td&gt;Turn off &lt;code&gt;Local network&lt;/code&gt; and connect to a disposable local test service&lt;/td&gt;
&lt;td&gt;Access should follow platform capabilities; account for the Linux spawned-process limitation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Git credentials&lt;/td&gt;
&lt;td&gt;Turn off &lt;code&gt;Git credentials&lt;/code&gt; and run a non-mutating authentication check in a test repository&lt;/td&gt;
&lt;td&gt;Authenticated HTTPS Git operations may be unavailable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub CLI credentials&lt;/td&gt;
&lt;td&gt;Turn off &lt;code&gt;GitHub CLI credentials&lt;/code&gt; and run a non-mutating check such as &lt;code&gt;gh auth status&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;GitHub CLI should not receive the previous authentication capability; exact errors can vary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fail-closed behavior&lt;/td&gt;
&lt;td&gt;If &lt;code&gt;unsupported-platform&lt;/code&gt; or &lt;code&gt;unsupported-policy&lt;/code&gt; appears, check that a target dummy file was not created&lt;/td&gt;
&lt;td&gt;The command should not continue unsandboxed or cause the intended side effect&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Delete the test folders afterward and restore only the minimum permissions the project actually needs. Do not prove a denial rule by attempting to access a real sensitive directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which starting policy fits your task
&lt;/h2&gt;

&lt;p&gt;Everyday development, an unfamiliar repository, and offline analysis should not share one policy. Keep the capabilities required for normal development, start tighter for unfamiliar code, and disable network and credentials first for offline work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Everyday development
&lt;/h3&gt;

&lt;p&gt;Enable the sandbox, retain the default network and credential capabilities, add only required external folders, and explicitly deny neighboring sensitive directories. This fits normal work that installs dependencies, runs local services, pushes branches, and opens pull requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reviewing an unfamiliar repository
&lt;/h3&gt;

&lt;p&gt;Give read/write access only to the workspace, make extra reference material read-only, disable Git and GitHub CLI credentials by default, and keep outbound internet off until you understand where the dependencies come from. When temporary access is necessary, open one specific capability rather than immediately using &lt;code&gt;/sandbox off&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Local offline analysis
&lt;/h3&gt;

&lt;p&gt;Disable outbound internet and unneeded credentials, keeping only necessary file access. If local-network isolation also matters, verify spawned-process behavior separately on Linux instead of assuming that one UI switch controls every process identically.&lt;/p&gt;

&lt;p&gt;These are not GitHub-named presets. They are starting points assembled from the permission dimensions GitHub exposes. Match the final policy to the repository, operating system, enterprise rules, and actual task.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistakes that make the policy ineffective or too broad
&lt;/h2&gt;

&lt;p&gt;The most common errors are treating “settings saved” as “policy enforced” and disabling the whole sandbox after the first denial. The seven cases below either invalidate your test or grant more access than the task needs.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Treating a working tree as a security boundary.&lt;/strong&gt; It separates concurrent branches and files; it does not prevent commands from reaching other locations on the machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Editing policy and continuing to test an old session.&lt;/strong&gt; Project changes are not retroactive; start a new session or use &lt;code&gt;/restart-session&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assuming the app and CLI share one sandbox.&lt;/strong&gt; They are configured separately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treating a successful save as proof of host support.&lt;/strong&gt; Enforcement support is checked only when the first sandboxed shell starts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overlooking what &lt;code&gt;/sandbox off&lt;/code&gt; means.&lt;/strong&gt; Agent-run commands then receive the same access scope as your user account.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assuming network behavior is identical on every platform.&lt;/strong&gt; Linux has a documented local-network limitation for spawned processes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using a broad bypass whenever access is denied.&lt;/strong&gt; Usually it is safer to confirm the need, make the smallest policy adjustment, and restart the session.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What to do next
&lt;/h2&gt;

&lt;p&gt;First confirm that you are using a local repository or local worktree session, then turn on &lt;code&gt;Sandbox new sessions&lt;/code&gt;. For everyday development, begin with the default policy and keep only the directories, network paths, and credentials the task needs; for unfamiliar code or offline analysis, start with the tighter scenario policy and add one capability at a time.&lt;/p&gt;

&lt;p&gt;After changing project policy, start a new session or run &lt;code&gt;/restart-session&lt;/code&gt;, then verify read-only, denied, network, and credential boundaries with disposable data. If you see &lt;code&gt;unsupported-platform&lt;/code&gt;, &lt;code&gt;unsupported-policy&lt;/code&gt;, or &lt;code&gt;Sandbox unavailable&lt;/code&gt;, resolve the compatibility issue instead of using &lt;code&gt;/sandbox off&lt;/code&gt; and mistaking an unsandboxed result for a successful sandbox test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Official references
&lt;/h2&gt;

&lt;p&gt;Use these GitHub pages before and after configuration to confirm the current interface, scope, and failure behavior.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/copilot/how-tos/github-copilot-app/configure-local-sandboxing" rel="noopener noreferrer"&gt;Configuring local sandboxing in the GitHub Copilot app&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.blog/changelog/2026-09-23-local-sandboxing-in-the-github-copilot-app/" rel="noopener noreferrer"&gt;Local sandboxing in the GitHub Copilot app — GitHub Changelog, September 23, 2026&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bettertoken.ai/en/blog/github-copilot-app-local-sandbox-setup/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=github-copilot-app-lokalnaya-pesochnitsa-nastroyka&amp;amp;utm_content=github-copilot-app-local-sandbox-setup" rel="noopener noreferrer"&gt;BetterToken blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;BetterToken provides pay-as-you-go access to AI model APIs through&lt;br&gt;
OpenAI-compatible and Anthropic-compatible endpoints — useful if you are wiring&lt;br&gt;
Claude Code, Codex, or your own tooling to a custom base URL.&lt;br&gt;
See the &lt;a href="https://docs.bettertoken.ai/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=github-copilot-app-lokalnaya-pesochnitsa-nastroyka&amp;amp;utm_content=github-copilot-app-local-sandbox-setup" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to get started.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Russian neural text-to-speech: how to choose by pronunciation, pauses, and cost</title>
      <dc:creator>Adela</dc:creator>
      <pubDate>Mon, 28 Sep 2026 06:31:12 +0000</pubDate>
      <link>https://dev.to/bettertoken_ai/russian-neural-text-to-speech-how-to-choose-by-pronunciation-pauses-and-cost-1o2d</link>
      <guid>https://dev.to/bettertoken_ai/russian-neural-text-to-speech-how-to-choose-by-pronunciation-pauses-and-cost-1o2d</guid>
      <description>&lt;p&gt;You may have sampled several Russian TTS services already: every demo sounds polished, but your own surnames, amounts, abbreviations, and long sentences can expose stress and pause errors. By the end of this guide, you will know which pair to test first, how to blind-rate one script, and how to include retries and rejected takes in the cost of each accepted minute.&lt;/p&gt;

&lt;p&gt;Start with this shortlist: for long-form Russian audio, test &lt;code&gt;gemini-3.8-flash-tts&lt;/code&gt; against ElevenLabs Multilingual v2; for high-volume short prompts, test &lt;code&gt;gemini-3.8-flash-lite-tts&lt;/code&gt; against ElevenLabs Flash/Turbo; for telephony and IVR, start with Gemini and ElevenLabs because both document direct μ-law and A-law output. Add &lt;code&gt;gpt-4o-mini-tts&lt;/code&gt; when you already use the OpenAI audio stack or need its streaming and export formats, but make it pass your Russian script because the built-in voices are optimized for English.&lt;/p&gt;

&lt;p&gt;Public documentation does not provide an independent same-script listening comparison across these services. Use the official capabilities and prices below to choose a first round, then let your own script, blinded listening, and actual bill decide; models, formats, and prices were checked on &lt;strong&gt;September 24, 2026&lt;/strong&gt; and should be rechecked before production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Filter by Russian support, control, format, and billing first
&lt;/h2&gt;

&lt;p&gt;Reject any option that fails one of these four gates before you spend time listening.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Russian is explicitly documented.&lt;/strong&gt; Language support qualifies a model for testing; it does not prove correct stress or natural delivery.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The control method fits your workflow.&lt;/strong&gt; You need to know where pace, tone, and pauses are specified—and whether those instructions can accidentally be spoken.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The output format fits your pipeline.&lt;/strong&gt; WAV or MP3 may be enough for editing, raw PCM can matter for streaming, and telephony often needs μ-law or A-law.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The billing unit is measurable.&lt;/strong&gt; A service may charge by characters, text tokens, audio tokens, or seconds. “From $X per minute” is not a production budget until retries and rejected takes are included.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Use the table to choose your first test pair
&lt;/h3&gt;

&lt;p&gt;All three services can enter a Russian test, but they differ in control, output formats, and billing. Use the table to decide what is worth testing first—not to declare a sound-quality winner.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Models and Russian support&lt;/th&gt;
&lt;th&gt;Delivery controls&lt;/th&gt;
&lt;th&gt;Export formats&lt;/th&gt;
&lt;th&gt;Price evidence checked on 2026-09-24&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Google Gemini&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;gemini-3.8-flash-tts&lt;/code&gt; and &lt;code&gt;gemini-3.8-flash-lite-tts&lt;/code&gt;; Russian is listed for both&lt;/td&gt;
&lt;td&gt;Sustained delivery in &lt;code&gt;speech_metadata.style&lt;/code&gt;; point-in-time pauses and vocal events through tags such as &lt;code&gt;&amp;lt;short pause&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Unary requests return 24 kHz mono 16-bit WAV; streaming returns raw PCM; μ-law and A-law are also available&lt;/td&gt;
&lt;td&gt;Standard output through 2026-12-31 is $9 or $6 per 1M audio tokens; audio uses 25 tokens per second&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;gpt-4o-mini-tts&lt;/code&gt;, plus &lt;code&gt;tts-1&lt;/code&gt; and &lt;code&gt;tts-1-hd&lt;/code&gt;; Russian appears in the supported-language list&lt;/td&gt;
&lt;td&gt;Instructions can control accent, speed, intonation, emotional range, tone, and whispering&lt;/td&gt;
&lt;td&gt;MP3, Opus, AAC, FLAC, WAV, and 24 kHz raw PCM; streaming is supported&lt;/td&gt;
&lt;td&gt;The official TTS guide does not list the current rate; record the live pricing-page or invoice amount on the test date&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ElevenLabs&lt;/td&gt;
&lt;td&gt;Eleven v3, v3 Conversational, Multilingual v2, and Flash/Turbo; Russian is listed for Multilingual v2 and Flash v2.5&lt;/td&gt;
&lt;td&gt;Textual context, Stability, and Similarity; &lt;code&gt;seed&lt;/code&gt; can improve consistency; &lt;code&gt;previous_text&lt;/code&gt; / &lt;code&gt;next_text&lt;/code&gt; can connect chunks&lt;/td&gt;
&lt;td&gt;MP3, PCM, μ-law, A-law, and Opus&lt;/td&gt;
&lt;td&gt;$0.10 per 1,000 characters for v3 and Multilingual; $0.05 for v3 Conversational and Flash/Turbo; taxes excluded&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Vendor phrases such as “studio-grade,” “most stable for long-form,” or “highest quality” are starting points, not evidence that a model will handle your names, numbers, or terminology. Keep a candidate only after the same Russian script is accurate, stable across three runs, and affordable to correct.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use a test script that mirrors your real workload
&lt;/h2&gt;

&lt;p&gt;Do not test with a random paragraph or a vendor’s showcase sentence. Use a miniature version of your actual workload. A course script should include terminology and long explanations; an e-commerce flow should include SKUs, amounts, and addresses; an IVR script should include short commands, names, and numbers.&lt;/p&gt;

&lt;p&gt;The first version should be neutral, with no provider-specific tags and no manual edits. The following Russian passage is a useful starting point. It deliberately remains in Russian in every localized version of this article because Russian pronunciation is what the test is meant to measure:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Добрый вечер! Заказ № 1847 готов к выдаче 5 октября в 18:30.&lt;br&gt;&lt;br&gt;
Сумма — 1 250 рублей 50 копеек. Код подтверждения: А-7-Б-9.&lt;br&gt;&lt;br&gt;
В письме указаны адреса example.ru/support и &lt;a href="mailto:support@example.ru"&gt;support@example.ru&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
Сначала откройте за́мок, затем осмотрите старинный замо́к.&lt;br&gt;&lt;br&gt;
Компания ООО «Северный ветер» выпустила API для CRM и IoT.&lt;br&gt;&lt;br&gt;
Анна сказала: «Подождите… Я проверю данные и перезвоню через две минуты».&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This passage probes several failure modes at once:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dates, time, money, decimals, and a character sequence;&lt;/li&gt;
&lt;li&gt;Russian abbreviations, Latin letters, a URL, and an email address;&lt;/li&gt;
&lt;li&gt;two readings of the same spelling with different stress;&lt;/li&gt;
&lt;li&gt;short and long pauses;&lt;/li&gt;
&lt;li&gt;the transition from narration to quoted speech;&lt;/li&gt;
&lt;li&gt;Russian names and an organization name.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add five to ten terms that are critical to your product: expert surnames, city names, brands, medical or legal language, or technical vocabulary. Store a reference reading next to the script that specifies the intended stress, number expansion, and abbreviation handling. Without an answer key, reviewers quickly end up debating taste rather than correctness.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run three untuned baselines to expose instability
&lt;/h2&gt;

&lt;p&gt;For each candidate, freeze the model, voice, speed, format, and all other settings. Generate the exact same uncorrected script once, then repeat it twice with identical settings. Three outputs are not meant to give you three chances to cherry-pick the best take; they reveal how much the result varies.&lt;/p&gt;

&lt;p&gt;Rename files A1, A2, A3, B1, and so on, so listeners cannot see the provider. Ask at least two native Russian speakers to score them independently. For specialist material, at least one reviewer should understand the domain vocabulary.&lt;/p&gt;

&lt;p&gt;A simple 0–2 rubric works well:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criterion&lt;/th&gt;
&lt;th&gt;0 points&lt;/th&gt;
&lt;th&gt;1 point&lt;/th&gt;
&lt;th&gt;2 points&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Pronunciation and stress&lt;/td&gt;
&lt;td&gt;An error changes meaning or forces a new take&lt;/td&gt;
&lt;td&gt;A noticeable but repairable issue&lt;/td&gt;
&lt;td&gt;All critical words are correct&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Numbers, dates, abbreviations&lt;/td&gt;
&lt;td&gt;Data are omitted or distorted&lt;/td&gt;
&lt;td&gt;The source text must be rewritten&lt;/td&gt;
&lt;td&gt;No correction is needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pauses and phrase boundaries&lt;/td&gt;
&lt;td&gt;Meaningful units run together&lt;/td&gt;
&lt;td&gt;Usable rhythm, but editing is needed&lt;/td&gt;
&lt;td&gt;Pauses match the intended delivery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stability across three runs&lt;/td&gt;
&lt;td&gt;Words, timbre, or rhythm change materially&lt;/td&gt;
&lt;td&gt;Minor variation&lt;/td&gt;
&lt;td&gt;Predictable output&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audio artifacts&lt;/td&gt;
&lt;td&gt;Clicks, repetitions, truncation, or clear failure&lt;/td&gt;
&lt;td&gt;Small defects&lt;/td&gt;
&lt;td&gt;No obvious defect&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Readiness for use&lt;/td&gt;
&lt;td&gt;Both regeneration and editing are required&lt;/td&gt;
&lt;td&gt;One of them is required&lt;/td&gt;
&lt;td&gt;The file can be accepted immediately&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Define hard failure conditions before adding scores. A misread amount can disqualify an IVR recording even if the voice is pleasant. A rare-name error in an audiobook may be repairable, while voice drift across chapters may not be.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use the second round to fix critical errors, not to tune forever
&lt;/h2&gt;

&lt;p&gt;The baseline shows what happens without assistance. The second round should reveal how much work it takes to correct the output—not how long you can keep tuning until one lucky generation appears.&lt;/p&gt;

&lt;h3&gt;
  
  
  Google Gemini TTS
&lt;/h3&gt;

&lt;p&gt;Gemini 3.8 treats the &lt;code&gt;text&lt;/code&gt; field as a verbatim transcript. Sustained directions such as “calm, slow, and confident” belong in &lt;code&gt;speech_metadata.style&lt;/code&gt; so they are not read aloud. A point-in-time pause can be placed in the transcript as &lt;code&gt;&amp;lt;short pause&amp;gt;&lt;/code&gt;. Google’s documentation also recommends English inline tag names even when the transcript is not in English.&lt;/p&gt;

&lt;p&gt;A unary request returns a complete WAV file with a RIFF header: 24 kHz, mono, 16-bit signed little-endian PCM. A streaming request returns headerless raw &lt;code&gt;audio/l16&lt;/code&gt; with the same basic audio parameters by default. Telephony workflows can request &lt;code&gt;audio/mulaw&lt;/code&gt; or &lt;code&gt;audio/alaw&lt;/code&gt; and specify a sample rate.&lt;/p&gt;

&lt;p&gt;Both 3.8 models share the same API schema. Google positions &lt;code&gt;gemini-3.8-flash-tts&lt;/code&gt; for higher fidelity, expressive control, difficult pronunciation, and long-form work, while &lt;code&gt;gemini-3.8-flash-lite-tts&lt;/code&gt; is positioned for high-volume, low-latency, lower-cost speech. Treat those as vendor guidance until your Russian test confirms them.&lt;/p&gt;

&lt;h3&gt;
  
  
  OpenAI Speech API
&lt;/h3&gt;

&lt;p&gt;With &lt;code&gt;gpt-4o-mini-tts&lt;/code&gt;, instructions can control accent, speed, intonation, emotional range, tone, and whispering. Russian is in the supported-language list, but the documentation explicitly says the built-in voices are optimized for English. That makes a Russian script test essential, especially for regional delivery, surnames, and specialist terms.&lt;/p&gt;

&lt;p&gt;The API returns MP3 by default and also supports Opus, AAC, FLAC, WAV, and 24 kHz raw PCM. The guide recommends WAV or PCM for faster response, and streaming lets playback begin before the whole file is complete.&lt;/p&gt;

&lt;p&gt;There is also a product requirement to account for: OpenAI requires clear disclosure to end users that the voice is AI-generated rather than human.&lt;/p&gt;

&lt;h3&gt;
  
  
  ElevenLabs
&lt;/h3&gt;

&lt;p&gt;The official guide lists Russian for Multilingual v2 and Flash v2.5 and recommends selecting a voice whose accent matches the target language and region. Textual phrases such as “she said excitedly” can influence delivery, but they are also spoken; if you use that technique, the phrase must be removed, rewritten, or edited out.&lt;/p&gt;

&lt;p&gt;Output can be MP3, PCM, μ-law, A-law, or Opus. The models are nondeterministic: &lt;code&gt;seed&lt;/code&gt; can improve repeatability but does not guarantee identical audio. For long material, the documentation recommends splitting the text and passing &lt;code&gt;previous_text&lt;/code&gt; / &lt;code&gt;next_text&lt;/code&gt; or adjacent request IDs to preserve prosodic continuity.&lt;/p&gt;

&lt;p&gt;Up to two free regenerations apply only when the text, voice, and all parameters remain exactly the same. Any text or setting change creates a new paid generation. The documentation also states that commercial usage rights require a paid plan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Include retries and rejected takes in the accepted-minute cost
&lt;/h2&gt;

&lt;p&gt;Counting only the first request systematically understates cost. Divide every generation charge for the item by the duration of the audio you actually accept.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accepted-minute cost = all generation spending for the item ÷ accepted audio duration in minutes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Paid alternatives, retries after script edits, and rejected takes all belong in the numerator. Track editing time separately so API price and labor remain visible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Google Gemini example
&lt;/h3&gt;

&lt;p&gt;Google states that audio is billed at 25 audio tokens per second, so one generated minute uses 1,500 audio tokens. Under Standard pricing through December 31, 2026:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;gemini-3.8-flash-tts&lt;/code&gt;: $9 per 1M output audio tokens, or &lt;strong&gt;$0.0135 per generated minute&lt;/strong&gt;, plus text input;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gemini-3.8-flash-lite-tts&lt;/code&gt;: $6 per 1M output audio tokens, or &lt;strong&gt;$0.009 per generated minute&lt;/strong&gt;, plus text input.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For Batch/Flex, output is about $0.00675 and $0.0045 per generated minute; for Priority, about $0.0243 and $0.0162. The official table doubles these rates starting January 1, 2027.&lt;/p&gt;

&lt;p&gt;If you create three one-minute Flash-Lite takes and accept only one, output spending per accepted minute is already about &lt;strong&gt;$0.027&lt;/strong&gt;, not $0.009. Add input tokens, taxes, and any other billed items from the actual account.&lt;/p&gt;

&lt;h3&gt;
  
  
  ElevenLabs example
&lt;/h3&gt;

&lt;p&gt;ElevenLabs bills TTS by character rather than audio duration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;v3 and Multilingual: $0.10 per 1,000 characters;&lt;/li&gt;
&lt;li&gt;v3 Conversational and Flash/Turbo: $0.05 per 1,000 characters.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A 1,200-character script costs $0.12 or $0.06 for one generation. If a final one-minute file requires three paid generations, the accepted-minute cost is $0.36 or $0.18. But the same 1,200 Russian characters may last 50 seconds or 90 seconds, so use the accepted file’s actual duration. The approximate “per minute” figures on the pricing page are averages, not a substitute for measuring your Russian speaking rate.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to handle OpenAI pricing
&lt;/h3&gt;

&lt;p&gt;The OpenAI TTS guide lists models, controls, and formats but not the current rate. On the test date, copy actual usage and cost from the live pricing page or invoice into the same worksheet; an old rate or the price of another audio product will make the comparison look precise while being wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose the first test pair by workload
&lt;/h2&gt;

&lt;p&gt;You do not need to test every service in the first round. Pick two based on content length, output path, and the correction work you can tolerate; expand the shortlist only when both fail.&lt;/p&gt;

&lt;h3&gt;
  
  
  Long courses, podcasts, and audiobooks: test Gemini Flash and Multilingual v2 first
&lt;/h3&gt;

&lt;p&gt;For long-form Russian audio, first compare &lt;code&gt;gemini-3.8-flash-tts&lt;/code&gt; with ElevenLabs Multilingual v2. Gemini provides verbatim scripts, structured style, and inline pause controls; ElevenLabs positions Multilingual v2 for stable long-form output and supports &lt;code&gt;previous_text&lt;/code&gt; / &lt;code&gt;next_text&lt;/code&gt; across chunks.&lt;/p&gt;

&lt;p&gt;Start with Gemini when exact scripts, WAV/raw PCM, or structured two-speaker turns matter most. Start with ElevenLabs when voice choice and chunk continuity matter more; switch the lead candidate if chapter-to-chapter timbre drifts, critical words are misread, or corrections require repeated generations.&lt;/p&gt;

&lt;h3&gt;
  
  
  High-volume short prompts: test Gemini Flash-Lite and ElevenLabs Flash/Turbo first
&lt;/h3&gt;

&lt;p&gt;For catalog text, notifications, and UI prompts, first compare &lt;code&gt;gemini-3.8-flash-lite-tts&lt;/code&gt; with ElevenLabs Flash/Turbo. Both are positioned for lower cost or higher throughput, so choose on accepted-minute cost rather than the list rate.&lt;/p&gt;

&lt;p&gt;ElevenLabs is easier to forecast when text length is stable and character billing suits your workflow. Gemini is the more direct first choice when you need raw PCM, μ-law, or A-law, or want to log audio-token usage; if retries and manual fixes erase the price gap, choose the option with fewer errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Existing streaming stack: let the decoder determine the first test
&lt;/h3&gt;

&lt;p&gt;If your product already uses OpenAI Speech API, test &lt;code&gt;gpt-4o-mini-tts&lt;/code&gt; first because it supports chunked streaming and WAV or PCM output. If exact recitation, structured delivery controls, and 24 kHz raw PCM matter more, test Gemini first.&lt;/p&gt;

&lt;p&gt;Use ElevenLabs Flash as the first candidate when low latency and a broad voice choice are central. Change course if Russian stress errors or cleanup work raise end-to-end latency and cost, even when time to first audio looks good.&lt;/p&gt;

&lt;h3&gt;
  
  
  Telephony and IVR: test Gemini and ElevenLabs first
&lt;/h3&gt;

&lt;p&gt;For telephony and IVR, test Gemini and ElevenLabs first because both can return μ-law or A-law directly, avoiding an extra transcode. Make amounts, dates, names, and confirmation codes hard-fail checks: a pleasant voice cannot compensate for wrong information.&lt;/p&gt;

&lt;p&gt;Add OpenAI only when you already have a reliable PCM transcoding path. Otherwise, reusing a familiar API can create more conversion and troubleshooting work than it saves.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two or more speakers: Gemini first for two, Eleven v3 first for more
&lt;/h3&gt;

&lt;p&gt;For exactly two fixed roles, test Gemini 3.8 first; for more speakers or more dramatic dialogue, test Eleven v3 first. Change the recommendation if Russian voices do not fit the roles, speakers bleed into each other, or long turns lose continuity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Brand or cloned voice: clear rights before comparing sound
&lt;/h3&gt;

&lt;p&gt;For a brand or cloned voice, first eliminate any option that cannot meet consent, retention, and commercial-use conditions, then test long-form quality. A technically convincing clone is not automatically cleared for publication, storage, or monetization.&lt;/p&gt;

&lt;h2&gt;
  
  
  Move to a pilot only after all six checks pass
&lt;/h2&gt;

&lt;p&gt;A single failed item is enough to keep the candidate out of production until you fix it or choose another option.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;critical Russian words, surnames, amounts, and abbreviations are correct;&lt;/li&gt;
&lt;li&gt;pace and pauses are controllable without instructions leaking into the audio;&lt;/li&gt;
&lt;li&gt;three identical requests are stable enough for the use case;&lt;/li&gt;
&lt;li&gt;format and sample rate fit editing, streaming, or telephony;&lt;/li&gt;
&lt;li&gt;commercial rights and synthetic-voice disclosure rules are understood;&lt;/li&gt;
&lt;li&gt;cost includes every generation and is divided by accepted duration;&lt;/li&gt;
&lt;li&gt;the model ID and price have been rechecked immediately before production.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reduce the first round to two candidates and blind-rate the same script across three runs. Start long-form work with Gemini Flash and ElevenLabs Multilingual v2, high-volume short prompts with Flash-Lite and Flash/Turbo, and telephony with Gemini and ElevenLabs; keep only the option that reads critical content correctly, stays stable, and delivers a controllable accepted-minute cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Official references
&lt;/h2&gt;

&lt;p&gt;Checked on September 24, 2026:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developers.openai.com/api/docs/guides/text-to-speech" rel="noopener noreferrer"&gt;OpenAI: Text to speech&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ai.google.dev/gemini-api/docs/speech-generation" rel="noopener noreferrer"&gt;Google Gemini API: Speech generation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ai.google.dev/gemini-api/pricing" rel="noopener noreferrer"&gt;Google Gemini API: Pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elevenlabs.io/docs/overview/capabilities/text-to-speech" rel="noopener noreferrer"&gt;ElevenLabs: Text to Speech&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elevenlabs.io/pricing/api" rel="noopener noreferrer"&gt;ElevenLabs: API pricing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bettertoken.ai/en/blog/russian-neural-text-to-speech-selection/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=neyrosetevaya-ozvuchka-russkogo-teksta-vybor&amp;amp;utm_content=russian-neural-text-to-speech-selection" rel="noopener noreferrer"&gt;BetterToken blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;BetterToken provides pay-as-you-go access to AI model APIs through&lt;br&gt;
OpenAI-compatible and Anthropic-compatible endpoints — useful if you are wiring&lt;br&gt;
Claude Code, Codex, or your own tooling to a custom base URL.&lt;br&gt;
See the &lt;a href="https://docs.bettertoken.ai/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=neyrosetevaya-ozvuchka-russkogo-teksta-vybor&amp;amp;utm_content=russian-neural-text-to-speech-selection" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to get started.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Gemini Omni video extension and frame interpolation: API workflow and continuity checks</title>
      <dc:creator>Adela</dc:creator>
      <pubDate>Mon, 28 Sep 2026 06:29:09 +0000</pubDate>
      <link>https://dev.to/bettertoken_ai/gemini-omni-video-extension-and-frame-interpolation-api-workflow-and-continuity-checks-1mg7</link>
      <guid>https://dev.to/bettertoken_ai/gemini-omni-video-extension-and-frame-interpolation-api-workflow-and-continuity-checks-1mg7</guid>
      <description>&lt;p&gt;You may already have a short clip that ends before the action is complete, or only a first and last frame with no motion between them. With &lt;code&gt;gemini-omni-1.1-flash&lt;/code&gt;, you can append a 3–10 second continuation or generate a transition between two boundary images; by the end, you will know which mode to use, how to call the API, and how to decide whether the result is deliverable.&lt;/p&gt;

&lt;p&gt;Use &lt;strong&gt;tail extension&lt;/strong&gt; when you want to preserve the motion, camera, and sound of an existing clip; use &lt;strong&gt;first/last-frame interpolation&lt;/strong&gt; when the start and finish are fixed and only the middle is missing; an MP4 response only completes generation, so you still need to inspect the subject, motion, seam, and audio.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should you extend the clip or interpolate two frames?
&lt;/h2&gt;

&lt;p&gt;If you have source video, start with tail extension; if a specific final image must be reached, start with interpolation. Extension is not bounded by a target final frame, so using it for that job can add another generation and review cycle.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Job&lt;/th&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Best use&lt;/th&gt;
&lt;th&gt;Continuity to inspect most closely&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tail extension&lt;/td&gt;
&lt;td&gt;One video, optionally with reference images&lt;/td&gt;
&lt;td&gt;Continue an action, camera move, or scene for a few seconds&lt;/td&gt;
&lt;td&gt;Pose, speed, camera direction, lighting, and audio around the seam&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;First/last-frame interpolation&lt;/td&gt;
&lt;td&gt;A first frame, a last frame, and a transition prompt&lt;/td&gt;
&lt;td&gt;Fill in motion between two defined states&lt;/td&gt;
&lt;td&gt;Identity, spatial relationships, motion path, and arrival at the target frame&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Uploaded-video extension is designed for short increments: the official guide describes a 3–10 second continuation, and the prompt guide also documents 10-second steps up to 40 seconds total. Your uploaded clip must be 10 seconds or shorter, and footage can only be appended at the tail; use a conventional editor if you need to insert a shot at the beginning or in the middle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decide these four things before you call the API
&lt;/h2&gt;

&lt;p&gt;Fix the model, output specification, cut behavior, and source material you will use for comparison before generating. Missing one of these decisions often means rerunning the job or being unable to tell whether a seam change came from the model or the source.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use the GA model ID
&lt;/h3&gt;

&lt;p&gt;Use the GA model ID &lt;code&gt;gemini-omni-1.1-flash&lt;/code&gt;. It became generally available on August 27, 2026; the older &lt;code&gt;gemini-omni-flash-preview&lt;/code&gt; endpoint is scheduled for deprecation on September 30, 2026.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validate continuity at 720p first
&lt;/h3&gt;

&lt;p&gt;For the first pass, use the default &lt;code&gt;720p&lt;/code&gt; so continuity debugging stays separate from high-resolution delivery. The &lt;code&gt;resolution&lt;/code&gt; field in &lt;code&gt;response_format&lt;/code&gt; accepts &lt;code&gt;360p&lt;/code&gt;, &lt;code&gt;720p&lt;/code&gt;, &lt;code&gt;1080p&lt;/code&gt;, and &lt;code&gt;4k&lt;/code&gt;; the documentation identifies &lt;code&gt;1080p&lt;/code&gt; and &lt;code&gt;4k&lt;/code&gt; as upscaled outputs, with 16:9 as the default aspect ratio and 9:16 available on request. For results larger than 4 MB, especially above 720p, use &lt;code&gt;delivery="uri"&lt;/code&gt;, wait until the file becomes active, and then download it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choose between one continuous shot and a deliberate cut
&lt;/h3&gt;

&lt;p&gt;Decide whether the extension is one continuous shot or an intentional cut. In an extension prompt, &lt;code&gt;0s&lt;/code&gt; means the start of the newly generated portion, not the start of the source clip. Ask for a “single continuous shot” and “no scene cuts” when the action must remain unbroken. When a cut is intentional, state when it should happen within the extension.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep the source clip and boundary images
&lt;/h3&gt;

&lt;p&gt;Retain the source clip and both boundary images. The official prompt guide says Omni uses the last 10 seconds of the original video as context and may edit some final input frames to make the transition. That makes a source-versus-output comparison part of the continuity review, not an optional backup step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Have a source clip? Extend it from the tail
&lt;/h2&gt;

&lt;p&gt;Use tail extension when you already have video and want the action, camera move, or scene to continue for a few seconds. Start with a minimal 720p request, then tighten the subject, motion, camera, and audio constraints.&lt;/p&gt;

&lt;h3&gt;
  
  
  Run a minimal 720p extension request
&lt;/h3&gt;

&lt;p&gt;The Python example below uploads the clip through the Files API, waits for processing, and passes the video URI and continuation instructions to &lt;code&gt;interactions.create&lt;/code&gt;. It stays at 720p so you can solve continuity before dealing with high-resolution file delivery.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;google&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;genai&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;genai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;video_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my_video.mp4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;video_file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PROCESSING&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;video_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;video_file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;video_file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FAILED&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;video_file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;interaction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;interactions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini-omni-1.1-flash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;video&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;uri&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;video_file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Continue the scene as one unbroken shot. &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Keep the same subject, wardrobe, camera direction, lighting, and motion speed. No scene cuts and no new dialogue.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;response_format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;video&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;resolution&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;720p&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;extended.mp4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b64decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;interaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Write prompts as observable conditions
&lt;/h3&gt;

&lt;p&gt;Do not stop at “continue the scene.” State at least five observable dimensions: what must remain unchanged about the subject, how the action should develop, how the camera should move, whether light or environment may change, and whether cuts or new sound are allowed. “The right hand keeps rising at the same speed” is testable; “make it natural” is not.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set &lt;code&gt;task&lt;/code&gt; only when prompting selects the wrong mode
&lt;/h3&gt;

&lt;p&gt;If prompting does not select extension mode, add &lt;code&gt;{"video_config": {"task": "extend"}}&lt;/code&gt; under &lt;code&gt;generation_config&lt;/code&gt;. The guide recommends prompting first because setting &lt;code&gt;task&lt;/code&gt; adds stricter constraints. For a video generated in the preceding turn, &lt;code&gt;previous_interaction_id&lt;/code&gt; can continue the sequence without another upload. That path requires stored interaction state; a result created with &lt;code&gt;store=false&lt;/code&gt; cannot be edited later through that ID.&lt;/p&gt;

&lt;h3&gt;
  
  
  Change the plan when dialogue or region limits apply
&lt;/h3&gt;

&lt;p&gt;There are important dialogue and region boundaries. An uploaded video in which someone is already speaking cannot currently be extended with additional dialogue; a silent continuation or a prompt that adds no dialogue is allowed. Spoken continuation is supported for multi-turn extension of model-generated video through &lt;code&gt;previous_interaction_id&lt;/code&gt;. Editing and extending uploaded video are currently unavailable to users in the EEA, Switzerland, and the United Kingdom, while extension of model-generated video remains supported in available regions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Only have boundary frames? Generate the motion between them
&lt;/h2&gt;

&lt;p&gt;Use first/last-frame interpolation when the start and finish are clear but the motion between them is missing. Submit the two images in order and describe how the subject, camera, and environment should move from the first state to the last.&lt;/p&gt;

&lt;h3&gt;
  
  
  Submit the two boundary images first
&lt;/h3&gt;

&lt;p&gt;Interpolation fits a job with clear boundary states but no middle motion. Put the two images in order in &lt;code&gt;input&lt;/code&gt;, then describe how the subject, camera, and environment should travel from the first state to the last. This complete example reads local JPEGs, encodes them, and requests a 720p result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;google&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;genai&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;genai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;first_frame_b64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b64encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;first.jpg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;read_bytes&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;last_frame_b64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b64encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;last.jpg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;read_bytes&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;interaction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;interactions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini-omni-1.1-flash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;first_frame_b64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mime_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image/jpeg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;last_frame_b64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mime_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image/jpeg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Transition naturally from the first frame to the last frame. &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Preserve subject identity and camera direction, keep the motion path continuous, and avoid abrupt cuts.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;response_format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;video&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;resolution&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;720p&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;interpolation.mp4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b64decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;interaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use &lt;code&gt;image_to_video&lt;/code&gt; only if the mode is still unclear
&lt;/h3&gt;

&lt;p&gt;After submitting the images in order, state that the first is the start and the second is the finish. If the mode is still wrong, use &lt;code&gt;image_to_video&lt;/code&gt; as a &lt;code&gt;task&lt;/code&gt; value; it supports a precise description of subject, camera, and motion rather than replacing one.&lt;/p&gt;

&lt;h3&gt;
  
  
  The larger the difference, the more you should sequence the changes
&lt;/h3&gt;

&lt;p&gt;Compatible boundary frames make the problem easier to specify. Keep subject identity, aspect ratio, camera axis, and spatial layout reasonably consistent, or explain the order of change: turn the subject first, move the camera second, and change the light last. That is production guidance, not a guarantee of model behavior; the returned video still has to be inspected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is the result deliverable? Inspect the seam, subject, motion, and audio
&lt;/h2&gt;

&lt;p&gt;The standard is not whether the result “looks close enough,” but whether defects can be pointed out and converted into actionable revision instructions. Watch once at normal speed, inspect the seam slowly or frame by frame, and listen to the audio in a separate pass.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;What to inspect&lt;/th&gt;
&lt;th&gt;Actionable revision wording&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Subject&lt;/td&gt;
&lt;td&gt;Face, hair, wardrobe, accessories, body proportions, hands, and held objects&lt;/td&gt;
&lt;td&gt;“Keep the coat color and the object in the right hand unchanged.”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Motion&lt;/td&gt;
&lt;td&gt;Direction, speed, balance, contact points, gaze, and camera trajectory&lt;/td&gt;
&lt;td&gt;“Continue the current stride to the right without accelerating or reversing.”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edit and image&lt;/td&gt;
&lt;td&gt;Jump cuts, exposure, color temperature, depth of field, perspective, and background geometry at the seam&lt;/td&gt;
&lt;td&gt;“Keep the same camera axis and focal length; do not cut.”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audio&lt;/td&gt;
&lt;td&gt;Ambience, music beat, dialogue, reverb, volume, clicks, and new noise&lt;/td&gt;
&lt;td&gt;“Continue the ambience, add no dialogue, and keep the music beat unchanged.”&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Check the seam for extension and both endpoints for interpolation
&lt;/h3&gt;

&lt;p&gt;For extension, concentrate on roughly the last second of the source and the first second of the generated continuation, and verify whether the output altered the original tail frames. For interpolation, inspect the middle path but also confirm that the start really corresponds to the first image and the finish reaches the second image, rather than merely producing something stylistically similar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tighten one variable per revision
&lt;/h3&gt;

&lt;p&gt;On revision, tighten one major variable at a time. Fix identity first, then motion, then camera and audio. This makes each prompt change easier to evaluate. Describe the location and behavior of the defect—“the left sleeve changes color at the seam”—instead of asking for something vague such as “more cinematic” or “smoother.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Do not force this endpoint into these jobs
&lt;/h2&gt;

&lt;p&gt;This endpoint is not a one-call editor when you need to insert a shot into the middle of a long program, continue existing dialogue, or reason across several source clips. If any limit below affects the job, split the work into shots or switch to a conventional editing workflow first.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uploaded clips can only be extended at the tail and must be 10 seconds or shorter.&lt;/li&gt;
&lt;li&gt;Additional dialogue cannot be generated from an uploaded clip in which someone is speaking; voice editing itself is unsupported.&lt;/li&gt;
&lt;li&gt;Audio references cannot be uploaded. Audio in a video reference is ignored.&lt;/li&gt;
&lt;li&gt;Video references support at most three clips of up to three seconds each. Reasoning across multiple videos is unsupported.&lt;/li&gt;
&lt;li&gt;System instructions, &lt;code&gt;temperature&lt;/code&gt;, &lt;code&gt;top_p&lt;/code&gt;, stop sequences, and a separate negative-prompt field are unsupported. Put negatives in the ordinary prompt, such as “Do not cut.”&lt;/li&gt;
&lt;li&gt;Every generated video includes invisible SynthID, and both inputs and outputs are subject to content-safety filtering.&lt;/li&gt;
&lt;li&gt;The documentation marks English prompts as fully supported; other languages have not been evaluated and may vary.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A practical fallback is to generate short shots separately, then assemble and mix them in a conventional editor. That is usually faster than repeatedly asking a tail-extension endpoint to perform mid-program insertion, dialogue continuation, or multi-clip reasoning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run this checklist before delivery
&lt;/h2&gt;

&lt;p&gt;A successful generation call is not a quality approval. Before delivery, confirm that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you retained the input video, output video, and both boundary images;&lt;/li&gt;
&lt;li&gt;you recorded the model ID, resolution, and complete prompt;&lt;/li&gt;
&lt;li&gt;you inspected the extension seam frame by frame and checked whether source tail frames changed;&lt;/li&gt;
&lt;li&gt;you confirmed that interpolation starts at the first image and actually reaches the second;&lt;/li&gt;
&lt;li&gt;you listened to the audio separately for gaps, clicks, or unexpected new noise;&lt;/li&gt;
&lt;li&gt;you checked regional, input-duration, dialogue, and reference-media limits.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any item is unexplained, revise the result instead of approving it from the API status alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Official references
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ai.google.dev/gemini-api/docs/omni" rel="noopener noreferrer"&gt;Generate and edit videos with Gemini Omni Flash&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ai.google.dev/gemini-api/docs/changelog" rel="noopener noreferrer"&gt;Gemini API release notes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bettertoken.ai/en/blog/gemini-omni-video-extension-frame-interpolation/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=gemini-omni-flash-prodlit-video-i-perekhod-kadrov&amp;amp;utm_content=gemini-omni-video-extension-frame-interpolation" rel="noopener noreferrer"&gt;BetterToken blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;BetterToken provides pay-as-you-go access to AI model APIs through&lt;br&gt;
OpenAI-compatible and Anthropic-compatible endpoints — useful if you are wiring&lt;br&gt;
Claude Code, Codex, or your own tooling to a custom base URL.&lt;br&gt;
See the &lt;a href="https://docs.bettertoken.ai/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=gemini-omni-flash-prodlit-video-i-perekhod-kadrov&amp;amp;utm_content=gemini-omni-video-extension-frame-interpolation" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to get started.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Veo 3.1 Cost per Accepted Video: Calculate Duration, Resolution, and Retries</title>
      <dc:creator>Adela</dc:creator>
      <pubDate>Mon, 28 Sep 2026 06:27:07 +0000</pubDate>
      <link>https://dev.to/bettertoken_ai/veo-31-cost-per-accepted-video-calculate-duration-resolution-and-retries-15j7</link>
      <guid>https://dev.to/bettertoken_ai/veo-31-cost-per-accepted-video-calculate-duration-resolution-and-retries-15j7</guid>
      <description>&lt;p&gt;You may have calculated that one eight-second Fast clip at 1080p costs only $0.96 and treated that as the price of a usable shot. If the third generation is the first one you approve, the bill is already $2.88; add several shots and the gap grows quickly. By the end of this guide, you can calculate cost shot by shot, set a retry stop-loss, and decide which tier and resolution to test first for your delivery specifications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use this formula to calculate the real cost of an accepted video
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The generation cost of a deliverable video is not final runtime multiplied by one rate; it is the total of every billable attempt across every shot.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cost of one successful generation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;billable seconds × the per-second rate for the selected tier and resolution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Generation cost of an accepted video:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Σ (billable seconds per shot × per-second rate × billable attempts)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example, one eight-second Fast generation at 1080p costs &lt;code&gt;8 × $0.12 = $0.96&lt;/code&gt;. If the third result is the first usable one, that shot costs &lt;code&gt;$0.96 × 3 = $2.88&lt;/code&gt; to generate.&lt;/p&gt;

&lt;p&gt;A “billable attempt” here means a version that was generated successfully and incurred a charge. A request that never produces a video is different from a generated result that you later reject during review.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose a tier by scenario: what should you test first when cost matters?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;For a cost-first workflow, test Lite first for 720p or 1080p and Fast first for 4k; move to another tier only when the current choice does not pass your acceptance criteria.&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your scenario&lt;/th&gt;
&lt;th&gt;Test first&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;th&gt;When to change&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;High-volume drafts, social experiments, or internal previews at 720p/1080p&lt;/td&gt;
&lt;td&gt;Lite&lt;/td&gt;
&lt;td&gt;At $0.05/sec for 720p and $0.08/sec for 1080p, it has the lowest official rate of the three tiers&lt;/td&gt;
&lt;td&gt;Test Fast if Lite cannot meet your criteria for subject, motion, composition, or consistency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You need 1080p and want room to iterate without starting at the highest rate&lt;/td&gt;
&lt;td&gt;Fast&lt;/td&gt;
&lt;td&gt;Its 1080p rate is $0.12/sec, versus $0.40/sec for Standard&lt;/td&gt;
&lt;td&gt;If Fast reaches your stop-loss without passing, revise the prompt or shot design first; test Standard only if you still need another tier comparison&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The final deliverable explicitly requires 4k&lt;/td&gt;
&lt;td&gt;Fast&lt;/td&gt;
&lt;td&gt;Fast costs $0.30/sec at 4k; Lite does not support 4k, and Standard costs $0.60/sec&lt;/td&gt;
&lt;td&gt;Test the same shot with Standard only when Fast misses specific acceptance criteria; do not default every shot to Standard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You need scene extension, last-frame control, or integration with a legacy pipeline&lt;/td&gt;
&lt;td&gt;Veo 3.1&lt;/td&gt;
&lt;td&gt;Google lists these as specific Veo 3.1 use cases&lt;/td&gt;
&lt;td&gt;If you do not need these capabilities, compare Gemini Omni Flash before committing to a Veo 3.1 workflow&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is a &lt;strong&gt;cost-first test order&lt;/strong&gt;, not a quality ranking. A lower rate does not guarantee approval, and a higher rate does not guarantee success on the first attempt. Write the acceptance criteria first, then find the least expensive workflow that actually meets them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Official rates set the floor for every attempt
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;As of September 24, 2026, paid Veo 3.1 usage in the Gemini API is billed per second, with both tier and resolution determining the cost.&lt;/strong&gt; Check the &lt;a href="https://ai.google.dev/gemini-api/pricing" rel="noopener noreferrer"&gt;official Google pricing page&lt;/a&gt; again before approving a production budget because prices and model status can change.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;Model ID&lt;/th&gt;
&lt;th&gt;720p&lt;/th&gt;
&lt;th&gt;1080p&lt;/th&gt;
&lt;th&gt;4k&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Standard&lt;/td&gt;
&lt;td&gt;&lt;code&gt;veo-3.1-generate-preview&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;$0.40/sec&lt;/td&gt;
&lt;td&gt;$0.40/sec&lt;/td&gt;
&lt;td&gt;$0.60/sec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fast&lt;/td&gt;
&lt;td&gt;&lt;code&gt;veo-3.1-fast-generate-preview&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;$0.10/sec&lt;/td&gt;
&lt;td&gt;$0.12/sec&lt;/td&gt;
&lt;td&gt;$0.30/sec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lite&lt;/td&gt;
&lt;td&gt;&lt;code&gt;veo-3.1-lite-generate-preview&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;$0.05/sec&lt;/td&gt;
&lt;td&gt;$0.08/sec&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Four conclusions directly affect the budget:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Standard costs the same at 720p and 1080p. If delivery genuinely requires 1080p, there is no API-price reason to fall back to 720p.&lt;/li&gt;
&lt;li&gt;Fast rises from $0.12/sec at 1080p to $0.30/sec at 4k, a 2.5× increase.&lt;/li&gt;
&lt;li&gt;Lite does not support 4k, so a 4k project must be budgeted with Fast or Standard.&lt;/li&gt;
&lt;li&gt;The listed prices are for video with audio by default; there is no published no-audio discount you can safely subtract.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of the three Veo 3.1 model IDs has a free tier. Google also says that when certain audio-processing problems prevent a video from being generated, charging applies only when a video is generated successfully. A generated version you later discard should still be recorded according to the actual bill.&lt;/p&gt;

&lt;h2&gt;
  
  
  Eight-second shots: what do one, three, and five attempts cost?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A small per-attempt price can become a large line item because the bill grows in direct proportion to billable attempts.&lt;/strong&gt; Eight seconds is used only to make the arithmetic easy; it is not a claim about a fixed or maximum generation length.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;8 sec at 720p&lt;/th&gt;
&lt;th&gt;8 sec at 1080p&lt;/th&gt;
&lt;th&gt;8 sec at 4k&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Standard&lt;/td&gt;
&lt;td&gt;$3.20&lt;/td&gt;
&lt;td&gt;$3.20&lt;/td&gt;
&lt;td&gt;$4.80&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fast&lt;/td&gt;
&lt;td&gt;$0.80&lt;/td&gt;
&lt;td&gt;$0.96&lt;/td&gt;
&lt;td&gt;$2.40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lite&lt;/td&gt;
&lt;td&gt;$0.40&lt;/td&gt;
&lt;td&gt;$0.64&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For an eight-second 1080p shot, retry scenarios look like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Billable attempts&lt;/th&gt;
&lt;th&gt;Standard&lt;/th&gt;
&lt;th&gt;Fast&lt;/th&gt;
&lt;th&gt;Lite&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;$3.20&lt;/td&gt;
&lt;td&gt;$0.96&lt;/td&gt;
&lt;td&gt;$0.64&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;$9.60&lt;/td&gt;
&lt;td&gt;$2.88&lt;/td&gt;
&lt;td&gt;$1.92&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;$16.00&lt;/td&gt;
&lt;td&gt;$4.80&lt;/td&gt;
&lt;td&gt;$3.20&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The table cannot tell you which tier has better quality. It can answer a more useful budgeting question: how many paid attempts are you willing to fund for one shot? If you cap Fast 1080p at five attempts, the API budget for that shot is $4.80. Once the cap is reached, change the prompt, redesign the shot, or change the workflow instead of generating without a limit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-shot videos must be calculated shot by shot
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Multiplying a final 32-second runtime by one rate misses the cost of every discarded version.&lt;/strong&gt; A useful production sheet needs one row per shot, not just one row for the whole project.&lt;/p&gt;

&lt;p&gt;Suppose a project contains four eight-second shots, all generated with Fast at 1080p for $0.12/sec. The shots require 1, 2, 3, and 4 billable attempts respectively:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Shot&lt;/th&gt;
&lt;th&gt;Seconds&lt;/th&gt;
&lt;th&gt;Attempts, example&lt;/th&gt;
&lt;th&gt;Calculation&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;8 × $0.12 × 1&lt;/td&gt;
&lt;td&gt;$0.96&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;8 × $0.12 × 2&lt;/td&gt;
&lt;td&gt;$1.92&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;8 × $0.12 × 3&lt;/td&gt;
&lt;td&gt;$2.88&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;8 × $0.12 × 4&lt;/td&gt;
&lt;td&gt;$3.84&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total&lt;/td&gt;
&lt;td&gt;32 accepted seconds&lt;/td&gt;
&lt;td&gt;10 shot attempts&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$9.60&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A one-pass calculation for 32 seconds would be $3.84; the shot-level calculation is $9.60. The extra $5.76 comes from additional versions, not from a longer finished video.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set three retry limits when you do not know the acceptance rate
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Do not borrow an imaginary “industry-average retry rate”; define target, stress, and stop-loss scenarios for each shot.&lt;/strong&gt; This shows the cash range before production begins and tells the team when it must stop and change the plan.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Target scenario:&lt;/strong&gt; the number of attempts you consider reasonable for an ordinary shot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stress scenario:&lt;/strong&gt; a higher cap for difficult motion or an important hero shot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stop-loss scenario:&lt;/strong&gt; the hard limit after which you change the prompt, redesign the shot, change resolution, or test another tier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the same eight-second Fast 1080p shot, one, three, and five attempts cost $0.96, $2.88, and $4.80. You might set three attempts as the target and five as the stop-loss. Every attempt after the fifth adds another $0.96 without guaranteeing that the result will be closer to approval.&lt;/p&gt;

&lt;p&gt;Important shots can receive a higher cap, but the cap should be written into the budget before generation starts. Otherwise, “the attempt is cheap” can turn into unlimited retries whose total exceeds a higher-priced alternative.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose resolution by delivery need: do not make every draft 4k
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Unless 4k is a real delivery need, use the lowest resolution that lets you evaluate the shot and reserve 4k for selected final assets.&lt;/strong&gt; This lowers both the first attempt and every failed retry that follows it.&lt;/p&gt;

&lt;p&gt;Using the official prices checked on September 24, 2026:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standard: 720p and 1080p cost the same; 4k costs 50% more.&lt;/li&gt;
&lt;li&gt;Fast: 1080p costs 1.2× the 720p rate; 4k costs 2.5× the 1080p rate.&lt;/li&gt;
&lt;li&gt;Lite: 1080p costs 1.6× the 720p rate; 4k is not supported.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With Standard, 720p and 1080p have the same API price if your workflow supports 1080p. Fast is different: an eight-second shot rises from $0.96 at 1080p to $2.40 at 4k. At five attempts, the comparison is $4.80 versus $12.00.&lt;/p&gt;

&lt;p&gt;For social posts, internal previews, or composition checks without a hard 4k need, do not upgrade every intermediate version merely for consistency. Apply 4k only to approved shots when the delivery channel truly needs it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Put the API bill back into the full production budget
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Generation is only one production cost; editing, sound, captions, and human review belong in the same budget.&lt;/strong&gt; When generation is inexpensive, selection and editing may cost more. With high resolution and many retries, the API bill can become a major line item.&lt;/p&gt;

&lt;p&gt;Record at least these fields for every shot:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;What you should enter&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Shot ID&lt;/td&gt;
&lt;td&gt;A, B, C, or the storyboard name&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Billable seconds&lt;/td&gt;
&lt;td&gt;The seconds shown in the actual billing record&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tier and resolution&lt;/td&gt;
&lt;td&gt;Standard, Fast, or Lite; 720p, 1080p, or 4k&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Current rate&lt;/td&gt;
&lt;td&gt;The per-second price from the official page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Target / stop-loss attempts&lt;/td&gt;
&lt;td&gt;The planned attempt count and hard cap&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Actual billable attempts&lt;/td&gt;
&lt;td&gt;Based on request results and billing records&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shot generation cost&lt;/td&gt;
&lt;td&gt;seconds × rate × billable attempts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Acceptance result&lt;/td&gt;
&lt;td&gt;accepted, revise, or abandoned&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;At project level:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;full production budget = total generation cost + editing + voice/music + captions/localization + human review + storage and other costs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When comparing two workflows, do not compare only the per-second rates. Put actual attempt counts, human selection time, and post-production costs into the same sheet to see which workflow truly costs less.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use your own records for the numbers public pricing cannot provide
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Public pricing tells you the rate per second, but it cannot supply your retry rate, acceptance rate, taxes, or actual billing-rounding behavior.&lt;/strong&gt; Those variables directly affect the final budget and should come from request logs and invoices.&lt;/p&gt;

&lt;p&gt;Google’s public pricing information does not publish a universal average retry count or promise that any tier will pass review on the first attempt. The one-, three-, and five-attempt examples in this article are budgeting scenarios, not model success rates.&lt;/p&gt;

&lt;p&gt;For actual reconciliation, use durations supported by the current request, billable seconds shown in your account, real billable attempts, and your own acceptance history. After several projects, group attempts by shot type—people, products, complex motion, or dialogue—to make the next estimate more accurate.&lt;/p&gt;

&lt;p&gt;Add taxes, exchange rates, card fees, and platform fees separately. Do not mix Gemini API, Vertex AI, Flow, Gemini app subscriptions, or third-party API prices in one rate table because their billing models may differ.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How much does Veo 3.1 cost per second?
&lt;/h3&gt;

&lt;p&gt;Using Gemini API prices checked on September 24, 2026, default video-with-audio rates range from $0.05/sec for Lite at 720p to $0.60/sec for Standard at 4k. The exact rate depends on tier and resolution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is it cheaper without audio?
&lt;/h3&gt;

&lt;p&gt;The official pricing page lists default prices with audio and does not publish a no-audio discount that can be used in this calculation. Do not subtract an audio charge unless the current official page explicitly lists a separate rate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are failed generations billed?
&lt;/h3&gt;

&lt;p&gt;Google says that when certain audio-processing problems prevent a video from being generated, charging applies only when the video is generated successfully. A successfully generated clip that later fails your creative review is a different case and should be counted according to the actual bill.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is there a Veo 3.1 free tier?
&lt;/h3&gt;

&lt;p&gt;The current official pricing table shows no free tier for any of the three Veo 3.1 model IDs. Budget testing as paid attempts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build your budget in four steps
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Start with the delivery specification, calculate one attempt, and then set a retry stop-loss.&lt;/strong&gt; Use this sequence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write down the duration, resolution, and acceptance criteria for every shot.&lt;/li&gt;
&lt;li&gt;Choose the first tier to test using the cost-first order and calculate its per-attempt price.&lt;/li&gt;
&lt;li&gt;Calculate one-, three-, and five-attempt scenarios, then set a hard cap for important shots.&lt;/li&gt;
&lt;li&gt;Record actual billing and acceptance shot by shot, and add editing, sound, captions, and human labor.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the total is too high, first remove unnecessary 4k generations and unlimited retries; then consider another tier or redesigning the shot. That optimizes the cost of a deliverable video, not a deceptively low one-attempt price that retries can multiply.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bettertoken.ai/en/blog/veo-3-1-accepted-video-cost/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=veo-3-1-stoimost-prinyatogo-video&amp;amp;utm_content=veo-3-1-accepted-video-cost" rel="noopener noreferrer"&gt;BetterToken blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;BetterToken provides pay-as-you-go access to AI model APIs through&lt;br&gt;
OpenAI-compatible and Anthropic-compatible endpoints — useful if you are wiring&lt;br&gt;
Claude Code, Codex, or your own tooling to a custom base URL.&lt;br&gt;
See the &lt;a href="https://docs.bettertoken.ai/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=veo-3-1-stoimost-prinyatogo-video&amp;amp;utm_content=veo-3-1-accepted-video-cost" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to get started.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Mistral Studio Prompt and Skill Version Control: A Traceable Release Workflow</title>
      <dc:creator>Adela</dc:creator>
      <pubDate>Mon, 28 Sep 2026 06:25:05 +0000</pubDate>
      <link>https://dev.to/bettertoken_ai/mistral-studio-prompt-and-skill-version-control-a-traceable-release-workflow-k0i</link>
      <guid>https://dev.to/bettertoken_ai/mistral-studio-prompt-and-skill-version-control-a-traceable-release-workflow-k0i</guid>
      <description>&lt;p&gt;You ship a Prompt change, the output regresses the next morning, and nobody can immediately say which version is live, who approved it, or what should be restored. Mistral Studio's immutable versions, named owners, version comparison, audit logs, and rollback can turn that kind of ad hoc change into a traceable release chain.&lt;/p&gt;

&lt;p&gt;By the end of this guide, you can set up a minimum process for one Prompt or Skill: name an owner, freeze a candidate, test it against fixed cases, promote it only after approval, and return to a known-good version when behavior degrades.&lt;/p&gt;

&lt;h2&gt;
  
  
  If it affects real users, stop managing it like ordinary copy
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;You need a versioned release process as soon as a Prompt or Skill is edited by several people, runs in production, or must be investigated and restored after a failure.&lt;/strong&gt; A solo experiment can stay lightweight. Once an output affects customers, business actions, or downstream systems, record at least the production version, owner, test result, approver, and rollback target.&lt;/p&gt;

&lt;p&gt;A Prompt determines how a model responds. A Skill may also choose a tool, pass parameters, and produce a structured contract. The wrong version can therefore change policy, tone, permissions, or downstream fields—not just wording—and make diagnosis much slower.&lt;/p&gt;

&lt;h2&gt;
  
  
  Studio provides versioning and traceability; you still define “pass”
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mistral Studio answers which version ran, who owns it, what changed, and whether you can go back, but your team still decides what acceptable behavior means.&lt;/strong&gt; In its July 9, 2026 announcement, Mistral described Prompts and Skills as tracked assets with immutable versions, owners, labels, full history, audit logs, comparison, and rollback.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Studio capability&lt;/th&gt;
&lt;th&gt;What it helps you answer&lt;/th&gt;
&lt;th&gt;What you still need to define&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Immutable versions&lt;/td&gt;
&lt;td&gt;Which exact content was running during an incident&lt;/td&gt;
&lt;td&gt;Which changes require a candidate and who may release it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Version comparison and rollback&lt;/td&gt;
&lt;td&gt;What changed between two versions and how to restore a known-good one&lt;/td&gt;
&lt;td&gt;What triggers rollback and how recovery is verified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Named owners&lt;/td&gt;
&lt;td&gt;Who is accountable for each Prompt or Skill&lt;/td&gt;
&lt;td&gt;Who owns business behavior and who reviews it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Classification labels&lt;/td&gt;
&lt;td&gt;Which asset is &lt;code&gt;Staging&lt;/code&gt; or &lt;code&gt;Production&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Entry criteria for each label and whether production can ever point to more than one version&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audit logs&lt;/td&gt;
&lt;td&gt;Who changed what and when&lt;/td&gt;
&lt;td&gt;Where approval evidence, test results, and incident records live&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observability and lineage&lt;/td&gt;
&lt;td&gt;Which asset version produced a production output; lineage is the link from output back to the assets behind it&lt;/td&gt;
&lt;td&gt;Which quality, compliance, latency, or cost indicators define regression&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workspace sharing and access control&lt;/td&gt;
&lt;td&gt;How an asset moves from creator-only access to a team or organization&lt;/td&gt;
&lt;td&gt;Who may view, edit, approve, and invoke it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skills delivered as MCP servers&lt;/td&gt;
&lt;td&gt;How the executed Skill can remain in the same governed system as the versioned asset&lt;/td&gt;
&lt;td&gt;Client compatibility, permissions, and production validation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Studio lets a domain expert or developer edit and test a Prompt or Skill without waiting for a full code pipeline on every attempt. A production change should still pass your existing tests and approvals. Mistral gives SDK-based label promotion connected to CI/CD such as GitHub Actions as one example; check the current documentation for exact interfaces and configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Name one accountable owner before adding more collaborators
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Every production asset should have one clearly named primary owner, even when a small team combines several roles in one person.&lt;/strong&gt; Version history cannot compensate for a setup in which everyone can edit but nobody owns the resulting behavior.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Minimum responsibility&lt;/th&gt;
&lt;th&gt;How a small team can combine it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Asset Owner&lt;/td&gt;
&lt;td&gt;Defines purpose, allowed and prohibited behavior, acceptance criteria, and next-version priorities&lt;/td&gt;
&lt;td&gt;May also act as Release Operator, but must still record the exact version being approved&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reviewer / Approver&lt;/td&gt;
&lt;td&gt;Reviews the diff, test evidence, risk, and production decision&lt;/td&gt;
&lt;td&gt;A colleague may review low-risk changes; use independent review for policy, tool-permission, or critical-output changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Release Operator&lt;/td&gt;
&lt;td&gt;Promotes the label or runs the release pipeline, then records time, target version, and rollback target&lt;/td&gt;
&lt;td&gt;May be the Owner, but cannot skip version and approval records&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Incident / Audit Owner&lt;/td&gt;
&lt;td&gt;Locates the active version, coordinates rollback, and preserves the incident record&lt;/td&gt;
&lt;td&gt;Can be an on-call or platform owner&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If only one person maintains the asset today, do not leave every responsibility blank. Put the same name in multiple roles if necessary, while keeping four answers visible: who changed it, who reviewed it, who released it, and who can order a rollback.&lt;/p&gt;

&lt;h2&gt;
  
  
  A small team still needs Draft, Staging, and Production
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The minimum setup is not four separate systems; it is a clear distinction between editing, validating, and running.&lt;/strong&gt; Add &lt;code&gt;Shared&lt;/code&gt; when several people collaborate. With a single maintainer, collaboration can remain inside Draft, but the boundary between Staging and Production should not disappear.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Draft&lt;/strong&gt; — creator-controlled, open to rapid edits and experiments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shared&lt;/strong&gt; — visible in the workspace for collaboration and review, but not used in production.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Staging&lt;/strong&gt; — a frozen candidate under fixed tests and approval; do not keep editing it while it is being evaluated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production&lt;/strong&gt; — the approved immutable version that represents the single current production baseline.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These names are a team convention, not a mandatory Studio state machine. What matters is that each state has explicit entry criteria, approval is attached to one exact version, and only one version represents the current production baseline for an asset.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run every release in seven version-linked steps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Freeze the current baseline before you change anything
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Record the production version and rollback target before editing.&lt;/strong&gt; At minimum, capture the asset name, owner, production version ID, production label, latest release time, and previous known-good version.&lt;/p&gt;

&lt;p&gt;Without that baseline, even a passing candidate cannot be compared against a reliable starting point. During an incident, the team also has to guess what it should restore.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Create a candidate instead of overwriting production
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Save every change as a new immutable version and state why it exists, what should change, and what must not change.&lt;/strong&gt; A useful change note answers three questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which user, policy, or operational problem triggered the work?&lt;/li&gt;
&lt;li&gt;Which behavior is expected to change?&lt;/li&gt;
&lt;li&gt;Which existing behaviors must remain unchanged?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;“Improve the Prompt” cannot guide a test. A useful note is more like: “When the order number is missing, ask for it before proceeding; do not change the refund-policy answer or the JSON field names.”&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Define pass conditions before running a fixed case set
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Do not decide which version ‘looks better’; give every case an observable pass condition.&lt;/strong&gt; Fixed cases make versions face the same inputs and stop reviewers from selecting only favorable examples.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Change type&lt;/th&gt;
&lt;th&gt;Test first&lt;/th&gt;
&lt;th&gt;Cost of choosing too narrow a test scope&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tone or wording&lt;/td&gt;
&lt;td&gt;Normal requests, brand voice, prohibited phrasing&lt;/td&gt;
&lt;td&gt;A few polished examples can hide old failures on edge inputs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Policy or refusal rules&lt;/td&gt;
&lt;td&gt;Allowed, refused, escalated, and insufficient-information cases&lt;/td&gt;
&lt;td&gt;A request that should be refused may pass, or a normal request may be blocked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tool use&lt;/td&gt;
&lt;td&gt;Tool choice, parameters, failure paths, permission boundaries&lt;/td&gt;
&lt;td&gt;The text may look fine while the Skill calls the wrong tool or sends bad arguments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Structured output&lt;/td&gt;
&lt;td&gt;Required fields, types, enum values, downstream compatibility&lt;/td&gt;
&lt;td&gt;Downstream parsing fails, often later than a visible wording regression&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Historical bug fix&lt;/td&gt;
&lt;td&gt;The original failure and nearby cases&lt;/td&gt;
&lt;td&gt;One example is fixed while an older behavior breaks again&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A practical minimum covers normal requests, missing or ambiguous input, policy and safety boundaries, tool and output contracts, and previous regression cases. High-risk assets need a broader set. A low-risk internal tool may begin smaller, but every case still needs a clear decision rule.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Review the exact diff, then approve the exact version
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;A Reviewer should approve one immutable version, not a Draft that can keep changing after review.&lt;/strong&gt; Use version comparison to confirm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;only the intended instructions changed;&lt;/li&gt;
&lt;li&gt;policy, tone, tool permissions, and output structure did not shift unexpectedly;&lt;/li&gt;
&lt;li&gt;the new rules do not conflict with each other;&lt;/li&gt;
&lt;li&gt;the test evidence belongs to this exact candidate;&lt;/li&gt;
&lt;li&gt;the rollback target still exists and is usable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If someone changes one sentence after approval, create another version and rerun the affected checks instead of reusing the old approval.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Point the production label only at an approved version
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Promote the candidate to &lt;code&gt;Production&lt;/code&gt; only after tests and approval are complete.&lt;/strong&gt; At minimum, the pipeline should verify the candidate version ID, approval record, test result, and whether the production baseline still matches the one that was reviewed.&lt;/p&gt;

&lt;p&gt;If another release changed production after approval, stop and compare again. Silently overwriting that newer baseline can erase somebody else’s change and makes the earlier approval irrelevant.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Observe the release with existing metrics and trace anomalies to a version
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;A release needs an explicit observation window, not just a successful promotion.&lt;/strong&gt; Use Observability, lineage, and telemetry to connect abnormal output to the relevant Prompt or Skill version, then apply the quality, compliance, latency, or cost indicators your organization already uses.&lt;/p&gt;

&lt;p&gt;Mistral does not publish a universal threshold for every task, so do not copy one arbitrary percentage. A customer-service Prompt might track incorrect policy answers and human escalation. A tool-using Skill might track invocation failures, invalid parameters, and downstream parse errors. Record the time window, affected scope, representative anomalies, and decision owner.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Close a healthy release or enter rollback immediately
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;If the observation window is healthy, preserve the candidate, tests, approver, and promotion time; if behavior clearly regresses, execute the prepared rollback.&lt;/strong&gt; Do not wait for an incident to decide for the first time who may roll back, which version to restore, and which checks confirm recovery.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write the rollback playbook before the release
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A minimum rollback playbook is usable if it answers what to pause, which version to find, how to restore it, and how to confirm recovery.&lt;/strong&gt; Run it in this order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pause new promotions so the production baseline cannot move again.&lt;/li&gt;
&lt;li&gt;Use lineage to identify the asset and production version connected to the anomaly.&lt;/li&gt;
&lt;li&gt;Compare the problematic version with the previous known-good version and confirm the rollback scope.&lt;/li&gt;
&lt;li&gt;Restore the known-good version or point the production label back to it.&lt;/li&gt;
&lt;li&gt;Rerun critical cases and inspect the necessary production indicators to confirm recovery.&lt;/li&gt;
&lt;li&gt;Preserve the failed version, triggering evidence, and post-incident conclusion instead of deleting history.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Rollback is not deletion. Keeping the failed version allows the team to explain what changed, who approved it, why the original tests passed, and which cases should be added next time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep one minimum record for every release
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;When these fields are available in one place, an incident review does not have to reconstruct the story from chats and tickets.&lt;/strong&gt; You can start with a structured table rather than a large governance platform.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Question it must answer&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Asset&lt;/td&gt;
&lt;td&gt;Which Prompt or Skill is this, and what job does it perform?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Owner&lt;/td&gt;
&lt;td&gt;Who is ultimately accountable for production behavior?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production version&lt;/td&gt;
&lt;td&gt;Which immutable version was active before the change?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Candidate version&lt;/td&gt;
&lt;td&gt;Which exact version was tested and approved?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Change reason&lt;/td&gt;
&lt;td&gt;Which user problem, policy change, or incident triggered it?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test set and result&lt;/td&gt;
&lt;td&gt;Which fixed cases ran, and which passed or failed?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reviewer and approval time&lt;/td&gt;
&lt;td&gt;Who approved which exact version, and when?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Promotion time&lt;/td&gt;
&lt;td&gt;When did it enter production, and who performed the action?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rollback target&lt;/td&gt;
&lt;td&gt;Which known-good version will be restored after regression?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observation / incident link&lt;/td&gt;
&lt;td&gt;Where is the post-release observation or incident record?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Start with one high-impact asset, not a company-wide rollout
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Choose a Prompt or Skill that affects real users, changes frequently, and has already shown behavioral drift.&lt;/strong&gt; It will expose gaps in the process quickly and show whether version tracing and rollback actually work.&lt;/p&gt;

&lt;p&gt;Start by naming one Owner, identifying the current production and rollback versions, building 10–20 fixed regression cases, and defining entry criteria for Draft, Staging, and Production. Then run one candidate release and one rollback exercise. Confirm that the audit log answers who changed what and when, and that lineage maps a production output to the correct version.&lt;/p&gt;

&lt;p&gt;Once that loop works reliably, copy it to the next asset. Measure progress by the number of assets that truly have an owner, tests, a release chain, and a rollback path—not by the length of the governance document.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recheck the current Studio UI, SDK, and permissions before implementation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mistral's announcement describes versions, owners, labels, audit logs, comparison and rollback, Observability, lineage, workspace sharing, and MCP delivery for Skills, but implementation details should come from the current documentation.&lt;/strong&gt; Label-promotion APIs, permission models, CI/CD configuration, and interface locations can change as the product evolves.&lt;/p&gt;

&lt;p&gt;The announcement also does not provide a universal task success rate, measured quality gain, or standard rollback threshold. Your final release decision therefore needs to come from your own fixed cases and production indicators, not from treating a feature list as test evidence.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mistral.ai/news/manage-prompts-and-skills-in-studio/" rel="noopener noreferrer"&gt;Mistral announcement: Manage prompts and skills in Studio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.mistral.ai/getting-started/quickstarts/studio/create-reusable-prompt" rel="noopener noreferrer"&gt;Create reusable prompts in Studio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.mistral.ai/getting-started/quickstarts/studio/create-skill" rel="noopener noreferrer"&gt;Create reusable skills in Studio&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bettertoken.ai/en/blog/mistral-studio-prompt-skill-version-control/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=mistral-studio-versii-promptov-i-skillov&amp;amp;utm_content=mistral-studio-prompt-skill-version-control" rel="noopener noreferrer"&gt;BetterToken blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;BetterToken provides pay-as-you-go access to AI model APIs through&lt;br&gt;
OpenAI-compatible and Anthropic-compatible endpoints — useful if you are wiring&lt;br&gt;
Claude Code, Codex, or your own tooling to a custom base URL.&lt;br&gt;
See the &lt;a href="https://docs.bettertoken.ai/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=mistral-studio-versii-promptov-i-skillov&amp;amp;utm_content=mistral-studio-prompt-skill-version-control" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to get started.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>GPT-6 Luna vs GPT-5.6 Luna: Calculating the Real Cost of a Successful Codex Task</title>
      <dc:creator>Adela</dc:creator>
      <pubDate>Mon, 28 Sep 2026 06:23:02 +0000</pubDate>
      <link>https://dev.to/bettertoken_ai/gpt-6-luna-vs-gpt-56-luna-calculating-the-real-cost-of-a-successful-codex-task-5h1h</link>
      <guid>https://dev.to/bettertoken_ai/gpt-6-luna-vs-gpt-56-luna-calculating-the-real-cost-of-a-successful-codex-task-5h1h</guid>
      <description>&lt;p&gt;You are not trying to decide which Luna generation sounds newer; you need to know which model should run the next batch of Codex tasks and when to switch after a failure. By the end, you can choose a first candidate from per-attempt cost, then use acceptance rate, retries, and manual-repair time to calculate the real cost of each successful task.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start here: test &lt;code&gt;gpt-6-luna&lt;/code&gt; first for most automatically verifiable tasks
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;gpt-6-luna&lt;/code&gt; is the better first candidate when the scope is clear and tests, lint, or an acceptance script can reject a bad result quickly. Its lower per-attempt token cost lets you build a baseline cheaply, then decide whether complex work should move back to &lt;code&gt;gpt-5.6-luna&lt;/code&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your situation&lt;/th&gt;
&lt;th&gt;What to do first&lt;/th&gt;
&lt;th&gt;What would change the recommendation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Small fixes or batch changes with automated tests&lt;/td&gt;
&lt;td&gt;Start with &lt;code&gt;gpt-6-luna&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;It fails repeatedly, or manual repair erases the price advantage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-file features, refactors, or interface changes&lt;/td&gt;
&lt;td&gt;Run paired tests on both models&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;gpt-5.6-luna&lt;/code&gt; for this class if it materially cuts retries and repair time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Input is near or above 272K&lt;/td&gt;
&lt;td&gt;Remove irrelevant files, shorten history, or split the task first&lt;/td&gt;
&lt;td&gt;If context cannot be reduced, compare with long-context rates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You are using ChatGPT or Codex plan allowances&lt;/td&gt;
&lt;td&gt;Use the plan dashboard and credit rules, not the API table&lt;/td&gt;
&lt;td&gt;Apply the token prices below only after moving to an API key or custom provider&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Public information does not yet include paired results for both models on the same Codex version, repository, and reasoning effort. Price can determine your testing order, but your own task data should determine the default model.&lt;/p&gt;

&lt;h2&gt;
  
  
  The interface limits are similar, so they do not predict coding quality
&lt;/h2&gt;

&lt;p&gt;The two models have similar core interfaces and context limits, so the specification sheet cannot tell you which one will be more reliable in your codebase. Both support text and image input, text output, the Responses API, reasoning tokens, and reasoning effort from &lt;code&gt;none&lt;/code&gt; through &lt;code&gt;max&lt;/code&gt;; each has a 1,050,000-token context window, a maximum input of 922,000 tokens, and a maximum output of 128,000 tokens.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;&lt;code&gt;gpt-6-luna&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;gpt-5.6-luna&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Official positioning&lt;/td&gt;
&lt;td&gt;Efficient model for focused, high-volume tasks&lt;/td&gt;
&lt;td&gt;Model for cost-sensitive, high-volume workloads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Knowledge cutoff&lt;/td&gt;
&lt;td&gt;2026-05-18&lt;/td&gt;
&lt;td&gt;2026-02-16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Context window&lt;/td&gt;
&lt;td&gt;1,050,000 tokens&lt;/td&gt;
&lt;td&gt;1,050,000 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default reasoning effort&lt;/td&gt;
&lt;td&gt;&lt;code&gt;medium&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;medium&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Those specifications do not prove that either model will have a higher acceptance rate, finish faster, or require fewer retries in your codebase. Codex outcomes also depend on task shape, context quality, tool permissions, client version, reasoning effort, and the acceptance criteria you apply.&lt;/p&gt;

&lt;h2&gt;
  
  
  Below 272K, &lt;code&gt;gpt-6-luna&lt;/code&gt; has the lower token rates
&lt;/h2&gt;

&lt;p&gt;When complete input context is at or below 272K, &lt;code&gt;gpt-6-luna&lt;/code&gt; costs half as much for input, cache reads, and cache writes, while its output rate is about 41.7% of &lt;code&gt;gpt-5.6-luna&lt;/code&gt;. The table was verified on &lt;strong&gt;2026-09-25&lt;/strong&gt;, uses &lt;strong&gt;USD per 1 million tokens&lt;/strong&gt;, and compares only OpenAI Standard with BetterToken API billing—not ChatGPT or Codex plan allowances or credit billing.&lt;/p&gt;

&lt;h3&gt;
  
  
  At or below 272K: calculate directly from this table
&lt;/h3&gt;

&lt;p&gt;Use this tier directly when the complete input context of each request stays at or below 272K; do not apply the long-context multipliers.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model ID&lt;/th&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Cache read&lt;/th&gt;
&lt;th&gt;Cache write&lt;/th&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-luna&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAI Standard&lt;/td&gt;
&lt;td&gt;$0.10&lt;/td&gt;
&lt;td&gt;$0.01&lt;/td&gt;
&lt;td&gt;$0.125&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-luna&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;BetterToken&lt;/td&gt;
&lt;td&gt;$0.068&lt;/td&gt;
&lt;td&gt;$0.0068&lt;/td&gt;
&lt;td&gt;$0.085&lt;/td&gt;
&lt;td&gt;$0.34&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-5.6-luna&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAI Standard&lt;/td&gt;
&lt;td&gt;$0.20&lt;/td&gt;
&lt;td&gt;$0.02&lt;/td&gt;
&lt;td&gt;$0.25&lt;/td&gt;
&lt;td&gt;$1.20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-5.6-luna&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;BetterToken&lt;/td&gt;
&lt;td&gt;$0.136&lt;/td&gt;
&lt;td&gt;$0.0136&lt;/td&gt;
&lt;td&gt;$0.17&lt;/td&gt;
&lt;td&gt;$0.816&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;BetterToken prices are dynamic, so &lt;a href="https://bettertoken.ai/pricing?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=gpt-6-luna-vs-gpt-5-6-luna-codex-stoimost-zadachi&amp;amp;utm_content=gpt-6-luna-vs-gpt-5-6-luna-codex-task-cost" rel="noopener noreferrer"&gt;view current prices&lt;/a&gt; on the day you publish or buy and use the values shown then. BetterToken is not an OpenAI product. The prices above are for its GPT group used through APIs, Codex, and tools that support a custom Base URL; they are not ChatGPT or Codex subscription allowances.&lt;/p&gt;

&lt;p&gt;OpenAI Batch and Flex are priced at 50% of Standard for these models, so they are lower than the BetterToken rates shown here. They are outside this comparison. The table must not be read as a claim that BetterToken is cheaper than every OpenAI processing option.&lt;/p&gt;

&lt;h3&gt;
  
  
  Above 272K: reduce the input first, then use long-context rates if needed
&lt;/h3&gt;

&lt;p&gt;If the task can be split, remove irrelevant files, shorten history, or divide the work before crossing the threshold because the entire request becomes more expensive. The threshold uses the complete input context, including cached portions; above 272K, input, cache reads, and cache writes cost 2× the short-context rate, while output costs 1.5×:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model ID&lt;/th&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Cache read&lt;/th&gt;
&lt;th&gt;Cache write&lt;/th&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-luna&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAI Standard&lt;/td&gt;
&lt;td&gt;$0.20&lt;/td&gt;
&lt;td&gt;$0.02&lt;/td&gt;
&lt;td&gt;$0.25&lt;/td&gt;
&lt;td&gt;$0.75&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-luna&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;BetterToken&lt;/td&gt;
&lt;td&gt;$0.136&lt;/td&gt;
&lt;td&gt;$0.0136&lt;/td&gt;
&lt;td&gt;$0.17&lt;/td&gt;
&lt;td&gt;$0.51&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-5.6-luna&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAI Standard&lt;/td&gt;
&lt;td&gt;$0.40&lt;/td&gt;
&lt;td&gt;$0.04&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;$1.80&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-5.6-luna&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;BetterToken&lt;/td&gt;
&lt;td&gt;$0.272&lt;/td&gt;
&lt;td&gt;$0.0272&lt;/td&gt;
&lt;td&gt;$0.34&lt;/td&gt;
&lt;td&gt;$1.224&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Separate four token categories to reproduce the cost of one attempt
&lt;/h2&gt;

&lt;p&gt;To calculate one Codex attempt, keep uncached input, cache reads, cache writes, and output separate. The shared usage profile below demonstrates the method; replace these hypothetical numbers with your own billing details to get your actual per-attempt cost:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;32,000 uncached input tokens;&lt;/li&gt;
&lt;li&gt;160,000 cache-read tokens;&lt;/li&gt;
&lt;li&gt;16,000 cache-write tokens;&lt;/li&gt;
&lt;li&gt;8,000 output tokens;&lt;/li&gt;
&lt;li&gt;a complete input context at or below 272K for every request, so short-context rates apply.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The formula is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task cost = uncached input / 1,000,000 × input price
          + cache read / 1,000,000 × cache-read price
          + cache write / 1,000,000 × cache-write price
          + output / 1,000,000 × output price
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model ID&lt;/th&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Input cost&lt;/th&gt;
&lt;th&gt;Cache-read cost&lt;/th&gt;
&lt;th&gt;Cache-write cost&lt;/th&gt;
&lt;th&gt;Output cost&lt;/th&gt;
&lt;th&gt;Total per attempt&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-luna&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAI Standard&lt;/td&gt;
&lt;td&gt;$0.003200&lt;/td&gt;
&lt;td&gt;$0.001600&lt;/td&gt;
&lt;td&gt;$0.002000&lt;/td&gt;
&lt;td&gt;$0.004000&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0.010800&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-luna&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;BetterToken&lt;/td&gt;
&lt;td&gt;$0.002176&lt;/td&gt;
&lt;td&gt;$0.001088&lt;/td&gt;
&lt;td&gt;$0.001360&lt;/td&gt;
&lt;td&gt;$0.002720&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0.007344&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-5.6-luna&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAI Standard&lt;/td&gt;
&lt;td&gt;$0.006400&lt;/td&gt;
&lt;td&gt;$0.003200&lt;/td&gt;
&lt;td&gt;$0.004000&lt;/td&gt;
&lt;td&gt;$0.009600&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0.023200&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-5.6-luna&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;BetterToken&lt;/td&gt;
&lt;td&gt;$0.004352&lt;/td&gt;
&lt;td&gt;$0.002176&lt;/td&gt;
&lt;td&gt;$0.002720&lt;/td&gt;
&lt;td&gt;$0.006528&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0.015776&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;With this hypothetical token structure, one &lt;code&gt;gpt-6-luna&lt;/code&gt; attempt costs about &lt;strong&gt;46.6%&lt;/strong&gt; of one &lt;code&gt;gpt-5.6-luna&lt;/code&gt; attempt. BetterToken applies the same price multiplier to both models, so the ratio between the two models is identical on both providers. This is still a cost per attempt, not a cost per successful task.&lt;/p&gt;

&lt;h2&gt;
  
  
  Count cache reads separately or you will overstate or understate cost
&lt;/h2&gt;

&lt;p&gt;Do not charge cache reads at the ordinary input rate, and do not omit them from the bill. Codex repeatedly reads repository context, conversation history, and tool output; cached tokens are usually cheaper, but their volume can be large, so one combined “input” number gives the wrong answer.&lt;/p&gt;

&lt;p&gt;For every run, retain separate values for &lt;code&gt;input&lt;/code&gt;, &lt;code&gt;cached input&lt;/code&gt;, &lt;code&gt;cache write&lt;/code&gt;, and &lt;code&gt;output&lt;/code&gt;. If an access layer exposes only a final dollar amount and not the four token categories, it becomes much harder to explain why one model or task costs more than another.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose the default model by cost per successful task
&lt;/h2&gt;

&lt;p&gt;A cheaper call does not guarantee a cheaper completed task; include the API cost of failures, rollbacks, and retries. The more useful metric is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cost per successful task = total API cost of all attempts / accepted tasks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Track at least these dimensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Acceptance rate:&lt;/strong&gt; the share of tasks that pass the predefined criteria without a developer rewriting the solution;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retries:&lt;/strong&gt; repeated prompts, rollbacks, or fresh model runs for the same task;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Elapsed time:&lt;/strong&gt; time from task start to an acceptable diff, not merely first-token latency;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual repair:&lt;/strong&gt; whether and how long a developer had to edit generated code;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token mix:&lt;/strong&gt; uncached input, cache reads, cache writes, and output.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the hypothetical OpenAI Standard costs above, the per-attempt ratio is &lt;code&gt;0.010800 / 0.023200 ≈ 46.6%&lt;/code&gt;. If the token profile stayed identical, &lt;code&gt;gpt-6-luna&lt;/code&gt; would still have a lower expected API cost whenever its acceptance rate exceeded roughly 46.6% of the &lt;code&gt;gpt-5.6-luna&lt;/code&gt; acceptance rate. This is only a break-even relationship derived from hypothetical prices, not a measured quality claim. The threshold changes when token use, retries, or task mix changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fix five conditions before trusting the comparison
&lt;/h2&gt;

&lt;p&gt;Running each model once is not a valid comparison; both must start from the same state, receive comparable tasks, and face the same acceptance criteria. These five steps reduce bias from caching, run order, and human judgment.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Freeze the environment
&lt;/h3&gt;

&lt;p&gt;Use the same Codex version, starting Git commit, configuration, tool permissions, reasoning effort, prompt, and acceptance command for both models. Do not call one model through OpenAI Standard and the other through a different access path, then attribute every latency or failure difference to the model.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Separate task categories
&lt;/h3&gt;

&lt;p&gt;At minimum, keep three task classes distinct:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task class&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Suggested acceptance criteria&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Small fix&lt;/td&gt;
&lt;td&gt;A well-defined defect in one or a few files&lt;/td&gt;
&lt;td&gt;Targeted tests pass; unrelated files remain unchanged&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-file change&lt;/td&gt;
&lt;td&gt;Feature, refactor, or coordinated interface change&lt;/td&gt;
&lt;td&gt;Full tests and lint pass; requested behavior is present&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Review and diagnosis&lt;/td&gt;
&lt;td&gt;Find a bug, explain risk, propose a fix&lt;/td&gt;
&lt;td&gt;Finds the known issue and points to concrete code evidence&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Do not collapse all three into one average. Two models may be nearly equal on small fixes but differ materially in retry rate on cross-file work.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Define acceptance before running the model
&lt;/h3&gt;

&lt;p&gt;Before testing, fix the required tests, allowed directories, dependency policy, and failure conditions. Lowering the bar after seeing an output makes the acceptance rate meaningless.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Alternate model order
&lt;/h3&gt;

&lt;p&gt;Do not always run the same model first. Alternate the order, or use equivalent independent tasks when possible, so first-run caching, environment repair, and operator familiarity do not systematically favor one model.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Preserve per-task records
&lt;/h3&gt;

&lt;p&gt;A useful row contains: task ID, task class, model ID, provider, processing tier, reasoning effort, start and end time, the four token categories, attempt count, pass/fail result, failure reason, manual-repair minutes, and final cost. Aggregate by task class only after retaining the raw rows.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to keep &lt;code&gt;gpt-6-luna&lt;/code&gt; and when to switch to &lt;code&gt;gpt-5.6-luna&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Keep &lt;code&gt;gpt-6-luna&lt;/code&gt; as the default candidate while its acceptance rate remains high enough to preserve the price advantage and manual-repair time is comparable. When the results differ by task class, route the work instead of forcing one global model on every task.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What you observe&lt;/th&gt;
&lt;th&gt;Recommended action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;gpt-6-luna&lt;/code&gt; acceptance exceeds roughly 46.6% of &lt;code&gt;gpt-5.6-luna&lt;/code&gt; acceptance, with similar token profiles and repair time&lt;/td&gt;
&lt;td&gt;Keep &lt;code&gt;gpt-6-luna&lt;/code&gt;; its expected API cost is lower&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;gpt-6-luna&lt;/code&gt; falls below that break-even point, or retries and repair make total cost higher&lt;/td&gt;
&lt;td&gt;Move that task class to &lt;code&gt;gpt-5.6-luna&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;gpt-6-luna&lt;/code&gt; wins on small fixes but &lt;code&gt;gpt-5.6-luna&lt;/code&gt; causes less rework on cross-file changes&lt;/td&gt;
&lt;td&gt;Route by task class rather than choosing one universal default&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The difference mostly comes from provider latency, errors, or rate limits&lt;/td&gt;
&lt;td&gt;Rerun through the same access path before blaming the model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Input frequently exceeds 272K&lt;/td&gt;
&lt;td&gt;Optimize context and test again; do not treat a pricing-tier jump as a quality difference&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The 46.6% threshold applies only to the hypothetical token profile above. If output length, cache usage, or retry count differs, recalculate the break-even point from each model’s actual per-attempt cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recommendation: baseline with &lt;code&gt;gpt-6-luna&lt;/code&gt;, then decide from successful-task cost
&lt;/h2&gt;

&lt;p&gt;If you must choose one model today, start clear, automatically verifiable work with &lt;code&gt;gpt-6-luna&lt;/code&gt;. Keep a representative sample of complex tasks for a same-condition &lt;code&gt;gpt-5.6-luna&lt;/code&gt; control; do not stop at comparing the price of one call.&lt;/p&gt;

&lt;p&gt;After a batch of comparable tasks, calculate acceptance rate, average retries, manual-repair time, and cost per successful task. Keep &lt;code&gt;gpt-6-luna&lt;/code&gt; as the default when it remains cheaper; if &lt;code&gt;gpt-5.6-luna&lt;/code&gt; removes enough rework to cover its higher token rate for a specific task class, route only that class to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Official references
&lt;/h2&gt;

&lt;p&gt;Use these three official pages to recheck model specifications and OpenAI pricing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developers.openai.com/api/docs/models/gpt-6-luna" rel="noopener noreferrer"&gt;GPT-6 Luna model page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.openai.com/api/docs/models/gpt-5.6-luna" rel="noopener noreferrer"&gt;GPT-5.6 Luna model page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.openai.com/api/docs/pricing" rel="noopener noreferrer"&gt;OpenAI API pricing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bettertoken.ai/en/blog/gpt-6-luna-vs-gpt-5-6-luna-codex-task-cost/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=gpt-6-luna-vs-gpt-5-6-luna-codex-stoimost-zadachi&amp;amp;utm_content=gpt-6-luna-vs-gpt-5-6-luna-codex-task-cost" rel="noopener noreferrer"&gt;BetterToken blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;BetterToken provides pay-as-you-go access to AI model APIs through&lt;br&gt;
OpenAI-compatible and Anthropic-compatible endpoints — useful if you are wiring&lt;br&gt;
Claude Code, Codex, or your own tooling to a custom base URL.&lt;br&gt;
See the &lt;a href="https://docs.bettertoken.ai/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=gpt-6-luna-vs-gpt-5-6-luna-codex-stoimost-zadachi&amp;amp;utm_content=gpt-6-luna-vs-gpt-5-6-luna-codex-task-cost" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to get started.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>GPT-6 Astra vs Sol vs Luna: Choose by Task Difficulty and Total Cost</title>
      <dc:creator>Adela</dc:creator>
      <pubDate>Mon, 28 Sep 2026 06:21:00 +0000</pubDate>
      <link>https://dev.to/bettertoken_ai/gpt-6-astra-vs-sol-vs-luna-choose-by-task-difficulty-and-total-cost-41n3</link>
      <guid>https://dev.to/bettertoken_ai/gpt-6-astra-vs-sol-vs-luna-choose-by-task-difficulty-and-total-cost-41n3</guid>
      <description>&lt;p&gt;You may already know that Luna is the cheapest and Astra is the most capable, but that still does not tell you whether this task is worth a 20× or 100× jump in token price. &lt;strong&gt;Use this default: start verifiable, high-volume work on Luna, complex coding and ordinary agentic workflows on Sol, and ambiguous or expensive-to-fail end-to-end work on Astra.&lt;/strong&gt; By the end, you will know where to start, which failure signals justify escalation, and how to compare the same token workload on OpenAI Standard and BetterToken.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start here: Luna for verifiable volume, Sol for complex builds, Astra for costly mistakes
&lt;/h2&gt;

&lt;p&gt;Choose the starting model from task boundaries and failure cost, then revise that default with your own acceptance data.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;OpenAI positioning&lt;/th&gt;
&lt;th&gt;Good initial candidates&lt;/th&gt;
&lt;th&gt;Escalate when&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-luna&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;An efficient model for focused, high-volume tasks&lt;/td&gt;
&lt;td&gt;Small scoped edits, structured extraction, classification, format conversion, tests from a clear specification, and batch work with deterministic validation&lt;/td&gt;
&lt;td&gt;Validation repeatedly fails; cross-file reasoning is required; the tool chain grows; a critical ambiguity remains&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-sol&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Built for complex coding and agentic workflows&lt;/td&gt;
&lt;td&gt;Multi-file feature work, debugging, code review, repository tasks with several tool calls, and moderately complex research or documentation with clear boundaries&lt;/td&gt;
&lt;td&gt;A wrong plan has high impact; repeated plans miss key constraints; the task requires cross-system trade-offs or difficult research&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-astra&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAI's most capable model for the hardest end-to-end work&lt;/td&gt;
&lt;td&gt;Architecture decisions, complex migrations, cross-system incident analysis, high-risk code changes, and long workflows combining research, document creation, or computer use&lt;/td&gt;
&lt;td&gt;Astra is already the top tier in this group; if it still fails, narrow the task, add evidence, or introduce a human decision point instead of escalating by name&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The goal is not to declare that Luna must handle every “easy” task. The goal is to choose the &lt;strong&gt;least expensive model that consistently clears the required quality bar&lt;/strong&gt;. A cheaper model that triggers repeated retries can cost more in the end. Conversely, starting every well-specified task with Astra may pay for capability the workflow never uses.&lt;/p&gt;

&lt;p&gt;Public documentation does not yet include an independent comparison of Astra, Sol, and Luna on the same real tasks. Treat this matrix as an actionable starting point, then record first-pass acceptance, retries, actual elapsed time to an accepted result, and total cost per accepted task.&lt;/p&gt;

&lt;h2&gt;
  
  
  Similar context limits do not make the models interchangeable
&lt;/h2&gt;

&lt;p&gt;The three models have similar context and tool envelopes, so task shape, reasoning configuration, and failure cost matter more than context-window size. OpenAI positions Astra for complex reasoning, coding, computer use, research, and document creation; Sol for complex coding and agentic workflows; and Luna for focused, high-volume work. Those descriptions help select the first candidate, but your task results must decide the default.&lt;/p&gt;

&lt;p&gt;All three models have a 1,050,000-token context window, a maximum input of 922,000 tokens, and a maximum output of 128,000 tokens. Context capacity alone therefore does not separate them. More practical differences include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Astra supports &lt;code&gt;reasoning.effort&lt;/code&gt; values of &lt;code&gt;low&lt;/code&gt;, &lt;code&gt;medium&lt;/code&gt;, &lt;code&gt;high&lt;/code&gt;, &lt;code&gt;xhigh&lt;/code&gt;, and &lt;code&gt;max&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Sol and Luna also support &lt;code&gt;none&lt;/code&gt;, with &lt;code&gt;medium&lt;/code&gt; as the default. For tightly bounded tasks, testing a lower reasoning level can reveal whether cost comes from the model choice or from unnecessary reasoning.&lt;/li&gt;
&lt;li&gt;For tool-heavy agent workflows, prefer the Responses API. With Sol and Luna, Chat Completions function calling requires &lt;code&gt;reasoning_effort&lt;/code&gt; to be &lt;code&gt;none&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Model choice, context, reasoning, tool use, retrieval, and caching all affect usage. Prompt length alone is not a reliable proxy for task cost.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A fair comparison therefore fixes the interface, context, tools, reasoning effort, maximum output, and acceptance checks. If several of those change at the same time, the observed difference may be a configuration effect rather than a model effect.&lt;/p&gt;

&lt;h2&gt;
  
  
  For the same tokens, compare BetterToken with OpenAI Standard
&lt;/h2&gt;

&lt;p&gt;For identical token usage, the BetterToken rates verified on 2026-09-24 were 68% of the corresponding OpenAI Standard rates. That does not make it the cheapest route in every case: OpenAI Batch and Flex are lower, while retries, tools, and human rework still determine full cost. The table uses USD per 1 million tokens and shows the rates for input context at or below 272K.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model ID&lt;/th&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Cached input read&lt;/th&gt;
&lt;th&gt;Cache write&lt;/th&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-astra&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAI Standard&lt;/td&gt;
&lt;td&gt;$10.00&lt;/td&gt;
&lt;td&gt;$1.00&lt;/td&gt;
&lt;td&gt;$12.50&lt;/td&gt;
&lt;td&gt;$50.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-astra&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;BetterToken&lt;/td&gt;
&lt;td&gt;$6.80&lt;/td&gt;
&lt;td&gt;$0.68&lt;/td&gt;
&lt;td&gt;$8.50&lt;/td&gt;
&lt;td&gt;$34.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-sol&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAI Standard&lt;/td&gt;
&lt;td&gt;$2.00&lt;/td&gt;
&lt;td&gt;$0.20&lt;/td&gt;
&lt;td&gt;$2.50&lt;/td&gt;
&lt;td&gt;$10.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-sol&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;BetterToken&lt;/td&gt;
&lt;td&gt;$1.36&lt;/td&gt;
&lt;td&gt;$0.136&lt;/td&gt;
&lt;td&gt;$1.70&lt;/td&gt;
&lt;td&gt;$6.80&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-luna&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAI Standard&lt;/td&gt;
&lt;td&gt;$0.10&lt;/td&gt;
&lt;td&gt;$0.01&lt;/td&gt;
&lt;td&gt;$0.125&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-luna&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;BetterToken&lt;/td&gt;
&lt;td&gt;$0.068&lt;/td&gt;
&lt;td&gt;$0.0068&lt;/td&gt;
&lt;td&gt;$0.085&lt;/td&gt;
&lt;td&gt;$0.34&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When a request exceeds 272K input context, all three GPT-6 models move to the long-context tier on both services: &lt;strong&gt;input, cached input read, and cache-write rates become 2× the table values, while output becomes 1.5×, for the full request.&lt;/strong&gt; For example, long-context &lt;code&gt;gpt-6-sol&lt;/code&gt; costs $4.00/$0.40/$5.00/$15.00 on OpenAI Standard and $2.72/$0.272/$3.40/$10.20 on BetterToken for input/cached read/cache write/output.&lt;/p&gt;

&lt;p&gt;Prices are dynamic. Before deploying, &lt;a href="https://bettertoken.ai/pricing?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=gpt-6-astra-sol-luna-kak-vybrat-model&amp;amp;utm_content=gpt-6-astra-sol-luna-how-to-choose" rel="noopener noreferrer"&gt;view current prices&lt;/a&gt; and recheck model availability, currency, and the applicable tier. OpenAI Batch and Flex currently cost 50% of Standard and are lower than the BetterToken rates in this snapshot; use them when asynchronous or lower-priority processing fits the workload. The table also excludes regional-processing premiums, tool-call fees, container charges, and retries.&lt;/p&gt;

&lt;p&gt;BetterToken's GPT group can be used through the API, Codex, and external tools that support a custom Base URL. BetterToken is not an OpenAI product, and its API usage is not the same as ChatGPT or Codex subscription messages, included plan capacity, or credits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Already on GPT-5.5? Keep the baseline before switching
&lt;/h2&gt;

&lt;p&gt;If your GPT-5.5 workflow is stable, do not switch only because the model family changed. Preserve its quality, elapsed-time, and cost baseline, then replay the same tasks on Sol, Luna, and Astra. The prices below are USD per 1 million tokens, verified on 2026-09-24.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model ID&lt;/th&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;Context&lt;/th&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Cached input read&lt;/th&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-5.5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAI Standard&lt;/td&gt;
&lt;td&gt;≤ 272K&lt;/td&gt;
&lt;td&gt;$5.00&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;$30.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-5.5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAI Standard&lt;/td&gt;
&lt;td&gt;&amp;gt; 272K&lt;/td&gt;
&lt;td&gt;$10.00&lt;/td&gt;
&lt;td&gt;$1.00&lt;/td&gt;
&lt;td&gt;$45.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-5.5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;BetterToken&lt;/td&gt;
&lt;td&gt;No tiers&lt;/td&gt;
&lt;td&gt;$3.40&lt;/td&gt;
&lt;td&gt;$0.34&lt;/td&gt;
&lt;td&gt;$20.40&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;BetterToken does not apply a separate long-context tier to &lt;code&gt;gpt-5.5&lt;/code&gt;; OpenAI Standard does above 272K. A cache-write price is not listed because OpenAI’s published GPT-5.5 pricing row does not provide one; it is left blank rather than estimated.&lt;/p&gt;

&lt;p&gt;There are also two different migration questions. OpenAI says GPT-5.5 will retire from ChatGPT, ChatGPT Work, and Codex on all plans on &lt;strong&gt;2026-10-14&lt;/strong&gt;, while the OpenAI API is unaffected. Codex plan users therefore need a replacement path before that date. API-key workloads do not need to migrate solely because of the plan-side retirement. Codex plan allowances, additional credits, and USD-priced API usage are separate accounting systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  The useful metric is cost per accepted task
&lt;/h2&gt;

&lt;p&gt;A single-call price cannot tell you which model is cheaper to finish the job. Count failed attempts, retries, cache writes, tool charges, and human rework, then divide the total by accepted results. The example below first isolates the two billing paths with the same token mix.&lt;/p&gt;

&lt;p&gt;Assume one accepted run uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;120,000 uncached input tokens;&lt;/li&gt;
&lt;li&gt;100,000 cached input tokens;&lt;/li&gt;
&lt;li&gt;10,000 output tokens;&lt;/li&gt;
&lt;li&gt;no new cache write in this run;&lt;/li&gt;
&lt;li&gt;220K total input context, so the short-context tier applies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using “tokens ÷ 1,000,000 × the relevant rate,” the model charge for that single run is:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model ID&lt;/th&gt;
&lt;th&gt;OpenAI Standard&lt;/th&gt;
&lt;th&gt;BetterToken&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-luna&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;$0.01800&lt;/td&gt;
&lt;td&gt;$0.01224&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-sol&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;$0.36000&lt;/td&gt;
&lt;td&gt;$0.24480&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-6-astra&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;$1.80000&lt;/td&gt;
&lt;td&gt;$1.22400&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-5.5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;$0.95000&lt;/td&gt;
&lt;td&gt;$0.64600&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This example compares billing for the same token mix; it does not compare quality, speed, or final value. With identical tokens and processing tier, Sol costs 20 times Luna and Astra costs 5 times Sol. But failed attempts, longer outputs, more tool calls, or human rework can narrow or reverse the difference in total completion cost.&lt;/p&gt;

&lt;p&gt;A more useful formula is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Completion cost = token charges across all attempts + cache-write charges + tool charges + failed retries and rework.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Divide that total by the number of accepted tasks to obtain cost per accepted result. That metric is much closer to a production routing decision than the price of one successful request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose the first model by workflow, then define escalation
&lt;/h2&gt;

&lt;p&gt;The default route can be explicit: start low-risk work with reliable automated checks on Luna, complex development on Sol, and high-risk or highly ambiguous work on Astra.&lt;/p&gt;

&lt;h3&gt;
  
  
  Verifiable, high-volume work: start with Luna
&lt;/h3&gt;

&lt;p&gt;If a schema, linter, unit test, or another deterministic rule can catch failure quickly, test Luna first. Good candidates include fixed-format transformations, extraction from known fields, local renames, tests from a precise specification, and other batch outputs with reliable automated acceptance.&lt;/p&gt;

&lt;p&gt;Escalate to Sol when validation fails, an unstated dependency appears, or the task requires a cross-module decision. Do not let a smaller model retry indefinitely in the same wrong direction.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-file coding and agent workflows: start with Sol
&lt;/h3&gt;

&lt;p&gt;When the task must understand several files, use tools in sequence, or change its plan after execution results, start with Sol. Typical examples are cross-file feature work, diagnosing test failures, searching a repository before editing, and continuing from tool output.&lt;/p&gt;

&lt;p&gt;Keep the task bounded. Explicit completion conditions such as “analyze, modify, run the most relevant tests, and report unresolved items” are usually more useful than raising &lt;code&gt;reasoning.effort&lt;/code&gt; without a plan. Move to Astra when Sol repeatedly misses architectural constraints on representative tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ambiguous or high-risk end-to-end work: start with Astra
&lt;/h3&gt;

&lt;p&gt;Start with Astra when the cost of a wrong answer clearly exceeds the model premium. Cross-system migrations, difficult production incidents, critical security boundaries, research-heavy decisions, and workflows combining coding, computer use, and a long tool chain belong in this group.&lt;/p&gt;

&lt;p&gt;Astra still requires validation. Split long work into checkpoints for the plan, evidence, changes, and verification so the strongest model does not spend more time following a bad assumption.&lt;/p&gt;

&lt;h2&gt;
  
  
  Still unsure? Compare the models on the same real tasks
&lt;/h2&gt;

&lt;p&gt;You do not need a universal fixed sample size. You do need a representative set covering normal, boundary, and failure cases, with the same acceptance rules for every model.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Choose a representative set.&lt;/strong&gt; Include small changes, multi-file development, debugging, tool use, and knowledge work instead of selecting only polished demos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Define acceptance before running.&lt;/strong&gt; Use tests, lint, schemas, a factual checklist, or human review. Changing the rubric after seeing an answer makes the comparison unreliable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hold other variables constant.&lt;/strong&gt; Use the same context, tools, API surface, reasoning effort, maximum output, and environment. Treat a different &lt;code&gt;reasoning.effort&lt;/code&gt; as a separate experiment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Record every attempt.&lt;/strong&gt; Capture first-pass acceptance, retries, actual elapsed time to an accepted result, input/cached/output tokens, tool calls, and final spend.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compute cost per accepted result.&lt;/strong&gt; Include failed attempts and human rework, not only the last successful run.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conclude by task class.&lt;/strong&gt; A model may pass coding edits but fail research or long agent runs. Do not hide that behind one global default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review after each task class has accumulated repeated real runs.&lt;/strong&gt; If a higher tier does not produce a repeatable improvement in acceptance or total cost, return to the smaller model or keep the existing GPT-5.5 API workflow.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At minimum, compare first-pass acceptance, final acceptance, total cost per accepted result, and median plus high-percentile completion time. A model should become the default only when it consistently wins under your actual quality threshold.&lt;/p&gt;

&lt;h2&gt;
  
  
  Escalate on repeated failure and risk, not on model prestige
&lt;/h2&gt;

&lt;p&gt;Escalation should be triggered by observable failure signals, not by the assumption that a more expensive model must be better.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Luna → Sol:&lt;/strong&gt; deterministic validation repeatedly fails; the task needs cross-file or cross-module reasoning; tool results materially change the plan; or a critical ambiguity remains after adding the missing task constraints.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sol → Astra:&lt;/strong&gt; repeated plans omit critical constraints; an error affects production, security, or a major migration; or the task combines difficult reasoning, research, documentation, and execution.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Astra → narrow the task:&lt;/strong&gt; when Astra still fails, add evidence, split the workflow, or request a human decision instead of continuously increasing context and reasoning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New model → GPT-5.5 rollback:&lt;/strong&gt; in API workloads, keep GPT-5.5 whenever it still meets quality, latency, and maintenance requirements. A newer model name alone is not a migration reason.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use Luna → Sol → Astra as the default escalation chain: reliable verifier first means Luna, complex development means Sol, and high risk means Astra. Change that rule only when your own acceptance rate, retries, elapsed time, and cost per accepted result show that another route is better.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bettertoken.ai/en/blog/gpt-6-astra-sol-luna-how-to-choose/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=gpt-6-astra-sol-luna-kak-vybrat-model&amp;amp;utm_content=gpt-6-astra-sol-luna-how-to-choose" rel="noopener noreferrer"&gt;BetterToken blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;BetterToken provides pay-as-you-go access to AI model APIs through&lt;br&gt;
OpenAI-compatible and Anthropic-compatible endpoints — useful if you are wiring&lt;br&gt;
Claude Code, Codex, or your own tooling to a custom base URL.&lt;br&gt;
See the &lt;a href="https://docs.bettertoken.ai/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=gpt-6-astra-sol-luna-kak-vybrat-model&amp;amp;utm_content=gpt-6-astra-sol-luna-how-to-choose" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to get started.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>programming</category>
      <category>news</category>
    </item>
    <item>
      <title>How to switch Claude Code to Opus 5.5 and keep it selected</title>
      <dc:creator>Adela</dc:creator>
      <pubDate>Mon, 28 Sep 2026 06:18:57 +0000</pubDate>
      <link>https://dev.to/bettertoken_ai/how-to-switch-claude-code-to-opus-55-and-keep-it-selected-1331</link>
      <guid>https://dev.to/bettertoken_ai/how-to-switch-claude-code-to-opus-55-and-keep-it-selected-1331</guid>
      <description>&lt;p&gt;You run &lt;code&gt;/model&lt;/code&gt;, choose Opus, and Claude Code still uses another model—or it returns a 400 before the first response. The reliable fix is to separate three things: the model command, the Claude Code version, and any request-level fallback triggered by a refusal.&lt;/p&gt;

&lt;p&gt;Use the full model ID when you need a reproducible setup, use the &lt;code&gt;opus&lt;/code&gt; alias only after checking what it resolves to, and remember that Opus 5.5 defaults to &lt;code&gt;medium&lt;/code&gt; effort rather than the &lt;code&gt;high&lt;/code&gt; default used by Opus 5.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use the full model ID to pin Opus 5.5
&lt;/h2&gt;

&lt;p&gt;The most explicit command is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/model claude-opus-5-5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anthropic documents &lt;code&gt;claude-opus-5-5&lt;/code&gt; as a fixed model ID without a date suffix. That makes it the better choice for project instructions, team runbooks, and custom providers where you need everyone to request the same model.&lt;/p&gt;

&lt;p&gt;The shorter alternative is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/model opus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use the alias only when Claude Code—or the provider behind your custom Base URL—shows that it resolves to Opus 5.5. An alias is convenient for interactive work, but the full ID is easier to audit when a session, script, or gateway behaves differently than expected.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your goal&lt;/th&gt;
&lt;th&gt;Prefer&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Pin the exact model&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/model claude-opus-5-5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The requested ID is explicit and reproducible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use the current Opus alias interactively&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/model opus&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Faster to type, but you should verify the resolved model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Diagnose a custom provider&lt;/td&gt;
&lt;td&gt;Full ID first&lt;/td&gt;
&lt;td&gt;It separates alias mapping problems from model availability problems&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you run Claude Code through an Anthropic-compatible custom Base URL such as BetterToken, the &lt;code&gt;/model&lt;/code&gt; procedure is unchanged; confirm that the provider actually exposes &lt;code&gt;claude-opus-5-5&lt;/code&gt; before treating an alias result as proof.&lt;/p&gt;

&lt;h2&gt;
  
  
  Update Claude Code before switching
&lt;/h2&gt;

&lt;p&gt;A client that predates the model may reject the selection even when your account or provider supports it. Update first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then restart the active Claude Code session or update the Claude desktop app if that is the client you use. After the restart, run the full-ID command again.&lt;/p&gt;

&lt;p&gt;A community issue captured one concrete error on September 22, 2026: Claude Code &lt;code&gt;2.1.257&lt;/code&gt; was rejected with &lt;code&gt;claude_code_version_too_old&lt;/code&gt;, and the response required &lt;code&gt;2.1.280&lt;/code&gt; or newer. That report is useful as an example of the version gate, not as a permanent universal minimum. Follow the minimum named by the error you actually receive, because later releases can raise it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Switch the model and verify the result
&lt;/h2&gt;

&lt;p&gt;Follow this order so that one failure does not hide another:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run &lt;code&gt;claude update&lt;/code&gt;, then restart Claude Code.&lt;/li&gt;
&lt;li&gt;Enter &lt;code&gt;/model claude-opus-5-5&lt;/code&gt; in the session where you will work.&lt;/li&gt;
&lt;li&gt;Check the model selection that Claude Code displays after the command. Do not infer success only because the command was accepted.&lt;/li&gt;
&lt;li&gt;Reopen &lt;code&gt;/model&lt;/code&gt; before a long or expensive task and confirm the current selection again.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the full ID works but &lt;code&gt;/model opus&lt;/code&gt; does not, keep the full ID. That points to alias resolution rather than a general inability to use Opus 5.5.&lt;/p&gt;

&lt;p&gt;If neither works and you use a third-party endpoint, verify model availability and mapping on that provider. The Claude API can expose the official ID while a compatible gateway uses a separate catalog or has not enabled it yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Expect &lt;code&gt;medium&lt;/code&gt; effort unless you set another level
&lt;/h2&gt;

&lt;p&gt;Claude Opus 5.5 uses adaptive thinking and its documented default effort is &lt;code&gt;medium&lt;/code&gt;. This differs from Claude Opus 5, whose default was &lt;code&gt;high&lt;/code&gt;, so a model switch can change latency, token use, and how much reasoning the model applies even when you do not change any visible Claude Code setting.&lt;/p&gt;

&lt;p&gt;For ordinary Claude Code use, there is no need to invent an effort value just to complete the switch. First confirm the model, then evaluate whether the default behavior fits the task. If your client or API gateway exposes an effort control, set it deliberately rather than assuming the old Opus default carried over.&lt;/p&gt;

&lt;p&gt;Custom integrations also need to respect the Opus 5.5 request rules. The model rejects requests that disable thinking or send a manual thinking budget. If model selection succeeds but the first request returns a 400, inspect any upstream payload transformation instead of repeatedly changing &lt;code&gt;/model&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A flagged message can take a fallback path
&lt;/h2&gt;

&lt;p&gt;A safety refusal is separate from your normal model selection. At the API level, Opus 5.5 can return HTTP 200 with &lt;code&gt;stop_reason: "refusal"&lt;/code&gt; and a &lt;code&gt;stop_details&lt;/code&gt; object. A client or provider with fallback enabled may retry that request on another model.&lt;/p&gt;

&lt;p&gt;Treat that event as a request-level fallback, not proof that your saved &lt;code&gt;/model&lt;/code&gt; choice changed. Before continuing important work, reopen &lt;code&gt;/model&lt;/code&gt; and verify the active selection. If the fallback moved the conversation from Opus 5.5 to most other models, Anthropic notes that the later turns run without the previous Opus 5.5 thinking blocks; restate critical constraints instead of assuming all hidden reasoning carried over.&lt;/p&gt;

&lt;p&gt;The practical sequence is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read the refusal or flagged-message notice instead of resending the same request unchanged.&lt;/li&gt;
&lt;li&gt;Remove or reframe the part that triggered the safeguard when the request is legitimate.&lt;/li&gt;
&lt;li&gt;Check whether your client or provider used a fallback model.&lt;/li&gt;
&lt;li&gt;Confirm Opus 5.5 again before resuming a task that depends on a fixed model.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Troubleshoot the common failure modes
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Most likely check&lt;/th&gt;
&lt;th&gt;Next action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;400 with &lt;code&gt;claude_code_version_too_old&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Claude Code or desktop version&lt;/td&gt;
&lt;td&gt;Run &lt;code&gt;claude update&lt;/code&gt;, restart, and retry the full ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Opus 5.5 is missing from the model list&lt;/td&gt;
&lt;td&gt;Client catalog or provider catalog is stale&lt;/td&gt;
&lt;td&gt;Update the client; then check provider availability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;/model opus&lt;/code&gt; chooses an unexpected model&lt;/td&gt;
&lt;td&gt;Alias resolution&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;/model claude-opus-5-5&lt;/code&gt; and verify the displayed selection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full ID is accepted, but the first request returns 400&lt;/td&gt;
&lt;td&gt;Upstream payload is incompatible&lt;/td&gt;
&lt;td&gt;Check for disabled/manual thinking settings or other gateway rewrites&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A message is flagged and another model answers&lt;/td&gt;
&lt;td&gt;Refusal fallback&lt;/td&gt;
&lt;td&gt;Review the refusal, verify the active model, and restate critical constraints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A mid-session switch feels less consistent&lt;/td&gt;
&lt;td&gt;Thinking blocks may not transfer to the target model&lt;/td&gt;
&lt;td&gt;Confirm the model and give the new turn the context it needs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Final checklist
&lt;/h2&gt;

&lt;p&gt;Before starting the real task, confirm all five points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claude Code has been updated and restarted.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/model claude-opus-5-5&lt;/code&gt; is accepted.&lt;/li&gt;
&lt;li&gt;The displayed selection resolves to Opus 5.5.&lt;/li&gt;
&lt;li&gt;You expect the default &lt;code&gt;medium&lt;/code&gt; effort unless another level is explicitly configured.&lt;/li&gt;
&lt;li&gt;A flagged or refused request has not silently moved that request onto a fallback model without your review.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once those checks pass, the exact model ID is the safest way to keep a session reproducible. The &lt;code&gt;opus&lt;/code&gt; alias remains useful for quick interactive switching, but it should be verified rather than assumed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://platform.claude.com/docs/en/models/opus-5-5/migration-guide" rel="noopener noreferrer"&gt;Anthropic: Opus 5.5 migration guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://platform.claude.com/docs/en/models/opus-5-5/whats-new-opus-5-5" rel="noopener noreferrer"&gt;Anthropic: What's new in Claude Opus 5.5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/can1357/oh-my-pi/issues/12870" rel="noopener noreferrer"&gt;GitHub issue #12870: one reported old-client version error&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bettertoken.ai/en/blog/claude-code-switch-to-opus-5-5/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=claude-code-pereklyuchit-opus-5-5&amp;amp;utm_content=claude-code-switch-to-opus-5-5" rel="noopener noreferrer"&gt;BetterToken blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;BetterToken provides pay-as-you-go access to AI model APIs through&lt;br&gt;
OpenAI-compatible and Anthropic-compatible endpoints — useful if you are wiring&lt;br&gt;
Claude Code, Codex, or your own tooling to a custom base URL.&lt;br&gt;
See the &lt;a href="https://docs.bettertoken.ai/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=claude-code-pereklyuchit-opus-5-5&amp;amp;utm_content=claude-code-switch-to-opus-5-5" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to get started.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Local Qwen Context Stops Early: Isolate KV Cache, Backend, and GPU Limits</title>
      <dc:creator>Adela</dc:creator>
      <pubDate>Mon, 28 Sep 2026 06:16:55 +0000</pubDate>
      <link>https://dev.to/bettertoken_ai/local-qwen-context-stops-early-isolate-kv-cache-backend-and-gpu-limits-5c42</link>
      <guid>https://dev.to/bettertoken_ai/local-qwen-context-stops-early-isolate-kv-cache-backend-and-gpu-limits-5c42</guid>
      <description>&lt;p&gt;You configured a local Qwen model for 128K context, but it may fail near 72K, slow down until it is impractical, or finish while ignoring instructions from the beginning. There is rarely one magic setting: model-weight quantization, the KV cache, the inference backend, and hardware placement all contribute to the limit.&lt;/p&gt;

&lt;p&gt;This guide gives you a repeatable diagnosis. You will identify whether the failure is capacity, speed, or effective memory, then change one variable at a time to decide whether to use a different KV cache, switch backends, rebalance multiple GPUs, or lower the production context target.&lt;/p&gt;

&lt;h2&gt;
  
  
  The direct answer: configured context is a ceiling, not a guarantee
&lt;/h2&gt;

&lt;p&gt;A 128K context setting only asks the backend to prepare for an input of that size. The setup is viable only when this memory budget holds:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;model weights + KV cache + runtime workspace + safety margin ≤ memory the backend can actually use&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Model weights usually take a large, mostly fixed allocation at load time. The KV cache grows with the number of retained tokens, while workspaces and temporary buffers vary with the backend, batching, and kernels. Even when allocation succeeds, latency or long-range recall may become unacceptable before memory is exhausted.&lt;/p&gt;

&lt;p&gt;That means you need three separate answers: does it fit, does it finish fast enough, and does the model still use information from the beginning? A maximum-context value in a UI answers none of them by itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Identify the symptom before changing the stack
&lt;/h2&gt;

&lt;p&gt;“Cannot reach 128K” can describe several different failures. Classify yours first so you do not optimize the wrong component.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;More likely direction&lt;/th&gt;
&lt;th&gt;First check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;The model or long context allocation immediately runs out of memory&lt;/td&gt;
&lt;td&gt;Weights and KV cache compete for memory, or one device cannot allocate its share&lt;/td&gt;
&lt;td&gt;Record peak and free memory on every GPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The backend fails near the same token count every time&lt;/td&gt;
&lt;td&gt;KV-cache format, backend implementation, or an allocation boundary&lt;/td&gt;
&lt;td&gt;Hold model and hardware fixed; change only KV cache or backend&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The prompt is accepted, but prefill or generation becomes unusably slow&lt;/td&gt;
&lt;td&gt;Bandwidth, cross-GPU traffic, kernels, or an excessive target length&lt;/td&gt;
&lt;td&gt;Measure prompt processing and generation separately&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generation completes, but early constraints are forgotten&lt;/td&gt;
&lt;td&gt;Effective-context quality, not raw capacity&lt;/td&gt;
&lt;td&gt;Test facts placed throughout the prompt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The same run sometimes passes and sometimes fails&lt;/td&gt;
&lt;td&gt;Too little headroom, concurrent load, or an unstable runtime&lt;/td&gt;
&lt;td&gt;Remove other load and repeat the identical run three times&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If the system fits but is too slow, a smaller KV cache is not automatically the best answer. If it fits but cannot recall early information, adding memory alone may not improve the result.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a reported move from 72K to 128K does—and does not—show
&lt;/h2&gt;

&lt;p&gt;In a &lt;a href="https://x.com/VectorCrossProd/status/2102902907872194639" rel="noopener noreferrer"&gt;September 23, 2026 configuration report&lt;/a&gt;, Nigel Hungerford-Symes described running Qwen3.8-27B (Unsloth UD-Q5_K_M) on an RTX 5060 Ti 16GB plus an RTX 3070 8GB. The reported 128K stack used &lt;code&gt;beellama.cpp + kvarn5 KV + MTP n=2&lt;/code&gt;, at about 36 tok/s for short context and 18 tok/s at 126K; the earlier mainline &lt;code&gt;llama.cpp&lt;/code&gt; setup with &lt;code&gt;q8_0&lt;/code&gt; KV reportedly stopped near 72K.&lt;/p&gt;

&lt;p&gt;The report matters because it shows that the usable limit on one specific machine can move when the inference stack changes. It does not isolate the cause: the backend, KV-cache scheme, and other runtime settings changed together, so it cannot prove that one cache format alone produced the difference or that the same speeds apply elsewhere.&lt;/p&gt;

&lt;p&gt;Use it as a diagnostic lead. When your limit repeatedly appears at one length, include the KV cache and backend in the comparison instead of looking only at the model file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a baseline before touching the 72K setup
&lt;/h2&gt;

&lt;p&gt;Save a reproducible baseline before changing anything. Otherwise, a successful new stack still will not tell you which change mattered.&lt;/p&gt;

&lt;p&gt;Record at least the following:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Area&lt;/th&gt;
&lt;th&gt;Values to capture&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Model&lt;/td&gt;
&lt;td&gt;Full model name, exact model file, weight quantization, file size&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;Backend name, version or commit, launch method&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Context&lt;/td&gt;
&lt;td&gt;Requested window, actual input tokens, reserved output tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KV cache&lt;/td&gt;
&lt;td&gt;Data type or scheme, GPU or host placement, compression settings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hardware&lt;/td&gt;
&lt;td&gt;Every GPU model and VRAM size, system RAM, PCIe topology&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Placement&lt;/td&gt;
&lt;td&gt;GPU split, offloaded components, whether work crosses devices&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime&lt;/td&gt;
&lt;td&gt;Batch settings, concurrency, sampling values, maximum output&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Result&lt;/td&gt;
&lt;td&gt;Success or error, exact error text, peak VRAM/RAM, prefill speed, generation speed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Do not treat a 16GB GPU plus an 8GB GPU as one simple 24GB pool. The backend decides where weights, KV cache, and workspaces live; one device may fill first, and cross-device traffic may dominate at long context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test four variables separately instead of replacing everything at once
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Weight quantization changes the fixed footprint
&lt;/h3&gt;

&lt;p&gt;Weight quantization primarily changes the memory required to load the model. Smaller weights can leave more room for the KV cache, but they do not guarantee a longer usable window and may also change quality or speed.&lt;/p&gt;

&lt;p&gt;To test whether weights are crowding out the cache, hold the backend, KV-cache type, and prompt constant. Change only the weight quantization, then record how much memory is freed and whether the failure point moves.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. KV-cache type changes the per-token footprint
&lt;/h3&gt;

&lt;p&gt;The KV cache stores reusable history needed for subsequent tokens. For a fixed model and cache representation, its memory use generally grows roughly with retained token count, which makes it the most direct long-context memory lever.&lt;/p&gt;

&lt;p&gt;When comparing cache schemes, evaluate three outcomes together: peak memory, longest stable input, and recall accuracy. “It fits 128K” is not a useful win if accuracy degrades or the backend becomes unreliable.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The backend decides how those formats are implemented
&lt;/h3&gt;

&lt;p&gt;Backends can differ in cache layout, allocation, multi-GPU placement, and kernels. The same context value and model file can therefore produce a different memory curve and different speed.&lt;/p&gt;

&lt;p&gt;If a candidate backend requires a different cache format, report the result as “this stack passed,” not “this cache format caused the gain.” To isolate the backend, run another A/B comparison using settings both backends support whenever possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Hardware placement decides which resource fails first
&lt;/h3&gt;

&lt;p&gt;The common multi-GPU mistake is to watch only total VRAM. A run may fail because one device lacks a large enough allocation, the cache is concentrated on one GPU, the workspace has no headroom, or cross-GPU transfers make the result too slow.&lt;/p&gt;

&lt;p&gt;Track every GPU separately. If one device is nearly full while another has meaningful headroom, rebalance placement before sacrificing model quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run a repeatable long-context acceptance ladder
&lt;/h2&gt;

&lt;p&gt;Do not jump from a short prompt straight to 128K. A fixed length ladder shows whether failure is abrupt or gradually becomes impractical.&lt;/p&gt;

&lt;p&gt;A useful starting ladder is &lt;code&gt;8K → 32K → 64K → 72K → 96K → 126K&lt;/code&gt;. The 126K point is close to 128K while leaving an explicit output budget; increase that reserve if your task needs long generations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prepare one controlled prompt set
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Count tokens with the tokenizer actually used by the target model; do not estimate from characters or file size.&lt;/li&gt;
&lt;li&gt;Place distinct “canary facts” near 10%, 20%, and so on through 90% of the input, such as &lt;code&gt;ORBIT-17 = copper&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Put one coding constraint near the beginning, middle, and end, then ask the final response to repeat the constraints and make a small code change.&lt;/li&gt;
&lt;li&gt;Keep content order, sampling settings, and output budget identical at every length.&lt;/li&gt;
&lt;li&gt;Remove other system load and repeat each critical length three times.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Canary facts measure retrieval, not complete coding ability. Add code, logs, or repository documentation resembling your real workload for the final acceptance run.&lt;/p&gt;

&lt;h3&gt;
  
  
  Record the same evidence for every run
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Question it answers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Actual input tokens&lt;/td&gt;
&lt;td&gt;Did the backend really accept the target length?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Allocation result and exact error&lt;/td&gt;
&lt;td&gt;Where did capacity or compatibility fail?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Peak memory per GPU and peak system RAM&lt;/td&gt;
&lt;td&gt;Which device became the bottleneck?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prompt processing time or rate&lt;/td&gt;
&lt;td&gt;Is long-input prefill still acceptable?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generation speed&lt;/td&gt;
&lt;td&gt;Is interaction after a long prompt practical?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canary facts recovered&lt;/td&gt;
&lt;td&gt;Can the model use distant information?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coding constraints satisfied&lt;/td&gt;
&lt;td&gt;Does the long window help the real task?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Define pass criteria before running the test. One example is three consecutive completions at the target length, no memory or backend error, at least 9 of 10 canaries correct, and prefill plus generation within your workflow limit. &lt;code&gt;9/10&lt;/code&gt; is only an example; the important part is deciding the threshold before seeing the result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose the next step from the result
&lt;/h2&gt;

&lt;h3&gt;
  
  
  It consistently runs out of memory at one length
&lt;/h3&gt;

&lt;p&gt;Find which device fills first. If cache growth consumes the remaining headroom, compare a lower-footprint KV scheme first. If loading the weights already leaves almost no room, compare a smaller weight quantization. Change one item per run and check whether the failure point moves as predicted.&lt;/p&gt;

&lt;h3&gt;
  
  
  A new backend reaches 128K while the old one stops at 72K
&lt;/h3&gt;

&lt;p&gt;Treat the new stack as a candidate, then reproduce it three times and run the recall test. Because backend and cache settings may have changed together, the defensible conclusion is that the candidate stack works—not that you have isolated a single root cause.&lt;/p&gt;

&lt;h3&gt;
  
  
  128K completes, but performance is unacceptable
&lt;/h3&gt;

&lt;p&gt;That is an operating boundary, not a capacity failure. Use a smaller default window and enable very long context only for the few tasks that need it, or compare a smaller model, another backend, or better hardware placement. Separate “can run” from “worth running every day.”&lt;/p&gt;

&lt;h3&gt;
  
  
  128K completes, but early information is repeatedly lost
&lt;/h3&gt;

&lt;p&gt;Treat it as an effective-context quality problem. Run the same prompt at 64K, 72K, and 96K to build a recall curve. If shorter inputs are clearly more reliable, set the production limit where quality passes rather than where allocation succeeds. Retrieval, chunking, or summarizing before coding can also remove irrelevant material from very large repository tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimize for a verified working window, not the largest menu value
&lt;/h2&gt;

&lt;p&gt;If 72K already covers your normal repositories and logs, do not replace weight quantization, KV cache, backend, and GPU split all at once just to display 128K. Preserve the stable baseline and require each change to demonstrate a capacity, speed, or recall benefit.&lt;/p&gt;

&lt;p&gt;If your work genuinely needs more than 100K input, build the length ladder and pass criteria first, then compare KV-cache and backend combinations. The useful final claim is specific: “this model, backend, cache, and hardware passed 126K three times at our required speed and recall”—not merely “the configuration supports 128K.”&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bettertoken.ai/en/blog/qwen-long-context-kv-cache-gpu-diagnosis/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=qwen-27b-local-128k-kv-cache-llama-cpp&amp;amp;utm_content=qwen-long-context-kv-cache-gpu-diagnosis" rel="noopener noreferrer"&gt;BetterToken blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;BetterToken provides pay-as-you-go access to AI model APIs through&lt;br&gt;
OpenAI-compatible and Anthropic-compatible endpoints — useful if you are wiring&lt;br&gt;
Claude Code, Codex, or your own tooling to a custom base URL.&lt;br&gt;
See the &lt;a href="https://docs.bettertoken.ai/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=qwen-27b-local-128k-kv-cache-llama-cpp&amp;amp;utm_content=qwen-long-context-kv-cache-gpu-diagnosis" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to get started.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Claude Opus 5.5 Code Audit Checklist: Verify Every Finding Before Merge</title>
      <dc:creator>Adela</dc:creator>
      <pubDate>Mon, 28 Sep 2026 06:14:54 +0000</pubDate>
      <link>https://dev.to/bettertoken_ai/claude-opus-55-code-audit-checklist-verify-every-finding-before-merge-45mh</link>
      <guid>https://dev.to/bettertoken_ai/claude-opus-55-code-audit-checklist-verify-every-finding-before-merge-45mh</guid>
      <description>&lt;p&gt;You let Claude Opus 5.5 audit a repository for several hours. It returns dozens of “high-risk” findings and may even prepare a large patch. The hard part is no longer getting suggestions; it is deciding which findings are real, which changes respect the system’s architecture, and which fixes are safe to merge.&lt;/p&gt;

&lt;p&gt;This workflow treats model output as &lt;strong&gt;audit hypotheses that require evidence&lt;/strong&gt;, not as conclusions. You establish a reproducible baseline, separate discovery from editing, and make every accepted finding pass reproduction, risk, architecture, fix, and regression gates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Opus 5.5 to widen the audit, not to approve the merge
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Opus 5.5 is a reasonable choice for broad, long-running audits, but it is not an independent reviewer.&lt;/strong&gt; Anthropic’s September 22, 2026 announcement specifically describes codebase-wide migrations and audits as a strength and reports results from internal tests and early testers. Those vendor and tester results do not prove the same outcome on your repository. &lt;a href="https://www.anthropic.com/claude-opus-5-5" rel="noopener noreferrer"&gt;Read Anthropic’s Opus 5.5 announcement&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Kent C. Dodds also published a broad audit prompt covering security, performance, accessibility, maintainability, scalability, architecture, documentation, testing, and automation. He said Opus 5.5 found a significant security issue that other models missed, but the post does not disclose the flaw, reproduction steps, or a controlled comparison. It supports trying the workflow, not waiving verification. &lt;a href="https://x.com/kentcdodds/status/2102890940356800751" rel="noopener noreferrer"&gt;Read the public report&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Your goal should therefore be: produce as many &lt;strong&gt;reproducible, graded, independently reviewable&lt;/strong&gt; findings as possible—not simply maximize the number of warnings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Define success as commands before the audit starts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Without a clean baseline, you cannot tell whether a later failure was pre-existing or introduced by the model.&lt;/strong&gt; Before the model scans the full repository, record the current commit, environment, dependency versions, and the exit code from every baseline command.&lt;/p&gt;

&lt;p&gt;Replace the placeholders with the commands your project actually uses. Mark a gate “not applicable” rather than inventing one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status &lt;span class="nt"&gt;--short&lt;/span&gt;
&amp;lt;install-command&amp;gt;
&amp;lt;lint-command&amp;gt;
&amp;lt;type-check-command&amp;gt;
&amp;lt;unit-test-command&amp;gt;
&amp;lt;integration-test-command&amp;gt;
&amp;lt;build-command&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Record at least:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the commit SHA, runtime, package manager, and material dependency versions;&lt;/li&gt;
&lt;li&gt;the exact command, working directory, exit code, and failure summary for each check;&lt;/li&gt;
&lt;li&gt;known failures, flaky tests, and temporary exemptions;&lt;/li&gt;
&lt;li&gt;directories that are in scope and files the model must not edit, such as generated code, historical migrations, lockfiles, or vendored sources;&lt;/li&gt;
&lt;li&gt;critical paths such as authentication, authorization, billing, data migration, and external API contracts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the baseline already fails, decide whether to fix, isolate, or register the failure before the audit. Do not allow an old failure to be presented as a new discovery.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ask for an audit first and no code changes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Discovery and remediation must be separate phases.&lt;/strong&gt; If the model edits while it investigates, a new failure may come from the original code, the first patch, or a later patch that interacts with it.&lt;/p&gt;

&lt;p&gt;Use this as a first-pass prompt and add repository-specific commands and boundaries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Perform a long-running code audit of this repository. In this phase, investigate and report only; do not modify files.

Scope: &amp;lt;directories, services, languages, critical business flows&amp;gt;
Exclusions: &amp;lt;generated files, third-party code, historical migrations, inaccessible systems&amp;gt;
Baseline: &amp;lt;commands already run, exit codes, known failures&amp;gt;

Audit areas:
1. Security and authorization boundaries
2. Correctness, concurrency, transactions, and error handling
3. Performance and resource use
4. Accessibility where applicable
5. Maintainability and scalability
6. Architecture and module boundaries
7. Documentation, testing, and automation gaps

For every finding, provide:
- a unique ID and short title
- severity and impact rationale
- affected files, symbols, and exact lines
- trigger, expected behavior, and actual behavior
- a reproducible command or minimal test
- output summary and exit code
- a plausible false-positive explanation
- the smallest remediation direction
- verification commands required after a fix
- confidence: high, medium, or low

Rules:
- Mark any command you did not run as NOT RUN.
- If you cannot reproduce a finding, label it UNVERIFIED, not confirmed.
- Never delete, skip, or weaken tests to make a result pass.
- Stop and list missing credentials, services, or dependencies.
- Update the audit status table at the end of each phase before continuing.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The prompt does not guarantee compliance. You still need to inspect terminal records, file diffs, and test output. Its purpose is to make acceptance fields explicit so that “this looks risky” cannot move directly into the fix queue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Split the long task into four controlled phases
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A long autonomous run should not mean unlimited scope or permissions.&lt;/strong&gt; Pause at each phase boundary and review the evidence before allowing the model to continue.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 1: Build a system map
&lt;/h3&gt;

&lt;p&gt;The model reads code, configuration, tests, and architecture documents. It identifies entry points, trust boundaries, data flows, external dependencies, and high-impact paths. It should not chase a target number of bugs or change files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2: Produce candidate findings
&lt;/h3&gt;

&lt;p&gt;The model groups candidate issues by audit area and points each one to concrete code. Advice without a location or trigger belongs in an “improvement ideas” list, not the defect count.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 3: Reproduce one finding at a time
&lt;/h3&gt;

&lt;p&gt;Start with high-impact findings that are cheap to test. Add a minimal test or run an existing check, retain the raw output, and record the environment. Do not bundle several hypotheses into one experiment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 4: Prepare a remediation plan
&lt;/h3&gt;

&lt;p&gt;Only reproduced findings enter the fix plan. The plan must state the smallest change, compatibility impact, migration risk, rollback path, and required gates. Architecture disputes go to the code owner before implementation.&lt;/p&gt;

&lt;p&gt;Track state in &lt;code&gt;audit-plan.md&lt;/code&gt; or a ticket table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ID&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;Risk&lt;/th&gt;
&lt;th&gt;Reproduction evidence&lt;/th&gt;
&lt;th&gt;Architecture decision&lt;/th&gt;
&lt;th&gt;Fix branch&lt;/th&gt;
&lt;th&gt;Approver&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AUD-001&lt;/td&gt;
&lt;td&gt;Awaiting reproduction&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;None yet&lt;/td&gt;
&lt;td&gt;Not reviewed&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Allow only an explicit progression: &lt;code&gt;candidate → awaiting reproduction → reproduced → architecture reviewed → fixed → accepted&lt;/code&gt;. A finding that cannot be reproduced returns to candidate status or closes; confident wording is not a reason to advance it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Risk gate: keep severity separate from confidence
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Severity measures impact; confidence measures evidence quality.&lt;/strong&gt; A possible authorization bypass can be high severity and low confidence. A reproducible typo in a log message can be low severity and high confidence.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Severity&lt;/th&gt;
&lt;th&gt;Use when&lt;/th&gt;
&lt;th&gt;Minimum evidence before remediation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Critical&lt;/td&gt;
&lt;td&gt;Broad privilege escalation, sensitive-data exposure, irreversible corruption, or core-service failure is plausible&lt;/td&gt;
&lt;td&gt;Controlled reproduction, clear blast radius, immediate owner review&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;A critical business flow is affected or realistic input triggers the failure reliably&lt;/td&gt;
&lt;td&gt;Minimal reproduction, failing test or command output, code-owner confirmation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Impact is bounded, a workaround exists, or unusual conditions are required&lt;/td&gt;
&lt;td&gt;Repeatable evidence, impact note, prioritization decision&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Local quality, documentation, maintainability, or non-critical performance issue&lt;/td&gt;
&lt;td&gt;Concrete code evidence and a case that benefit exceeds regression risk&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Do not let the model assign business impact alone. It can trace code paths, but data sensitivity, customer commitments, acceptable downtime, and compatibility policy usually require an owner’s judgment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reproduction gate: turn each finding into a failing check
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Suspicious code is not enough; acceptance needs a check that fails before the fix and passes after it.&lt;/strong&gt; For every finding, answer:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Which commit and environment exhibit the behavior?&lt;/li&gt;
&lt;li&gt;What is the smallest triggering input?&lt;/li&gt;
&lt;li&gt;Is expected behavior defined by a test, specification, interface contract, or business rule?&lt;/li&gt;
&lt;li&gt;What exactly happened, and where is the raw output?&lt;/li&gt;
&lt;li&gt;Why did existing tests miss it?&lt;/li&gt;
&lt;li&gt;Could a valid design choice or environment difference explain it?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The best evidence is a minimal regression test. If automation is impractical, provide deterministic manual steps, expected observations, and cleanup instructions. Reproduce security findings only in systems you own or are authorized to test, preferably local, isolated, or pre-production environments.&lt;/p&gt;

&lt;p&gt;When the model says it ran a command, look for the full command, working directory, exit code, and relevant output. A prose summary by itself is not execution evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture gate: learn why the old code exists before changing it
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A cleaner-looking implementation can break compatibility, deployment ordering, or an intentional boundary.&lt;/strong&gt; Before accepting an architecture finding or broad refactor, review ADRs, design documents, API contracts, migration constraints, and the relevant history.&lt;/p&gt;

&lt;p&gt;When the repository has usable Git history, the model can help inspect it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git log &lt;span class="nt"&gt;--&lt;/span&gt; &amp;lt;path&amp;gt;
git blame &lt;span class="nt"&gt;-L&lt;/span&gt; &amp;lt;start&amp;gt;,&amp;lt;end&amp;gt; &amp;lt;file&amp;gt;
git show &amp;lt;commit&amp;gt; &lt;span class="nt"&gt;--&lt;/span&gt; &amp;lt;path&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then require answers to these questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What constraint is the current design preserving?&lt;/li&gt;
&lt;li&gt;Which callers, data formats, or deployment steps depend on it?&lt;/li&gt;
&lt;li&gt;Is the proposed change correcting a defect or changing product behavior?&lt;/li&gt;
&lt;li&gt;Can a smaller local change solve the reproduced issue?&lt;/li&gt;
&lt;li&gt;Does rollback require restoring code, configuration, or data?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;History is evidence, not a perfect record of intent. If no rationale is available, mark the decision “architecture intent unknown” and ask a maintainer. Do not let the model silently redraw module boundaries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fix gate: one reproduced finding per small patch
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Do not accept a mega-patch that claims to fix a dozen unrelated findings.&lt;/strong&gt; A safer pattern is one reproduced issue per branch or independently reviewable commit: add the failing regression test first, then make the smallest change that passes it.&lt;/p&gt;

&lt;p&gt;Each patch should clear these gates:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Gate&lt;/th&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;If it fails&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Scope&lt;/td&gt;
&lt;td&gt;The diff addresses only the approved finding&lt;/td&gt;
&lt;td&gt;Split unrelated changes and review again&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Regression test&lt;/td&gt;
&lt;td&gt;Fails before the fix and passes after it&lt;/td&gt;
&lt;td&gt;Repair the test or reconsider the finding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Static checks&lt;/td&gt;
&lt;td&gt;Format, lint, and type checks pass&lt;/td&gt;
&lt;td&gt;Do not hide new errors with broad exemptions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Project tests&lt;/td&gt;
&lt;td&gt;Relevant unit, integration, and build checks pass&lt;/td&gt;
&lt;td&gt;Investigate the first new failure before stacking patches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Architecture&lt;/td&gt;
&lt;td&gt;The owner confirms boundaries and compatibility&lt;/td&gt;
&lt;td&gt;Reduce scope or open a design review&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Human diff review&lt;/td&gt;
&lt;td&gt;Error handling, permissions, data changes, and deletions are inspected&lt;/td&gt;
&lt;td&gt;Explain every suspicious change&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Explicitly reject fake passes: deleting assertions, skipping tests, swallowing exceptions, weakening validation, increasing retries to hide races, or performing a large refactor that makes the original defect hard to trace.&lt;/p&gt;

&lt;h2&gt;
  
  
  Regression gate: run project-owned checks, not only model-selected tests
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The model will naturally focus on checks closest to its change; merge acceptance needs an independent project-level gate.&lt;/strong&gt; Use existing repository scripts or CI definitions for the final run rather than letting the model substitute an easier command.&lt;/p&gt;

&lt;p&gt;Compare:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the full baseline before the audit with the post-fix result;&lt;/li&gt;
&lt;li&gt;whether the new regression test fails on the unpatched revision;&lt;/li&gt;
&lt;li&gt;lockfiles, database migrations, public APIs, and configuration defaults for unintended changes;&lt;/li&gt;
&lt;li&gt;performance claims using the same environment and input before and after;&lt;/li&gt;
&lt;li&gt;security fixes for new authorization or availability regressions;&lt;/li&gt;
&lt;li&gt;documentation and operational steps against the final behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For flaky tests, do not rerun until green. Record the failure pattern, isolate the source of nondeterminism, and determine whether the patch made instability worse.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reject the audit result when any of these conditions appear
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Do not move a finding toward merge when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it lacks an exact code location, trigger, or inspectable evidence;&lt;/li&gt;
&lt;li&gt;an unexecuted command is reported as passing;&lt;/li&gt;
&lt;li&gt;severity is just an adjective with no impact path;&lt;/li&gt;
&lt;li&gt;the patch exceeds approved scope or casually redesigns architecture;&lt;/li&gt;
&lt;li&gt;tests are deleted, skipped, weakened, or errors are swallowed;&lt;/li&gt;
&lt;li&gt;the change conflicts with an ADR, contract, or migration policy without owner approval;&lt;/li&gt;
&lt;li&gt;you receive only a final summary, with no reviewable commands or diff;&lt;/li&gt;
&lt;li&gt;a security claim is supported only by another model agreeing with it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A second model can search for counterexamples, but model consensus is not independent evidence. Independent validation comes from tests, runtime output, history, specifications, and accountable human judgment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final pre-merge acceptance checklist
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Treat the model-assisted fix as mergeable only when all ten items are true:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Scope, exclusions, and the baseline commit are frozen.&lt;/li&gt;
&lt;li&gt;[ ] Baseline commands and exit codes are retained.&lt;/li&gt;
&lt;li&gt;[ ] Every accepted finding has a unique ID and exact code location.&lt;/li&gt;
&lt;li&gt;[ ] Severity and confidence are recorded separately.&lt;/li&gt;
&lt;li&gt;[ ] The defect is reproduced by a test or deterministic procedure.&lt;/li&gt;
&lt;li&gt;[ ] Architecture intent, compatibility, and rollback are reviewed.&lt;/li&gt;
&lt;li&gt;[ ] Each finding maps to a small, reviewable patch.&lt;/li&gt;
&lt;li&gt;[ ] The regression test fails before the fix and passes after it.&lt;/li&gt;
&lt;li&gt;[ ] Full project gates run through existing scripts or CI.&lt;/li&gt;
&lt;li&gt;[ ] A code owner reviews the final diff and explicitly approves it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The available public reports make Opus 5.5 a credible candidate for broad, long-running audits and suggest it can surface issues missed elsewhere. They do not remove the need for verification. The minimum next step is not to let it edit the repository: save a clean baseline and issue the first “audit only, no modifications” task.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://bettertoken.ai/en/blog/claude-opus-5-5-code-audit-verification/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=opus-5-5-code-audit-checklist-verification&amp;amp;utm_content=claude-opus-5-5-code-audit-verification" rel="noopener noreferrer"&gt;BetterToken blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;BetterToken provides pay-as-you-go access to AI model APIs through&lt;br&gt;
OpenAI-compatible and Anthropic-compatible endpoints — useful if you are wiring&lt;br&gt;
Claude Code, Codex, or your own tooling to a custom base URL.&lt;br&gt;
See the &lt;a href="https://docs.bettertoken.ai/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=opus-5-5-code-audit-checklist-verification&amp;amp;utm_content=claude-opus-5-5-code-audit-verification" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to get started.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
