76 lines
4.8 KiB
Python
76 lines
4.8 KiB
Python
#!/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())
|