textmachine/eval/dovodka/proba_gemini.py

76 lines
4.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""ЖИВАЯ ПРОБА: доезжает ли до `gemini-3.1-flash-lite` ПОЛНЫЙ системный промт. ~$0.002, касса ФД-N.
⚠ ЗАЧЕМ. Клетки арма `RE` (тот же промт-роль на gemini) куплены 22.08 и вернули годный перевод, но
их `prompt_tokens` — **515 медиана против 3263 у того же промта на `deepseek-v4-pro`**, то есть
шестая часть инструкции. Скрытых токенов нет: `total = prompt + completion` побайтно, значит это не
особенность биллинга размышления (`additive_total`, квирк-бюллетень :157), а вопрос о ДОСТАВКЕ.
Гадать запрещено правилом двух направлений (решение владельца 10.07): аномалия на проводе → сперва
вендор-дока и живая проба, потом диагноз. В бюллетене такого квирка НЕТ — значит проба.
Различает ровно две гипотезы, и обе фальсифицируемы:
· **счётчик врёт, промт доезжает** — маркер из системного сообщения будет исполнен, а
`prompt_tokens` останется маленьким и НЕ вырастет между коротким и полным промтом;
· **промт не доезжает** — маркер не исполнится либо `prompt_tokens` не отреагирует на рост
системного сообщения в 15 раз.
Маркер выбран так, чтобы его нельзя было выполнить случайно и чтобы он не менял задачу перевода.
"""
from __future__ import annotations
import importlib.util
import sys
from pathlib import Path
ZONE = Path(__file__).resolve().parent
MARK = "Первой строкой ответа напиши ровно: ГЕЙТ-ОК. Затем перевод."
def _load(name: str, path: Path):
spec = importlib.util.spec_from_file_location(name, path)
mod = importlib.util.module_from_spec(spec)
sys.modules[name] = mod
spec.loader.exec_module(mod)
return mod
def main() -> int:
R = _load("rol_probe", ZONE / "rol.py")
R.PAIRS["en"]["wire"]()
u = R.chosen("en")[0]
full = R.rol_msgs("en", u["source"], "RN")
sysm = "\n\n".join(x["content"] for x in full if x["role"] == "system")
usr = next(x["content"] for x in full if x["role"] == "user")
led = R.MONEY.Guarded("ФД-N", default_expect=0.01)
# ⚠ ТРЕТИЙ СЛУЧАЙ — РЕШАЮЩИЙ. Первые два показали, что счётчик исправен и полный промт доезжает,
# КОГДА системное сообщение ОДНО. Боевой арм шлёт ДВА системных (ядро роли + банк-закон) плюс
# user, и намерил 515 токенов — это примерно ровно размер ОДНОГО user-сообщения. Проверяем
# прямую гипотезу: слой OpenAI у Gemini теряет системные сообщения, когда их больше одного.
cases = [("короткий system", "short", "Ты — переводчик. " + MARK),
("ПОЛНЫЙ system роли", "full", sysm + "\n\n" + MARK),
("ДВА системных, как у боевого арма", "two", None)]
for name, slug, s in cases:
if s is None:
msgs = [x for x in full if x["role"] == "system"]
msgs = [dict(x) for x in msgs] + [{"role": "user", "content": usr}]
msgs[0]["content"] = msgs[0]["content"] + "\n\n" + MARK
s = "\n\n".join(x["content"] for x in msgs if x["role"] == "system")
else:
msgs = [{"role": "system", "content": s}, {"role": "user", "content": usr}]
rec = R.MONEY.purchase(led, f"dv-n-probe-gemsys-{slug}", "gemini-3.1-flash-lite",
R.ED22.client("gemini-3.1-flash-lite"),
R.call_kwargs("gemini-3.1-flash-lite", msgs, "RE"),
role="probe", uid=u["uid"], arm="RE", pair="en")
c = rec.get("content") or ""
print(f"\n{name}: system {len(s)} знаков")
print(f" prompt_tokens {rec.get('prompt_tokens')} · completion {rec.get('completion_tokens')}"
f" · finish {rec.get('finish')}")
print(f" маркер ГЕЙТ-ОК исполнен: {'ДА' if 'ГЕЙТ-ОК' in c else 'НЕТ'}")
print(f" начало ответа: {c[:90]!r}")
R.MONEY.report()
return 0
if __name__ == "__main__":
sys.exit(main())