Una risposta sui tuoi documenti è buona solo quanto il testo da cui è stata costruita, e quando incolli file interi in una chat non puoi sapere quale parte il modello abbia effettivamente usato. GroupDocs.Search.Mcp, in esecuzione localmente in Docker, fornisce a Claude Desktop, Cursor o Copilot un primitivo diverso: get_text_fragments restituisce solo i passaggi che corrispondono a una query, con poche parole di contesto e il file da cui provengono, così l’agente risponde citando:

Cosa dicono i miei contratti riguardo alle penali? Cita i passaggi, con abbastanza contesto per capire ciascuno.

La versione passo‑passo con configurazione e risoluzione dei problemi è nella documentazione: How to get the matching passages instead of reading whole files.

Perché le risposte si allontanano dai documenti?

Perché la finestra di contesto è un budget, e i documenti interi lo consumano in modo inefficiente. Una domanda sulle penali potrebbe richiedere forse tre frasi su cinquanta pagine. Incolla le cinquanta pagine e il modello deve trovare le tre frasi da solo, tra tutto il resto, e poi trattenerle mentre scrive. I contesti lunghi vengono riassunti, il materiale iniziale perde peso, e la risposta inizia a basarsi sul senso generale del modello di ciò che i contratti di solito dicono piuttosto che su ciò che dicono i tuoi. L’industria chiama la disciplina di gestire questo context engineering; la forma più semplice è non caricare testo di cui non hai bisogno.

Come appare un frammento?

L’indice contiene già il testo di ogni documento, quindi il server può estrarre il passaggio intorno a ciascuna corrispondenza. Queste sono risposte reali dal nostro test, su cinque contratti sintetici. Le impostazioni predefinite, otto parole per lato, forniscono una frase:

-> get_text_fragments {"query":"penalty","indexName":"contracts"}
<- === contracts/acme-master-services-agreement.pdf (1 occurrence(s)) ===
     [content] …before the end of the Term, a termination penalty of
   three monthly fees applies, payable within 30…

Venti parole per lato restituiscono l’intera clausola:

-> get_text_fragments {"query":"penalty","indexName":"contracts",
     "termsBefore":20,"termsAfter":20,"maxFragmentsPerDocument":1}
<- === contracts/acme-master-services-agreement.pdf (1 occurrence(s)) ===
     …convenience on 90 days written notice.
   12.3 If the Client terminates before the end of the Term, a termination
   penalty of three monthly fees applies, payable within 30 days of the
   termination date.
   14.2 Force majeure: neither party is…

termsBefore e termsAfter sono una manopola: piccola per “quali file e più o meno dove”, grande per “citami la clausola”. maxFragmentsPerDocument e maxDocuments limitano la dimensione della risposta, così una parola che compare duecento volte non inonda il contesto.

Il budget, a confronto

Reading the files                        Searching the index
-------------------------------------    -------------------------------------
agent opens every document               search: which files match (JSON)
  context grows with the corpus          get_text_fragments: the passages
  long files crowd out the question        (~8 words either side, per file)
  repeated for every question            answer cites file + passage
                                         the index is reused next time

La differenza cresce con il corpus. Per tre file brevi conta poco. Per una cartella di contratti lunghi, report e mail, i frammenti per una domanda sono poche centinaia di parole, contro il testo completo di ogni documento candidato.

Quando le parole differiscono

La ricerca full‑text corrisponde alle parole, il che è una caratteristica per il grounding (ogni risultato è spiegabile) e un limite per il recall (un sinonimo è una mancata corrispondenza). Il compito dell’agente è provare varianti, e può vedere cosa ha effettivamente corrisposto ogni variante:

-> search {"query":"renewal OR renews","indexName":"contracts"}
<- umbrella-office-lease.pdf, terms ["renewal", "renews"]

-> search {"query":"renewl","indexName":"contracts","fuzzy":true}
<- umbrella-office-lease.pdf, terms ["renewal", "renews", "rent"]

Il matching fuzzy ha salvato un errore di battitura e ha anche introdotto rent. Poiché la risposta elenca i termini corrisposti, un agente, o tu, puoi vedere l’over‑match invece di fidarti ciecamente. Questa trasparenza è ciò che “grounded” dovrebbe significare: non solo “la risposta cita una fonte”, ma “puoi vedere come è stata trovata la fonte”.

Come appare una risposta grounded

Chiedi citazioni, e la risposta arriva in una forma che puoi verificare a colpo d’occhio:

Due contratti prevedono una penale di risoluzione. Acme MSA, clausola 12.3: “a termination penalty of three monthly fees applies, payable within 30 days of the termination date.” Accordo di consulenza Globex, sezione 9: “the Client pays 50 percent of the fees remaining for the current phase.” L’NDA di Initech menziona risoluzione e penale ma afferma che non esiste alcuna penale.

Se un riassunto interpreta male una citazione, l’interpretazione errata si trova subito accanto alla citazione.

Limiti onesti

  • In modalità valutazione un indice contiene al massimo 100 documenti e una ricerca restituisce al massimo 10. La modalità valutazione aggiunge anche una riga “Evaluation only…” al testo indicizzato di alcuni formati, che può comparire nei frammenti; licenzia il server e ricostruisci l’indice per rimuoverla. Chiama prima get_license_status.
  • Il contesto del frammento è contato in parole, non in frasi, quindi un passaggio può iniziare a metà frase; aumenta termsBefore quando è importante.
  • Nessun OCR: scansioni senza livello di testo non hanno passaggi da restituire.
  • Solo Docker; su Linux aggiungi --user "$(id -u):$(id -g)".

FAQ

Come faccio a far citare a Claude le fonti dai miei documenti?
Forniscigli uno strumento che restituisce il testo della fonte con il nome del file. get_text_fragments fa esattamente questo, e un’istruzione come “quote the passage and its file” lo rende un’abitudine.

Questo riduce l’uso di token?
Evita di caricare documenti interi per rispondere a una domanda: l’agente legge solo i passaggi corrispondenti. Quanto risparmia dipende dalle dimensioni dei tuoi file.

L’agente può ancora leggere un file intero quando necessario?
Sì, con i propri strumenti per i file. I frammenti servono per trovare e citare; leggi l’intero file quando il passaggio non è sufficiente.

Approfondisci