feat(chatbot-pensees): garde-fou serveur des citations (guillemets retirés si introuvables)

La route demande include_references + include_chunk_content à LightRAG et vérifie
chaque segment >= 6 mots entre « » / "…" / “…” dans les chunks réellement
récupérés (normalisation accents, casse, apostrophes, ponctuation, élisions [...]).
Un segment introuvable perd ses guillemets (texte conservé) ; champ optionnel
citations: { gardees, retirees }. Fonction pure dans server/utils/citations.ts,
réutilisée par scripts/verif-citations.mjs (qui gagne --max-total-tokens) ;
scripts/test-citations.mjs couvre les cas limites.

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:59:32 +02:00
co-authored by Claude Opus 5.5
parent 52b79e1e8e
commit 85cd31d201
4 changed files with 154 additions and 21 deletions
+12 -1
View File
@@ -7,6 +7,7 @@ import { readFileSync } from 'node:fs'
import { join } from 'node:path'
import { checkRateLimitJson } from '~/server/utils/rateLimitJson'
import { profondeurDuBody, REGLE_GUILLEMETS } from '~/server/utils/bifrost'
import { verifierCitations, contenusChunks } from '~/server/utils/citations'
/**
* Règle citations — commune aux 4 préambules (mesure M7 du 05/10 : le modèle invente des
@@ -158,6 +159,9 @@ export default defineEventHandler(async (event) => {
const ragBody: Record<string, any> = {
query,
mode,
// textes des chunks utilisés : sert au garde-fou des citations (server/utils/citations.ts)
include_references: true,
include_chunk_content: true,
user_prompt: profondeur === 'approfondi'
? `${systemPreface}\n\n${POSTURE_REFLEXION}\n\n${REGLE_CITATIONS}`
: `${systemPreface}\n\n${REGLE_CITATIONS}`,
@@ -193,8 +197,15 @@ export default defineEventHandler(async (event) => {
}
}
// Garde-fou : un segment long entre guillemets absent des chunks récupérés perd ses guillemets.
const verif = verifierCitations(String(ragResponse.response ?? ''), contenusChunks(ragResponse.references))
if (verif.retirees > 0) {
console.warn(`[chatbot-pensees] ${verif.retirees} citation(s) non retrouvée(s) dans le contexte, guillemets retirés (${verif.gardees} gardée(s))`)
}
return {
response: ragResponse.response ?? '',
response: verif.texte,
citations: { gardees: verif.gardees, retirees: verif.retirees },
mode,
corpus,
auteur: auteurSlug && nomAuteurMatch ? { slug: auteurSlug, nom: nomAuteurMatch } : null,