feat(phase-2.5): population_prompt_diversity metric + piano aggiornato

Task 5 del piano Phase 2.5: nuovo modulo src/multi_swarm/metrics/diversity.py
con population_prompt_diversity(prompts) che ritorna la diversità media
1 - SequenceMatcher.ratio() su tutte le coppie distinte. 0.0 identici,
fino a ~0.9 totalmente diversi (SequenceMatcher considera spazi/lunghezza).

5 test: edge case empty/single, identici, diversi, intermediate, simmetria.

Piano aggiornato a stato "IMPLEMENTATO 2026-05-11": checkbox task 1-5
spuntate, task 6 (cost attribution per call_kind) deferito con motivazione.
Header preambolo aggiornato con trigger verificati e decisione collaterale
rollback tier C.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-11 23:52:09 +02:00
parent c38311e5fa
commit ec80af9f26
3 changed files with 102 additions and 20 deletions
+30
View File
@@ -0,0 +1,30 @@
"""Metriche di diversità popolazione.
``population_prompt_diversity`` calcola la diversità media fra i prompt di una
popolazione tramite la similarity di ``difflib.SequenceMatcher`` (proxy di
Levenshtein normalizzata): 0.0 = tutti i prompt identici, 1.0 = tutti diversi.
Usata come telemetry Phase 2.5 per monitorare se ``mutate_prompt_llm`` sta
effettivamente introducendo diversità di prompt nel pool.
"""
from __future__ import annotations
from difflib import SequenceMatcher
from itertools import combinations
def population_prompt_diversity(prompts: list[str]) -> float:
"""Diversità media (0.0 - 1.0) sui prompt della popolazione.
Calcolo: media di ``1 - similarity(a, b)`` su tutte le coppie distinte.
Per N prompt il numero di coppie è ``N*(N-1)/2``. Con N=20 sono 190 coppie
— trascurabile a livello di compute.
"""
if len(prompts) < 2:
return 0.0
diffs = [
1.0 - SequenceMatcher(None, a, b).ratio()
for a, b in combinations(prompts, 2)
]
return sum(diffs) / len(diffs)