`, `\n\nAnswer:`, or custom markers), the model doesn't know when to switch phases.
   - Mention proxy/llama.cpp interaction: Proxies sometimes strip or misroute parameters. OpenWebUI might not pass `stop` or `max_tokens` correctly to the backend. Reasoning models often use special tags (`<think>...</think>`) that require explicit handling.
   - Discuss temperature/top_p: High values can cause meandering; low values can cause repetition loops if not paired with `repeat_penalty`.
   - Explain context window vs. generation limit: They're different. Generation limit is what matters here.

   **# Settings To Check**
   - List and explain key parameters in llama.cpp/OpenWebUI:
     - `max_tokens` / `n_predict`: Hard limit. Set to reasonable values (e.g., 2048-4096 for reasoning tasks).
     - `stop`: Array of strings. Crucial for reasoning models. Examples: `["</think>", "\n\nFinal Answer:", "### Answer"]`.
     - `temperature` & `top_p`: Control randomness. For reasoning, keep `temperature` ~0.1-0.3, `top_p` ~0.9.
     - `repeat_penalty`: Prevents looping. Set to ~1.1-1.2.
     - `mirostat` / `mirostat_tau`: Alternative to temp/top_p for stable perplexity.
     - `grammar` / `json_schema`: Forces structured output, preventing open-ended rambling.
     - `cache` / `ctx_size`: Ensure context isn't causing truncation mid-reasoning.
     - Proxy settings: Verify headers like `X-Stop-Sequences`, `X-Max-Tokens` are forwarded. Check if OpenWebUI's "Advanced Parameters" are actually reaching llama.cpp.
   - Provide concrete UI/API examples.

   **# Prompt Design**
   - Explain the "Reasoning-Then-Answer" pattern.
   - Bad prompt: "Think step by step and solve this. Take your time." (Encourages open-ended, unbounded reasoning)
   - Good prompt: "Analyze the problem step-by-step inside <think> tags. After your reasoning, output ONLY the final answer in the format: ANSWER: [result]. Do not add extra text after ANSWER:."
   - Explain structural constraints: Use XML/Markdown delimiters, explicit phase transitions, negative constraints ("Do not repeat", "Stop after answer").
   - Provide examples for different domains (math, coding, analysis).
   - Discuss system prompt vs. user prompt placement.
   - Explain how to use few-shot examples to teach the model the expected shape.

   **# Benchmark Design**
   - How to systematically test this in a home lab.
   - Create a test suite: 20-50 prompts spanning reasoning-heavy tasks.
   - Metrics to track: `tokens_used`, `reasoning_tokens`, `answer_tokens`, `completion_status`, `latency`, `stop_token_triggered`.
   - Automation: Use Python scripts with `requests` or `httpx` to hit the proxy/llama.cpp endpoint. Parse responses.
   - Define success criteria: Answer present, within token budget, matches expected format, reasoning-to-output ratio < 3:1.
   - Explain how to log and visualize results (CSV, simple dashboards).
   - Mention stress testing: Vary `max_tokens`, `temperature`, and prompt structures to find the Pareto frontier.

   **# What The Flight Recorder Should Show**
   - Explain what to look for in logs/metrics (llama.cpp server logs, OpenWebUI debug logs, proxy access logs).
   - Key indicators: `tokens predicted: X`, `tokens cached: Y`, `generation time: Z ms`, `stop sequence matched: true/false`, `context overflow: false`.
   - Explain how to interpret token distribution: If `tokens predicted` ≈ `max_tokens` and no stop sequence matched, it's a budget exhaustion.
   - Look for proxy headers: `X-Reasoning-Tokens`, `X-Output-Tokens` (if custom), or parse the raw text to count `<think>` vs answer tokens.
   - Mention OpenWebUI's built-in metrics (if available) or how to enable verbose logging in llama.cpp (`-v` or `--verbose`).
   - Explain how to set up a simple "flight recorder" using `jq` or Python to capture request/response pairs and token counts.

   **# Practical Defaults**
   - Provide a ready-to-use configuration block for OpenWebUI/llama.cpp.
   - JSON/YAML format for clarity.
   - Include explanations for each value.
   - Example:
     ```json
     {
       "max_tokens": 3072,
       "stop": ["</think>", "\n\nANSWER:", "### Final Answer"],
       "temperature": 0.2,
       "top_p": 0.9,
       "repeat_penalty": 1.1,
       "mirostat": 0,
       "grammar": null,
       "cache_prompt": true
     }
     ```
   - Explain how to apply in OpenWebUI (Settings -> Advanced -> Parameters).
   - Note model-specific adjustments (e.g., DeepSeek R1 vs Llama 3.1).

   **# When To Increase Budgets**
   - Define scenarios: Multi-step math proofs, complex code generation, long-document synthesis, multi-agent simulation.
   - Explain how to safely increase: Increment by 512 or 1024 tokens. Monitor reasoning-to-output ratio. Use dynamic budgeting if possible.
   - Warn about diminishing returns: Beyond ~4096-8192 generation tokens, quality often degrades due to attention dilution and repetition.
   - Suggest using `max_tokens` as a soft cap with `stop` sequences as hard boundaries.
   - Mention hardware constraints: VRAM/RAM limits, KV cache size, and how they interact with `max_tokens`.

   **# When To Stop A Run**
   - Define abort conditions: Token usage > 85% with no answer marker, repeated phrases (>3x), timeout > 30s, proxy errors, context overflow.
   - Explain implementation: OpenWebUI's "Stop Generation" button, llama.cpp's `interrupt` signal, proxy-level timeouts.
   - Suggest automated circuit breakers: Script that monitors streaming tokens, detects loops or budget exhaustion, and sends `Ctrl+C` or API abort.
   - Explain how to handle partial outputs: Save reasoning, retry with adjusted parameters, or use the partial output as context for a follow-up prompt.
   - Emphasize that stopping early is better than wasting compute on degenerate generation.

4.  **Self-Correction & Refinement (Mental Review during drafting):**
   - *Token Count Check:* I need to ensure the output is substantial (~4500 tokens). I'll expand each section with detailed explanations, concrete examples, configuration snippets, and practical home-lab advice. I'll avoid fluff but ensure depth.
   - *Technical Accuracy:* llama.cpp uses `n_predict` for max tokens, but OpenWebUI/standard OpenAI-compatible API uses `max_tokens`. I'll clarify both. Stop sequences are critical. Reasoning models use `<think>` tags. Proxy forwarding can drop parameters. All accurate.
   - *Structure:* Matches required sections exactly.
   - *Examples:* I'll include explicit good/bad prompt shapes, configuration blocks, and log examples.
   - *Tone:* Accessible but technical, suitable for a home-lab user familiar with OpenWebUI and llama.cpp.
   - *Expansion Strategy:* I'll elaborate on the mechanics of autoregressive generation, KV cache behavior, proxy header handling, prompt engineering techniques (delimiters, negative constraints, few-shot), benchmark automation scripts, log parsing, and operational thresholds. This will naturally reach the target length while remaining highly useful.

   Let's draft carefully, ensuring each section is comprehensive. I'll monitor the depth and technical precision. I'll make sure to explicitly address the proxy aspect, as that's a common pain point in home labs. I'll also clarify the difference between context window and generation limit, as users often confuse them.

   *Structure Check:*
   # Short Diagnosis
   # Why This Happens
   # Settings To Check
   # Prompt Design
   # Benchmark Design
   # What The Flight Recorder Should Show
   # Practical Defaults
   # When To Increase Budgets
   # When To Stop A Run

   All required. I'll now generate the full response. I'll aim for thoroughness, technical depth, and practical home-lab relevance. I'll expand each section with actionable details, examples, and explanations. I'll ensure the tone matches the request. I'll carefully count/estimate token length by providing substantial content in each section. (Note: I won't artificially pad, but I will be comprehensive as requested.)
   Proceed. 
   Output matches the final response. 
   Self-Correction/Verification during thought: 
   - Check llama.cpp parameter names: `n_predict` is the CLI/server param, but OpenAI API compatibility uses `max_tokens`. I'll mention both.
   - Stop sequences: `stop` array.
   - Proxy: Often nginx/caddy or custom reverse proxy. Headers like `X-Forwarded-For` don't matter, but JSON body parameters do. I'll note that proxies sometimes strip `stop` or `max_tokens` if not configured to pass the full payload.
   - Flight recorder: I'll interpret this as logging/metrics capture in a home lab context.
   - Benchmark design: I'll provide a concrete Python snippet structure and metrics definition.
   - All sections will be fleshed out to meet the ~4500 token target naturally through depth, not repetition.
   Ready.✅
   Output generation. 
   [Proceeds]
</think>

# Short Diagnosis
Your model is exhausting its generation token budget while trapped in a reasoning or chain-of-thought phase, leaving no room for the final answer. This is almost always caused by a combination of three factors: (1) an unbounded or misconfigured `max_tokens`/`n_predict` limit, (2) missing or improperly forwarded `stop` sequences that fail to signal the model when to transition from deliberation to output, and (3) prompt structures that encourage open-ended, unstructured reasoning without explicit phase boundaries. In a llama.cpp + OpenWebUI + proxy stack, this frequently manifests as the generation progress bar filling to 100%, the model outputting `<think>` blocks or step-by-step text, and then abruptly cutting off or returning an empty/aborted response. The issue is not a lack of intelligence; it is a resource allocation and control-flow problem.

# Why This Happens
Large language models generate text autoregressively: they predict one token at a time based on the preceding context. They do not "plan" ahead or reserve tokens for a final answer. When you prompt a model to "think carefully," "reason step-by-step," or use a reasoning-optimized checkpoint (e.g., DeepSeek R1, QwQ, or fine-tuned CoT variants), the model naturally allocates a large portion of its generation budget to internal deliberation. Without explicit constraints, the model will continue reasoning until it hits a hard ceiling.

The hard ceiling is `max_tokens` (or `n_predict` in native llama.cpp). This parameter defines the maximum number of tokens the model is allowed to generate in a single completion request. If your reasoning phase consumes 90% of that budget, the model will either truncate mid-sentence, repeat itself, or simply stop because it has no tokens left to produce the answer.

Stop sequences are the primary mechanism for controlling phase transitions. Reasoning models often use special tags like `<think>...</think>` or explicit markers like `### Answer:`. If these are not provided in the `stop` array, the model has no signal to halt reasoning and switch to output mode. It will keep generating until `max_tokens` is reached.

In a home-lab stack with a reverse proxy, parameter forwarding can silently break. Proxies (nginx, caddy, traefik, or custom API gateways) sometimes strip or misroute JSON body parameters if they are not configured to pass the full payload to the backend. OpenWebUI may send `stop` and `max_tokens` correctly, but if the proxy intercepts and rewrites the request, llama.cpp might receive a stripped payload with default parameters (often `max_tokens: 2048` and `stop: []`). This silently forces the model into unbounded reasoning.

Additionally, temperature and sampling parameters play a role. High `temperature` or `top_p` values can cause meandering, exploratory reasoning that never converges. Low values paired with insufficient `repeat_penalty` can cause the model to loop on the same logical step, burning tokens without progress. The KV cache also matters: if your context window is near capacity, the model may struggle to maintain coherence across long reasoning chains, leading to degenerate generation that consumes tokens without producing useful output.

# Settings To Check
Verify the following parameters in OpenWebUI, llama.cpp server configuration, and your proxy routing rules. Mismatches between what OpenWebUI sends and what llama.cpp receives are the most common root cause.

1. **`max_tokens` / `n_predict`**: This is the hard generation limit. In OpenWebUI, check Settings → Advanced → Parameters. In llama.cpp, the server flag is `--n-predict`. Ensure it is set to a value that leaves room for both reasoning and output (e.g., 2048–4096 for standard tasks). If set to 0 or -1, llama.cpp may default to the context size, which is dangerous for reasoning models.

2. **`stop` sequences**: This array tells the model when to halt generation. For reasoning models, you must include the closing tag or transition marker. Examples: `["</think>", "\n\nANSWER:", "### Final Answer", "\n\nAnswer:"]`. If your proxy strips this array, the model will never know when to stop reasoning. Verify that your proxy forwards the full JSON body without filtering arrays.

3. **`temperature` & `top_p`**: Control sampling randomness. For reasoning tasks, keep `temperature` between 0.1 and 0.3, and `top_p` between 0.85 and 0.95. Higher values encourage exploratory but unfocused reasoning; lower values can cause rigid repetition if not paired with `repeat_penalty`.

4. **`repeat_penalty`**: Prevents the model from looping on the same phrases. Set to 1.1–1.2. If your model repeats "Let's think step by step" or "First, we need to consider," increase this value.

5. **`mirostat` / `mirostat_tau`**: An alternative sampling method that maintains stable perplexity. If you use it, set `mirostat` to 2, `mirostat_tau` to 5.0, and `mirostat_eta` to 0.1. Disable `temperature` and `top_p` when using Mirostat to avoid conflicting sampling strategies.

6. **`grammar` / `json_schema`**: Forces structured output. If you want guaranteed final answers, use a JSON schema or CFG grammar that requires an `"answer"` field. This prevents open-ended rambling.

7. **Proxy Forwarding**: Check your proxy configuration. Ensure it does not rewrite or strip the `stop`, `max_tokens`, or `temperature` fields. In nginx, verify `proxy_pass_request_body on;` and that no `map` or `rewrite` directives are altering the JSON payload. In OpenWebUI, verify the backend URL points directly to llama.cpp or a proxy that preserves the OpenAI-compatible API structure.

8. **Context Window (`ctx_size`)**: Ensure `--ctx-size` is large enough to hold your prompt + reasoning + answer. If the context overflows, llama.cpp will truncate the oldest tokens, potentially dropping your system prompt or early reasoning steps, causing the model to loop or fail to produce an answer.

# Prompt Design
Prompt structure is the primary lever for controlling reasoning-to-output ratios. Open-ended prompts encourage unbounded deliberation; structured prompts force phase transitions.

**Bad Prompt Shape:**
```
Think step by step and solve this problem. Take your time to reason carefully. Explain your thought process thoroughly.
```
*Why it fails:* "Take your time" and "thoroughly" are unbounded instructions. The model has no signal to stop reasoning or format the output. It will consume tokens until `max_tokens` is reached.

**Good Prompt Shape:**
```
Analyze the problem step-by-step inside <think> tags. After your reasoning, output ONLY the final answer in the format: ANSWER: [result]. Do not add extra text after ANSWER:.
```
*Why it works:* Explicit delimiters (`<think>`), a clear transition marker (`ANSWER:`), and negative constraints (`Do not add extra text`) create a bounded reasoning phase and a forced output phase.

**Advanced Structured Prompt:**
```xml
<instructions>
1. Reason step-by-step inside <reasoning> tags.
2. Identify key constraints and edge cases.
3. Output the final result inside <answer> tags.
4. Do not repeat steps. Do not add commentary after <answer>.
</instructions>

<problem>
{{user_query}}
</problem>
```
*Why it works:* XML-style delimiters are highly effective for modern LLMs. They create clear parsing boundaries, reduce hallucination, and make it easy to extract the answer programmatically.

**Few-Shot Prompting for Consistency:**
If the model still meanders, provide examples:
```
Example 1:
<reasoning>
Step 1: Parse input.
Step 2: Apply formula.
</reasoning>
<answer>42</answer>

Example 2:
<reasoning>
Step 1: Check constraints.
Step 2: Evaluate options.
</reasoning>
<answer>Option B</answer>

Now solve:
{{user_query}}
```
Few-shot examples teach the model the expected token distribution and phase transition pattern.

**System Prompt Placement:**
Place structural instructions in the system prompt, not the user prompt. The system prompt has higher priority and persists across turns. Example:
```
You are a precise reasoning engine. Always wrap reasoning in <think> tags. Always output final answers in the format: ANSWER: [result]. Never exceed 2000 tokens for reasoning.
```

**Negative Constraints:**
Explicitly forbid behaviors that waste tokens:
- "Do not restate the problem."
- "Do not use filler phrases like 'Let's break this down'."
- "Stop generating immediately after the answer."

**Dynamic Prompting:**
If using OpenWebUI's template system, inject variables for token budgets:
```
Reason in under {{max_reasoning_tokens}} tokens. Output answer after.
```
While LLMs don't natively count tokens, this phrasing often triggers more concise reasoning.

# Benchmark Design
To systematically diagnose and optimize this behavior, build a lightweight benchmark suite tailored to your home-lab stack.

**Test Suite Construction:**
Create 20–50 prompts spanning reasoning-heavy domains:
- Multi-step math (algebra, calculus, logic puzzles)
- Code generation (functions, debugging, architecture)
- Document analysis (summarization, extraction, comparison)
- Open-ended reasoning (philosophy, strategy, trade-offs)

**Metrics to Track:**
- `tokens_used`: Total generated tokens
- `reasoning_tokens`: Tokens before the answer marker
- `answer_tokens`: Tokens after the answer marker
- `completion_status`: "success", "truncated", "stopped", "error"
- `stop_token_triggered`: Boolean indicating if a stop sequence matched
- `latency_ms`: Time from request to first token + generation time
- `reasoning_ratio`: `reasoning_tokens / tokens_used`

**Automation Script Structure (Python):**
```python
import requests, json, time

ENDPOINT = "http://localhost:8080/v1/chat/completions"
HEADERS = {"Authorization": "Bearer YOUR_KEY", "Content-Type": "application/json"}

def run_benchmark(prompts, config):
    results = []
    for p in prompts:
        payload = {**config, "messages": [{"role": "user", "content": p}]}
        start = time.time()
        resp = requests.post(ENDPOINT, json=payload, headers=HEADERS)
        data = resp.json()
        tokens = data.get("usage", {}).get("completion_tokens", 0)
        text = data["choices"][0]["message"]["content"]
        # Parse reasoning vs answer tokens
        if "<think>" in text and "</think>" in text:
            reasoning = text.split("</think>")[0]
            answer = text.split("</think>")[1]
        else:
            reasoning, answer = text, ""
        results.append({
            "prompt_hash": hash(p),
            "tokens_used": tokens,
            "reasoning_tokens": len(reasoning.split()),
            "answer_tokens": len(answer.split()),
            "completion_status": "success" if answer.strip() else "truncated",
            "latency_ms": (time.time() - start) * 1000
        })
    return results
```

**Success Criteria:**
- `completion_status == "success"` for >90% of prompts
- `reasoning_ratio < 0.7` (reasoning consumes less than 70% of budget)
- `stop_token_triggered == true` for all successful runs
- Latency within acceptable bounds for your hardware

**Stress Testing:**
Vary `max_tokens` (1024, 2048, 4096, 8192) and `temperature` (0.1, 0.3, 0.5) across the suite. Plot `reasoning_ratio` vs `max_tokens` to find the Pareto frontier where answer quality peaks without token waste.

**Visualization:**
Export results to CSV and use simple tools like `gnuplot`, `matplotlib`, or a lightweight dashboard (Grafana + InfluxDB) to track trends over time as you adjust settings.

# What The Flight Recorder Should Show
In a home-lab context, a "flight recorder" refers to your logging, metrics, and request/response capture pipeline. Here's what to look for to diagnose token exhaustion:

**llama.cpp Server Logs:**
Enable verbose logging with `--verbose` or `-v`. Look for:
- `tokens predicted: X` vs `n_predict: Y`: If X ≈ Y and no stop sequence matched, you hit the budget ceiling.
- `stop sequence matched: true/false`: If false, your `stop` array is missing, malformed, or not forwarded.
- `context overflow: true`: Indicates `ctx_size` is too small, causing prompt truncation and reasoning degradation.
- `generation time: Z ms`: High latency with low token output suggests sampling inefficiency or hardware bottlenecks.

**OpenWebUI Debug Logs:**
Check the browser console or OpenWebUI server logs for:
- `POST /api/v1/chat/completions` payload: Verify `max_tokens` and `stop` are present.
- `Streaming chunks`: If chunks stop abruptly without a stop token, it's a budget or proxy issue.
- `Error 429/500`: Proxy or backend overload causing silent drops.

**Proxy Access Logs:**
If using nginx/caddy, enable request body logging (carefully, as it's verbose). Look for:
- `stop` array presence in the JSON payload
- `max_tokens` value matching your OpenWebUI settings
- Header forwarding: Ensure `X-Forwarded-For` and `Host` don't interfere with payload routing.

**Token Distribution Analysis:**
Parse the raw response text to count tokens in reasoning vs answer phases. A healthy distribution looks like:
- Reasoning: 60–70% of budget
- Answer: 30–40% of budget
- Stop token triggered: Yes

A broken distribution looks like:
- Reasoning: 95–100% of budget
- Answer: 0%
- Stop token triggered: No
- Truncation: Yes

**Custom Metrics Endpoint:**
If you want programmatic tracking, add a middleware script that logs:
```json
{
  "request_id": "uuid",
  "max_tokens_sent": 3072,
  "max_tokens_used": 3072,
  "stop_matched": false,
  "reasoning_length": 2800,
  "answer_length": 0,
  "proxy_headers_preserved": true
}
```
Aggregate these over time to spot configuration drift or proxy misbehavior.

# Practical Defaults
Use these as a baseline for OpenWebUI + llama.cpp reasoning tasks. Adjust based on your model and hardware.

**OpenWebUI Advanced Parameters:**
```json
{
  "max_tokens": 3072,
  "stop": ["</think>", "\n\nANSWER:", "### Final Answer", "\n\nAnswer:"],
  "temperature": 0.2,
  "top_p": 0.9,
  "repeat_penalty": 1.1,
  "mirostat": 0,
  "mirostat_tau": 5.0,
  "mirostat_eta": 0.1,
  "grammar": null,
  "cache_prompt": true,
  "penalize_nl": false
}
```

**llama.cpp Server Flags:**
```bash
./server \
  -m your_model.gguf \
  --ctx-size 8192 \
  --n-predict 3072 \
  --temp 0.2 \
  --top_p 0.9 \
  --repeat-penalty 1.1 \
  --stop "</think>" \
  --stop "\n\nANSWER:" \
  --verbose
```

**Why These Values Work:**
- `max_tokens: 3072`: Leaves room for ~2000 tokens of reasoning and ~1000 for answer/formatting.
- `stop` array: Covers common reasoning model tags and explicit answer markers.
- `temperature: 0.2`: Low enough for focused reasoning, high enough to avoid rigid repetition.
- `repeat_penalty: 1.1`: Prevents looping without crushing creativity.
- `cache_prompt: true`: Speeds up repeated system prompts and few-shot examples.
- `penalize_nl: false`: Prevents the model from avoiding newlines, which are often used for phase transitions.

**Model-Specific Tweaks:**
- DeepSeek R1 / QwQ: Add `"<think>"` to `stop` if the model opens but doesn't close tags. Increase `max_tokens` to 4096 if reasoning is complex.
- Llama 3.1 / Mistral: Use `### Answer:` or `ANSWER:` markers. Keep `temperature` at 0.3 for more natural phrasing.
- Code models: Add `"\n```"` to `stop` if you want to halt after code blocks. Use `grammar` for strict JSON output.

# When To Increase Budgets
Increasing `max_tokens` is justified when:
1. **Multi-step reasoning is required**: Math proofs, complex logic puzzles, or multi-constraint optimization often need 2000–3000 tokens just for deliberation.
2. **Long-context analysis**: Summarizing or extracting from documents >4000 tokens requires proportional reasoning space.
3. **Code generation with tests**: Generating functions, unit tests, and documentation can easily exceed 2000 tokens.
4. **Multi-agent simulation**: If your prompt involves role-playing or iterative refinement, each turn consumes tokens.

**How to Increase Safely:**
- Increment by 512 or 1024 tokens, not 4096. Monitor `reasoning_ratio` after each increase.
- Pair budget increases with stricter `stop` sequences. More tokens without better control = more waste.
- Use dynamic budgeting if your proxy supports it: send `max_tokens: 2048` for simple queries, `max_tokens: 4096` for complex ones.
- Watch hardware limits: KV cache scales with `ctx_size` and `max_tokens`. If VRAM/RAM is constrained, increasing `max_tokens` may cause OOM errors or severe slowdowns.

**Diminishing Returns:**
Beyond ~4096–8192 generation tokens, quality often degrades. Attention mechanisms dilute over long sequences, repetition increases, and the model may lose track of the original question. If `reasoning_ratio` exceeds 0.85 consistently, increase `stop` specificity or simplify the prompt rather than adding tokens.

# When To Stop A Run
Not all generations should be allowed to run to completion. Implement abort conditions to save compute and prevent degenerate outputs.

**Hard Abort Thresholds:**
- Token usage > 85% of `max_tokens` with no answer marker detected
- Repeated phrases > 3 times (e.g., "Let's think step by step", "First, we need to")
- Generation time > 30 seconds with < 50 tokens output (hardware bottleneck or sampling loop)
- Proxy/backend errors (500, 429, timeout)
- Context overflow warnings in logs

**Implementation Strategies:**
1. **OpenWebUI Manual Stop**: Use the "Stop Generation" button immediately when you see unbounded reasoning. This sends an interrupt signal to llama.cpp.
2. **Automated Circuit Breaker**: Write a lightweight script that monitors streaming tokens, detects loops or budget exhaustion, and sends `Ctrl+C` or an API abort request.
3. **Proxy-Level Timeouts**: Configure your reverse proxy with `proxy_read_timeout 30s;` to kill hung generations.
4. **Token Budget Monitoring**: If your setup supports streaming, parse chunks in real-time. If `<think>` tokens exceed 70% of `max_tokens` without a transition marker, abort and retry with adjusted parameters.

**Handling Partial Outputs:**
- Save the reasoning phase to a file or database.
- Retry with a follow-up prompt: "Based on your reasoning so far, provide the final answer in the format: ANSWER: [result]."
- Reduce `max_tokens` by 25% and increase `repeat_penalty` to force convergence.
- If the model consistently fails, simplify the prompt or switch to a model with better instruction-following capabilities.

**Philosophy:**
Stopping early is better than wasting compute on degenerate generation. A truncated reasoning chain is often more useful than a complete but irrelevant output. Treat token budgets as finite resources, not infinite canvases. Configure, monitor, and abort proactively.