fix(youtube): las etiquetas salen del spec, no de la consulta de investigación
Build & Deploy ResearchOwl / build-and-push (push) Successful in 10s

El Short de Trans-en-Provence subió al canal en inglés etiquetado `análisis`,
`suelo`, `evidencia` y `física`; el de Cash-Landrum con `quemaduras`,
`radiación`, `demanda` y `gobierno`. Salían del `topic`, que es la consulta de
investigación y en la mitad de las sesiones está en español.

No se arregla con una lista de palabras en español ni con un detector de idioma,
que serían el parche sin fin — y además el criterio correcto no es el idioma:
`BASE AÉREA TALAVERA` es el nombre de la base y está DIBUJADO en pantalla, así
que etiquetarlo es correcto. Al revés, `Zimbabwe`, `Brazil` y `Texas` sólo
estaban en la consulta y son justo lo que se busca.

Así que el tema no se tira, se criba: llega a etiqueta si el vídeo lo dice. El
spec es inglés por construcción (título e id los escribe el modelo, los props
son lo dibujado), y sirve de criba sin que haya que saber de idiomas.

Y un segundo fallo que salió al medir: la etiqueta de frase se cortaba a media
palabra en CINCO de los ocho Shorts generados ("...GEPAN CNES análisis suelo
evi", "...demanda gobiern"). Eran etiquetas muertas, y era justamente la
etiqueta que la función existía para poner. Ahora sale del `meta.id`, que ya
venía en inglés y es la frase que se busca de verdad — "socorro 1964 zamora",
"ariel school 1994" — y el recorte, si hace falta, corta por palabra.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EHakatofHeJAzdXL26Q5bq
This commit is contained in:
ChemaVX
2026-09-02 08:25:55 +00:00
co-authored by Claude Opus 5
parent 068b7feefa
commit bf51fb30c0
2 changed files with 112 additions and 18 deletions
+54 -10
View File
@@ -326,8 +326,6 @@ def test_the_research_topic_never_reaches_the_description():
assert topic not in meta["snippet"]["description"]
for palabra in ("análisis", "suelo", "evidencia"):
assert palabra not in meta["snippet"]["description"]
# Pero sigue alimentando las etiquetas, donde una frase de búsqueda sí vale.
assert any(topic.startswith(tag[:20]) for tag in meta["snippet"]["tags"])
def test_the_description_survives_a_spec_with_nothing_to_cite():
@@ -348,21 +346,67 @@ def test_title_falls_back_to_the_topic():
def test_tags_drop_stopwords_and_duplicates_and_respect_the_limit():
tags = build_metadata(SPEC, "The Landing of the UFO in Socorro New Mexico"
)["snippet"]["tags"]
tags = build_metadata(SPEC, "The Radars of the FAA in Alaska")["snippet"]["tags"]
lowered = [t.casefold() for t in tags]
assert "the" not in lowered and "of" not in lowered and "in" not in lowered
assert len(lowered) == len(set(lowered))
assert "socorro" in lowered
assert "radars" in lowered, "el vídeo lo dice en el título"
assert "faa" in lowered, "el vídeo lo dibuja en un plano"
assert sum(len(t) + 1 for t in tags) <= yt.MAX_TAGS_CHARS
def test_the_whole_topic_is_one_tag():
"""Partido en palabras deja "New" y "Mexico" sueltas, que no buscan igual."""
tags = build_metadata(SPEC, "Socorro New Mexico 1964")["snippet"]["tags"]
assert "Socorro New Mexico 1964" in tags
assert "Socorro" in tags, "las sueltas también, que cuestan poco"
def test_tags_never_carry_the_spanish_that_only_lived_in_the_search_query():
"""El caso real: el Short de Trans-en-Provence, canal en inglés.
Se etiquetó con `análisis`, `suelo`, `evidencia` y `física` porque las
etiquetas salían del `topic`, que es la consulta de investigación. No se
arregla con una lista de palabras en español —eso es el parche sin fin—
sino cambiando de fuente: ahora salen del spec, que es inglés por
construcción, y del tema sólo lo que el vídeo de verdad dice.
"""
spec = {"meta": {"id": "trans_en_provence_1981",
"title": "Trans-en-Provence: Ground Trace, Lab Analysis"},
"shots": [{"template": "signal_strips",
"props": {"headline": "GEPAN ANALYSIS · SOIL"}}]}
topic = "Trans-en-Provence Francia 1981 GEPAN CNES análisis suelo evidencia física"
tags = build_metadata(spec, topic)["snippet"]["tags"]
lowered = {t.casefold() for t in tags}
for basura in ("análisis", "suelo", "evidencia", "física", "francia", "cnes"):
assert basura not in lowered, f"{basura} sólo estaba en la consulta"
# Y lo que el vídeo sí dice sobrevive.
assert "gepan" in lowered
assert "trans-en-provence" in lowered
def test_a_topic_word_survives_if_the_video_says_it():
"""La criba no es por idioma, es por si el vídeo lo dice.
Zimbabwe, Brazil y Texas sólo estaban en la consulta y son justo lo que se
busca; `BASE AÉREA TALAVERA` está en español y también, porque es el nombre
de la base y sale dibujado. Un filtro por idioma habría tirado los dos.
"""
spec = {"meta": {"id": "talavera_1976", "title": "Green Humanoid at the Air Base"},
"shots": [{"template": "data_card",
"props": {"card_title": "BASE AÉREA TALAVERA"}}]}
tags = build_metadata(spec, "Talavera 1976 OVNI humanoide Base Aérea")["snippet"]["tags"]
lowered = {t.casefold() for t in tags}
assert "aérea" in lowered, "está dibujado en pantalla"
assert "ovni" not in lowered and "humanoide" not in lowered
def test_the_phrase_tag_is_never_cut_mid_word():
"""En cinco de los ocho Shorts generados la frase salía partida —"...GEPAN
CNES análisis suelo evi"— y una frase partida no la busca nadie."""
largo = "_".join(["palabra"] * 12) # muy por encima de MAX_TAG
spec = {"meta": {"id": largo, "title": "T"}, "shots": []}
frase = build_metadata(spec, "x")["snippet"]["tags"][len(yt.BASE_TAGS)]
assert len(frase) <= yt.MAX_TAG
assert not frase.endswith("palabr"), "cortada a media palabra"
assert frase.split()[-1] == "palabra"
def test_tags_stay_under_the_limit_with_an_absurd_topic():