Spaces:
Running
Running
| #!/usr/bin/env python3 | |
| # -*- coding: utf-8 -*- | |
| """ | |
| qa.py — QA + SUMMARY via Groq uniquement (pas de LLM local) | |
| - Pas de fallback llama.cpp (trop lent). | |
| - Si GROQ_API_KEY n'est pas défini, on lève une erreur explicite. | |
| """ | |
| from __future__ import annotations | |
| import os | |
| from dataclasses import dataclass | |
| from typing import List, Dict | |
| from src.resources import generate_chat, is_groq_enabled | |
| # ==================== CONFIG ==================== | |
| class QAConfig: | |
| qa_top_k_final: int = int(os.environ.get("QA_TOP_K_FINAL", "2")) | |
| qa_doc_max_chars: int = int(os.environ.get("QA_DOC_MAX_CHARS", "700")) | |
| qa_max_tokens: int = int(os.environ.get("QA_MAX_TOKENS", "220")) | |
| qa_temperature: float = float(os.environ.get("QA_TEMPERATURE", "0.1")) | |
| # ==================== TEXT UTILS ==================== | |
| def truncate_text(s: str, n: int) -> str: | |
| if not s: | |
| return "" | |
| s = s.strip() | |
| return s if len(s) <= n else s[:n].rstrip() + "\n[...]\n" | |
| # ==================== PROMPTS ==================== | |
| def build_qa_prompt_fast(question: str, context: str, sources: List[str]) -> str: | |
| src = ", ".join(sources) if sources else "N/A" | |
| return f"""Tu es un assistant juridique francophone. Tu aides à comprendre le Code de l'éducation (France). | |
| RÈGLES STRICTES : | |
| - Réponds uniquement en français. | |
| - Appuie-toi en priorité sur le CONTEXTE fourni. | |
| - Si l'information n'est pas dans le contexte, dis-le explicitement. | |
| - Réponse courte et pratique (6 à 10 phrases maximum). | |
| - Ne cite pas de sources externes (sites, lois non fournies, jurisprudence, etc.). | |
| QUESTION : | |
| {question} | |
| CONTEXTE : | |
| {context} | |
| Termine par une ligne : | |
| Sources (articles) : {src} | |
| """ | |
| def build_summary_prompt(article_id: str, article_text: str) -> str: | |
| return f"""Tu es un assistant juridique francophone. | |
| LANGUE : réponds uniquement en français. | |
| TÂCHE : résumer fidèlement un article du Code de l'éducation à partir du texte fourni. | |
| RÈGLES STRICTES : | |
| - N'invente rien. Si une information n'est pas dans le texte, ne l'ajoute pas. | |
| - 4 puces maximum. | |
| - 1 seule phrase courte par puce. | |
| - Chaque puce ≤ 12 mots. | |
| - Ne pas numéroter. Ne pas écrire "Puce 1", "Puce 2". | |
| - Commence chaque ligne par "- ". | |
| - 45 mots maximum au total. | |
| - Ne rien écrire en dehors des puces. | |
| ARTICLE {article_id} (texte / extraits fournis) : | |
| {article_text} | |
| """ | |
| # ==================== GENERATION (GROQ ONLY) ==================== | |
| def llm_generate_qa(prompt: str, cfg: QAConfig | None = None) -> str: | |
| """ | |
| Génération via Groq uniquement. | |
| """ | |
| if not is_groq_enabled(): | |
| raise RuntimeError( | |
| "Groq n'est pas configuré : variable GROQ_API_KEY manquante. " | |
| "Ajoute GROQ_API_KEY (et optionnellement GROQ_MODEL) dans l'environnement." | |
| ) | |
| cfg = cfg or QAConfig() | |
| messages: List[Dict[str, str]] = [{"role": "user", "content": prompt}] | |
| return generate_chat( | |
| messages, | |
| max_tokens=cfg.qa_max_tokens, | |
| temperature=cfg.qa_temperature, | |
| ) | |