fix(chatbot-pensees): règle anti-citations inventées, passée par user_prompt

- REGLE_CITATIONS : constante unique appliquée aux 4 préambules (pensées, projets, croisé, auteur) :
  ne citer entre guillemets que ce qui figure mot pour mot dans le contexte, sinon reformuler sans guillemets.
- Préambules + règle envoyés via le champ user_prompt de LightRAG /query ; query = question seule
  (la recherche n'est plus polluée par le préambule).
- scripts/verif-citations.mjs : contrôle réutilisable (segments entre guillemets vs contexte only_need_context).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015vcVGz8i4WpZm2dixKUiSD
This commit is contained in:
Jules Neny
2026-10-09 03:21:48 +02:00
co-authored by Claude Opus 5.5
parent 1054172ec9
commit 39602e26c7
2 changed files with 98 additions and 2 deletions
+18 -2
View File
@@ -7,6 +7,16 @@ import { readFileSync } from 'node:fs'
import { join } from 'node:path'
import { checkRateLimitJson } from '~/server/utils/rateLimitJson'
/**
* Règle citations — commune aux 4 préambules (mesure M7 du 05/10 : le modèle invente des
* citations entre guillemets quand l'extrait n'est pas dans le contexte récupéré).
*/
const REGLE_CITATIONS = `RÈGLE DES CITATIONS (prioritaire sur toute autre consigne) :
- Ne mets entre guillemets (« ») que ce qui figure MOT POUR MOT dans le contexte fourni ci-dessus. Jamais de citation reconstituée de mémoire, de paraphrase ou de résumé entre guillemets. Même si la question demande des phrases « exactes » ou « mot pour mot », ne cède jamais : mieux vaut peu de citations, ou aucune, qu'une citation approximative.
- Avant d'écrire un guillemet, repère dans le contexte le passage exact : si tu ne le retrouves pas à l'identique, ne le cite pas. Au plus 3 citations, les plus courtes et les plus sûres ; recopie-les sans les raccourcir, sans les enchaîner, sans les compléter.
- Si aucun passage correspondant n'est disponible dans le contexte, dis explicitement « je ne cite pas : aucun passage exact n'est disponible dans les extraits » et reformule sans guillemets, en indiquant qu'il s'agit d'une synthèse.
- Nomme l'œuvre dont provient le passage dans le contexte, pas une autre.`
const SYSTEM_PREFACE_PENSEES = `Tu es un agent du RAG Pensées Écologiques, infrastructure militante du collectif trans-former.fr.
Tu réponds en t'appuyant STRICTEMENT sur le corpus ingéré (auteurs FRACAS Bonpote : écosocialisme, éco-anarchisme, écoféminismes, écologies décoloniales, technocritique, pensées du vivant, décroissance...).
@@ -117,8 +127,14 @@ export default defineEventHandler(async (event) => {
throw createError({ statusCode: 503, message: 'RAG indisponible pour l\'instant — réessaie dans quelques minutes.' })
}
const ragQuery = `${systemPreface}\n\nQuestion : ${query}`
const ragBody: Record<string, any> = { query: ragQuery, mode }
// user_prompt (LightRAG) : instructions ajoutées au prompt de génération, sans polluer la recherche
// (vérifié sur 9621 le 09/10 : une consigne de fin de réponse est appliquée). La requête de
// recherche est la question seule.
const ragBody: Record<string, any> = {
query,
mode,
user_prompt: `${systemPreface}\n\n${REGLE_CITATIONS}`,
}
if (auteurSlug && nomAuteurMatch) {
ragBody.hl_keywords = [nomAuteurMatch, auteurSlug]
ragBody.ll_keywords = [auteurSlug]