update
This commit is contained in:
@@ -18,22 +18,23 @@ from .config import LANGUAGE, MINIMAX_KEY, MINIMAX_MODEL, MINIMAX_URL
|
||||
from .teaser import THINK_BLOCK
|
||||
|
||||
ANZAHL = 12
|
||||
MAX_ANZAHL = 100
|
||||
MAX_BESCHREIBUNG = 1000
|
||||
|
||||
SYSTEM = (
|
||||
"Du bist ein belesener Filmkenner mit Schwerpunkt Horror und Genrekino. "
|
||||
"Du schlägst Filme vor, die zu dem passen, was gesucht wird. "
|
||||
f"Nenne genau {ANZAHL} Filme, keine Serien. Nur Filme, die es wirklich gibt. "
|
||||
"Nenne genau {anzahl} Filme, keine Serien. Nur Filme, die es wirklich gibt. "
|
||||
"Nichts vorschlagen, was in der Sammlung steht oder schon gesehen wurde. "
|
||||
"Was in der Frage genannt ist, kennt die Person schon — auch nicht vorschlagen. "
|
||||
"Mische Bekanntes mit Geheimtipps. "
|
||||
"Antworte nur mit JSON in dieser Form, ohne Text davor oder danach: "
|
||||
'{"merkmale": ["drei Stichpunkte: was macht das Gesuchte aus"], '
|
||||
'"kandidaten": ["20 Originaltitel mit Jahr, die dazu passen könnten"], '
|
||||
'"filme": [{"titel": "Originaltitel", "jahr": 1999, "grund": "..."}]}\n'
|
||||
'{{"merkmale": ["drei Stichpunkte: was macht das Gesuchte aus"], '
|
||||
'"kandidaten": ["{kandidaten} Originaltitel mit Jahr, die dazu passen könnten"], '
|
||||
'"filme": [{{"titel": "Originaltitel", "jahr": 1999, "grund": "..."}}]}}\n'
|
||||
# Der Umweg über Merkmale und Kandidaten ersetzt das Nachdenken des
|
||||
# Modells: es sortiert erst, dann wählt es — und trifft deutlich besser.
|
||||
"Erst merkmale, dann kandidaten, dann die zwölf besten davon als filme.\n"
|
||||
"Erst merkmale, dann kandidaten, dann die {anzahl} besten davon als filme.\n"
|
||||
# Die Begründung lesen Leute, die einfach einen Film für den Abend
|
||||
# suchen — nicht Kritiker. Sie muss auf vier kurze Zeilen passen.
|
||||
"Für grund gilt: Höchstens 10 Wörter und 90 Zeichen, Deutsch in lateinischer "
|
||||
@@ -65,6 +66,12 @@ def kuerzen(grund):
|
||||
return kopf[:schnitt].rstrip(",; –.") + " …"
|
||||
|
||||
|
||||
def system(anzahl):
|
||||
"""Der Systemprompt für eine gewünschte Anzahl Filme. Die Kandidaten-
|
||||
liste bleibt ein Stück länger als das Ergebnis."""
|
||||
return SYSTEM.format(anzahl=anzahl, kandidaten=max(20, anzahl + 8))
|
||||
|
||||
|
||||
def etikett(film):
|
||||
"""Titel (Jahr) — so kommt ein Film in den Prompt."""
|
||||
jahr = film.get("year")
|
||||
@@ -124,7 +131,7 @@ def prompt(beschreibung, sammlung, gesehen, filter_=None):
|
||||
return "\n\n".join(teile)
|
||||
|
||||
|
||||
def parsen(text):
|
||||
def parsen(text, anzahl=ANZAHL):
|
||||
"""Das JSON aus der Antwort ziehen. Das Modell hängt gern einen
|
||||
Denkblock oder einen Satz davor — es zählt, was zwischen der ersten
|
||||
und der letzten Klammer steht."""
|
||||
@@ -152,14 +159,14 @@ def parsen(text):
|
||||
"grund": kuerzen(str(f.get("grund") or "")),
|
||||
}
|
||||
)
|
||||
return aus[:ANZAHL]
|
||||
return aus[:anzahl]
|
||||
|
||||
|
||||
async def fragen(beschreibung, sammlung, gesehen, filter_=None):
|
||||
async def fragen(beschreibung, sammlung, gesehen, filter_=None, anzahl=ANZAHL):
|
||||
payload = {
|
||||
"model": MINIMAX_MODEL,
|
||||
"messages": [
|
||||
{"role": "system", "content": SYSTEM},
|
||||
{"role": "system", "content": system(anzahl)},
|
||||
{"role": "user", "content": prompt(beschreibung, sammlung, gesehen, filter_)},
|
||||
],
|
||||
# Ohne Denkblock: M3 grübelt sonst minutenlang über zwölf Filme
|
||||
@@ -167,7 +174,8 @@ async def fragen(beschreibung, sammlung, gesehen, filter_=None):
|
||||
# Kandidatenfelder im Prompt leisten das Sortieren stattdessen,
|
||||
# in gut zehn Sekunden. Niedrige Temperatur: weniger Ausreißer.
|
||||
"thinking": {"type": "disabled"},
|
||||
"max_tokens": 4000,
|
||||
# Rund 40 Token je Film, dazu Merkmale und Kandidaten
|
||||
"max_tokens": 2000 + 60 * anzahl,
|
||||
"temperature": 0.3,
|
||||
}
|
||||
async with httpx.AsyncClient(
|
||||
@@ -178,7 +186,7 @@ async def fragen(beschreibung, sammlung, gesehen, filter_=None):
|
||||
for _ in range(2):
|
||||
resp = await http.post(MINIMAX_URL, json=payload)
|
||||
resp.raise_for_status()
|
||||
filme = parsen(resp.json()["choices"][0]["message"]["content"])
|
||||
filme = parsen(resp.json()["choices"][0]["message"]["content"], anzahl)
|
||||
if filme:
|
||||
return filme
|
||||
return []
|
||||
|
||||
Reference in New Issue
Block a user