Skip to content

Commit 321caa3

Browse files
committed
docs: document Qwen3 thinking-mode quirks and the ReAct workarounds
New subsection 'Handling Qwen3's known quirks' inside the ReAct agent section explains: - Qwen3 ships with thinking mode on by default and emits <think> blocks that break strict-format agents. - The pipeline applies four defensive patches: /no_think prefix, _strip_thinking() post-processing, English system prompt with a few-shot example, and TEMPERATURE=0.0 default. - Out-of-scope Qwen3 caveats: shaky native tool calling via OVMS (which is why we use a text-prompted ReAct loop), and ~32k context window. Both README.md (EN) and README.es.md (ES) updated symmetrically.
1 parent c40c0f9 commit 321caa3

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

README.es.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,32 @@ Open WebUI → Admin Panel → Pipelines → `react-agent` → Valves. Puedes aj
327327
- `MODEL` (cambiar a otro modelo de OVMS)
328328
- `SHOW_TRACE` (oculta el trace si quieres sólo la respuesta final)
329329

330+
**Manejando las peculiaridades conocidas de Qwen3**:
331+
332+
Qwen3 viene con **thinking mode activado por defecto** — emite bloques
333+
`<think>...</think>` con razonamiento libre antes de cualquier salida
334+
estructurada. Eso rompe la gramática estricta `Thought: / Action: /
335+
Action Input:` en la que se basa el loop ReAct. Este pipeline aplica
336+
cuatro parches defensivos:
337+
338+
| Parche | Por qué es necesario |
339+
|---|---|
340+
| El system prompt empieza con `/no_think` | Directiva oficial de Qwen3 para saltarse la fase de thinking. Sin esto el modelo divaga en prosa y el parser regex falla en el turno 1. |
341+
| La salida pasa por `_strip_thinking()` (elimina cualquier bloque `<think>...</think>`) antes de parsear | Defensa por si Qwen3 ignora el `/no_think` en algún turno. Lo limpiamos en vez de fallar. |
342+
| System prompt en **inglés** con ejemplo few-shot | Qwen3 sigue mejor las instrucciones en inglés; el instruction-tuning está sesgado hacia ese idioma. |
343+
| `TEMPERATURE` default `0.0` (antes 0.2) | El cumplimiento del formato se vuelve determinista. Súbela vía valves solo si quieres variedad estilística en las respuestas. |
344+
345+
Estos cuatro parches juntos llevan el loop de "falla en el primer turno"
346+
a "completa en ~4 s una query con `calc`" sobre el mismo hardware.
347+
348+
Otros caveats de Qwen3 que quedan fuera del pipeline pero conviene saber:
349+
- **Tool calling nativo de OpenAI**: el soporte de `tools=[...]` de
350+
Qwen3-8B vía OVMS es flojo. Usamos un loop ReAct por texto en su
351+
lugar — más lento, pero mucho más fiable en modelos pequeños.
352+
- **Ventana de contexto**: ~32k tokens. Traces ReAct largos con muchas
353+
llamadas a tools pueden pasarse; baja `MAX_ITERATIONS` o
354+
`MAX_TOKENS_PER_STEP` si ves truncado.
355+
330356
**Pipelines vs Tools nativas — cuándo usar qué**:
331357
- *Tools nativas* (paso 5): el LLM elige cuándo llamarlas vía `tools=[...]` en la API. Más rápido, menos transparente.
332358
- *ReAct pipeline*: loop explícito en Python, controlas iteraciones y prompt, ves todos los pasos. Más robusto cuando el modelo flojea en function calling nativo.

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,31 @@ Open WebUI → Admin Panel → Pipelines → `react-agent` → Valves. You can t
332332
- `MODEL` (point at a different OVMS model)
333333
- `SHOW_TRACE` (hide the trace if you only want the final answer)
334334

335+
**Handling Qwen3's known quirks**:
336+
337+
Qwen3 ships with **thinking mode enabled by default** — it emits free-form
338+
`<think>...</think>` blocks before any structured output. That breaks the
339+
strict `Thought: / Action: / Action Input:` grammar the ReAct loop relies on.
340+
This pipeline applies three defensive patches:
341+
342+
| Patch | Why it's needed |
343+
|---|---|
344+
| System prompt starts with `/no_think` | Qwen3's official directive to skip the thinking phase. Without it the model rambles in prose and the regex parser bails on turn 1. |
345+
| Output is run through `_strip_thinking()` (removes any `<think>...</think>` blocks) before parsing | Defensive — Qwen3 occasionally still emits a short `<think>` even with `/no_think`. We strip it instead of failing. |
346+
| System prompt is in **English** with a few-shot example | Qwen3 follows English ReAct system prompts more reliably than Spanish; instruction tuning is heavily weighted toward English. |
347+
| Default `TEMPERATURE = 0.0` (was 0.2) | Format compliance becomes deterministic. Raise via valves only if you want stylistic variety in answers. |
348+
349+
These four patches together make the loop go from "fails immediately"
350+
to "completes in ~4 s for a `calc` query" on the same hardware.
351+
352+
Other Qwen3 caveats that are out of scope of this pipeline but worth knowing:
353+
- **Native OpenAI tool calling**: Qwen3-8B's `tools=[...]` support is shaky
354+
via OVMS. We use a text-prompted ReAct loop instead, which is slower but
355+
far more reliable on small models.
356+
- **Context window**: ~32k tokens. Long ReAct traces with many tool calls
357+
can blow past it; lower `MAX_ITERATIONS` or `MAX_TOKENS_PER_STEP` if you
358+
see truncation.
359+
335360
**Pipelines vs native Tools — when to use which**:
336361
- *Native tools* (step 5): the LLM decides when to call them via `tools=[...]` in the API. Faster, less transparent.
337362
- *ReAct pipeline*: explicit loop in Python, you control iterations and prompt, you see every step. More robust when the model is shaky on native function calling.

0 commit comments

Comments
 (0)