Add ikario_processual with David profile and embedding script

- david_profile_declared.json: David's declared profile values from questionnaire
- scripts/embed_david.py: Python script to generate embeddings using BGE-M3 model
- questionnaire_david.md: Questionnaire template for profile values

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-31 16:56:41 +01:00
parent 9e657cbf29
commit 21f5676c7b
18 changed files with 5463 additions and 0 deletions

View File

@@ -0,0 +1,211 @@
#!/usr/bin/env python3
"""
Phase 2 : Creation des directions de projection.
Ce script:
1. Cree la collection ProjectionDirection dans Weaviate
2. Genere les vecteurs de direction par contraste (BGE-M3)
3. Sauvegarde les directions dans Weaviate
4. Calcule et affiche le profil de S(0)
Usage:
python phase2_projection_directions.py
python phase2_projection_directions.py --dry-run
python phase2_projection_directions.py --reset
"""
import argparse
import sys
from pathlib import Path
import numpy as np
# Ajouter le parent au path
sys.path.insert(0, str(Path(__file__).parent.parent))
from state_vector import (
check_weaviate_ready,
get_state_vector,
)
from projection_directions import (
get_existing_classes,
create_projection_direction_collection,
delete_projection_direction_collection,
create_direction_by_contrast,
save_direction,
get_all_directions,
get_state_profile,
format_profile,
DIRECTIONS_CONFIG,
)
def print_section(title: str):
print("\n" + "=" * 60)
print(title)
print("=" * 60)
def main():
parser = argparse.ArgumentParser(
description="Phase 2: Creation des directions de projection"
)
parser.add_argument(
"--dry-run",
action="store_true",
help="Simuler sans creer"
)
parser.add_argument(
"--reset",
action="store_true",
help="Supprimer et recreer la collection"
)
args = parser.parse_args()
print_section("PHASE 2 : DIRECTIONS DE PROJECTION")
# 1. Verifier Weaviate
print("\n[1/5] Verification Weaviate...")
if not check_weaviate_ready():
print("ERREUR: Weaviate non accessible")
sys.exit(1)
print(" Weaviate [OK]")
# 2. Gerer la collection ProjectionDirection
print("\n[2/5] Collection ProjectionDirection...")
existing = get_existing_classes()
if "ProjectionDirection" in existing:
if args.reset:
print(" Suppression de la collection existante...")
if not args.dry_run:
delete_projection_direction_collection()
print(" Collection supprimee")
else:
print(" [DRY-RUN] Suppression simulee")
else:
# Verifier combien de directions existent
directions = get_all_directions()
if len(directions) > 0:
print(f" Collection existe avec {len(directions)} directions")
print(" Utilisez --reset pour reinitialiser")
# Afficher le profil de S(0) quand meme
print("\n[INFO] Affichage du profil S(0) existant...")
s0 = get_state_vector(0)
if s0:
state_vec = np.array(s0.get("_additional", {}).get("vector", []))
if len(state_vec) > 0:
profile = get_state_profile(state_vec)
print(format_profile(profile))
sys.exit(0)
# Creer la collection
if args.dry_run:
print(" [DRY-RUN] Creation collection simulee")
else:
if "ProjectionDirection" not in get_existing_classes():
create_projection_direction_collection()
# 3. Charger le modele
print("\n[3/5] Chargement du modele BGE-M3...")
if args.dry_run:
print(" [DRY-RUN] Chargement simule")
model = None
else:
try:
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('BAAI/bge-m3')
print(" Modele charge [OK]")
except ImportError:
print("ERREUR: sentence-transformers non installe")
print(" pip install sentence-transformers")
sys.exit(1)
# 4. Creer les directions
print("\n[4/5] Creation des directions par contraste...")
print(f" {len(DIRECTIONS_CONFIG)} directions a creer")
print()
created_count = 0
for name, config in DIRECTIONS_CONFIG.items():
category = config["category"]
positive = config["positive_examples"]
negative = config["negative_examples"]
if args.dry_run:
print(f" [DRY-RUN] {name} ({category})")
print(f" + {len(positive)} exemples positifs")
print(f" - {len(negative)} exemples negatifs")
created_count += 1
else:
# Calculer la direction
direction_vec = create_direction_by_contrast(positive, negative, model)
# Sauvegarder
obj_id = save_direction(name, config, direction_vec)
if obj_id:
print(f" [OK] {name} ({category})")
created_count += 1
else:
print(f" [FAIL] {name}")
print(f"\n Total: {created_count}/{len(DIRECTIONS_CONFIG)} directions creees")
# 5. Calculer le profil de S(0)
print("\n[5/5] Calcul du profil de S(0)...")
if args.dry_run:
print(" [DRY-RUN] Profil simule")
else:
# Recuperer S(0)
s0 = get_state_vector(0)
if not s0:
print(" ERREUR: S(0) non trouve. Executez d'abord phase1_state_vector.py")
sys.exit(1)
state_vec = np.array(s0.get("_additional", {}).get("vector", []))
if len(state_vec) == 0:
print(" ERREUR: S(0) n'a pas de vecteur")
sys.exit(1)
# Calculer le profil
profile = get_state_profile(state_vec)
print("\n PROFIL DE S(0) - Etat initial d'Ikario")
print(" " + "-" * 50)
print(format_profile(profile))
# Resume
print_section("PHASE 2 TERMINEE")
if args.dry_run:
print("\n[DRY-RUN] Aucune modification effectuee")
else:
print("\nResultat:")
print(f" - Collection ProjectionDirection creee")
print(f" - {created_count} directions creees:")
# Grouper par categorie
by_category = {}
for name, config in DIRECTIONS_CONFIG.items():
cat = config["category"]
if cat not in by_category:
by_category[cat] = []
by_category[cat].append(name)
for cat, names in sorted(by_category.items()):
print(f" {cat}: {', '.join(names)}")
print("\nTests de validation:")
print(" curl -s 'http://localhost:8080/v1/objects?class=ProjectionDirection' | jq '.objects | length'")
print(" python -c \"from projection_directions import *; print(get_all_directions())\"")
print("\nProchaine etape:")
print(" python scripts/phase3_transformation.py")
if __name__ == "__main__":
main()