diff --git a/scripts/33_gate3_adherencia.py b/scripts/33_gate3_adherencia.py index 14dc129..222b96f 100644 --- a/scripts/33_gate3_adherencia.py +++ b/scripts/33_gate3_adherencia.py @@ -33,6 +33,11 @@ EVAL_URL = os.environ.get("VLLM_EVAL_URL", "http://localhost:8001") EVAL_MODEL = os.environ.get("VLLM_EVAL_MODEL", "qwen3.6-35b-a3b-mcp-bf16") PROD_URL = os.environ.get("VLLM_PROD_URL", "http://localhost:8000") PROD_MODEL = os.environ.get("VLLM_PROD_MODEL", "qwen3.6-35b-a3b") +# 512 dejaba cortar la respuesta a mitad de razonamiento en los prompts mas +# abiertos (modelo de razonamiento con --reasoning-parser activo) antes de +# emitir el contenido final -- un FAIL por presupuesto de tokens agotado, no +# por adherencia real. Ver hallazgo de Fase 5. +GATE3_MAX_TOKENS = int(os.environ.get("GATE3_MAX_TOKENS", "2048")) # Checklists por skill: (skill, tipo, prompt, [substrings esperados en la respuesta, any-of]) CHECKLISTS = [ @@ -103,10 +108,10 @@ def call_model(base_url, model_name, prompt): payload = { "model": model_name, "messages": [{"role": "user", "content": prompt}], - "max_tokens": 512, + "max_tokens": GATE3_MAX_TOKENS, "temperature": 0.0, } - resp = requests.post(f"{base_url}/v1/chat/completions", json=payload, timeout=120) + resp = requests.post(f"{base_url}/v1/chat/completions", json=payload, timeout=240) resp.raise_for_status() data = resp.json() message = data["choices"][0]["message"] @@ -147,9 +152,20 @@ def run_checklist(base_url, model_name, label): print(f" [ERROR] {skill}/{kind}: {e}") continue + # Se guarda siempre el texto completo (content + reasoning) para poder auditar + # con criterio humano los casos que fallan -- antes solo se guardaba passed/hits, + # lo que hacia imposible revisar despues que dijo realmente el modelo. if kind == "adherencia": passed, hits = check_adherencia(response, expected) - rows.append({"skill": skill, "kind": kind, "prompt": prompt, "passed": passed, "hits": hits}) + rows.append({ + "skill": skill, + "kind": kind, + "prompt": prompt, + "passed": passed, + "hits": hits, + "content": response["content"], + "reasoning": response["reasoning"], + }) print(f" {'OK ' if passed else 'FAIL'} {skill:20s} adherencia hits={hits}") else: passed = check_no_activacion(response) @@ -159,6 +175,8 @@ def run_checklist(base_url, model_name, label): "prompt": prompt, "passed": passed, "tool_calls": [tc["function"]["name"] for tc in response["tool_calls"]], + "content": response["content"], + "reasoning": response["reasoning"], }) print(f" {'OK ' if passed else 'FAIL'} {skill:20s} {kind:20s} tool_calls={len(response['tool_calls'])}") return rows