Questo articolo fa parte di una serie chiamata Enterprise Document Intelligence, il cui punto di vista centrale è che l'enterprise RAG (RAG aziendale) potenzia l'esperto, senza sostituirlo. L'architettura proposta prevede quattro componenti fondamentali (document parsing, question parsing, retrieval e generation), ciascuna delle quali produce pezzi di dati tipizzati che convergono in un'unica chiamata al modello linguistico. Il termine ufficializzato è context engineering, riconosciuto e adottato a livello industriale come disciplina per fornire al modello le giuste informazioni riferite al compito da svolgere.
Il documento discusso è incentrato sulla versione a singolo documento; estensioni a corpus, conversazioni e chiamate a strumenti verranno affrontate in articoli successivi. L’obiettivo qui è illustrare l’architettura e come ogni blocco del sistema contribuisce alla generazione del risultato finale.
Il significato del termine "context engineering"
Nel giugno 2025, Tobi Lütke ha affermato su Twitter che l’espressione “prompt engineering” non era più adatta e ha proposto “context engineering” come termine alternativo, definendolo come “l’arte di fornire al modello un contesto completo per risolvere in modo plausibile una determinata attività”. Questa idea fu appoggiata da Andrej Karpathy, che la descrisse come “l’arte e la scienza delicata di riempire la finestra di contesto del modello con le informazioni esatte per il passo successivo”. Nei mesi successivi, il termine fu incluso in un libro di O’Reilly e organizzato in una taxonomia da LangChain.
Quali aspetti copre l'ingegneria del contesto
Il termine “context engineering” non include solo il prompt, ma ogni elemento che finisce all’interno della finestra di contesto del modello durante una chiamata:
- Il prompt system (ruolo, regole, esempi).
- I documenti recuperati o i record estratti.
- L'history della conversazione, se presente.
- I definitori degli strumenti e i relativi output.
- La memoria, i scratchpad, lo stato degli agenti.
- Le metadati strutturati relativi al documento, al corpus e al progetto.
- L'input effettivo dell'utente.
Con un agente in attività lunga che chiama il modello decine di volte, il prompt è uno dei sei o otto elementi necessari. Gli altri derivano da componenti esterni: un recuperatore, un tool, una memoria, una ricerca del profilo.
Struttura tipizzata e pipeline dei dati
Nell’architettura del sistema ogni brick emette informazioni tipizzate che convergono sul "PromptContext", dove vengono assemblate prima della chiamata al LLM.
- Parsing: restituisce tabelle relazionali e un dizionario di sintesi.
- Analisi delle domande: genera un oggetto ParsedQuestion con informazioni precise sull'intento, parole chiave, pagine specificate e forma attesa.
- Cerca: produce un subset di righe filtrate e un log dell'audit per chiarire chi ha deciso cosa.
- Generazione: utilizza i dati recuperati, lo schema tipizzato e il PromptContext per ottenere la risposta.
La pipeline e i quattro tipi di contesto in un RAG a singolo documento
Lavoriamo con sette tipi diversi di informazioni tipizzate che alimentano la finestra di contesto del modello. Essi sono organizzati in base all’origine: dal question, dai documenti e dall’infrastruttura.
La figura mostra questi canali di contesto tipizzato, che convergono nella sezione superiore chiamata PromptContext. Questa è formata da un PromptContext, da un system prompt fisso, e da un user template. Tutte si uniscono prima della chiamata al modello.
Output del parsing
Il parsing produce:
- Una tabella line_df, con una riga per ogni riga del documento e coordinate per i bounding box.
- Una tabella page_df, una riga per pagina con informazioni sul tipo e numero di colonne.
- Una tabella toc_df (sommario), con voce e pagina di inizio.
- Una tabella image_df per immagini annidate con hash e metadati.
- Un dizionario parsing_summary con informazione di sintesi su tipo di documento, numero di pagine, campi comuni, sommario.
Output dell’elaborazione della domanda
La struttura ParsedQuestion contiene:
- Un elenco breve di parole chiave che definiscono il contenuto richiesto.
- Un intento espresso come etichetta fissa (che guida la generazione).
- Un campo pages_hint quando l’utente specifica, ad esempio, “pagina 3”.
- La forma attesa (testo, importo, data, elenco, tabella, indirizzo).
Output del recupero
Il recupero produce:
- Un subset di line_df (righe selezionate).
- Un audit con metodi utilizzati (parole chiave, sommario, LLM arbitro), decisioni del modello, e log delle pagine selezionate.
Il ruolo della generazione
La generazione non produce contesto, lo utilizza. Riceve:
- La domanda elaborata (ParsedQuestion).
- Le righe filtrate dal recupero.
- Il PromptContext, che assembla contesto da molteplici fonti.
- Lo schema di risposta atteso (strutturato in Pydantic).
Implementazione con codice
La zona PROMPT ASSEMBLY a destra implementa praticamente l’ingegneria del contesto come codice. La sua struttura si articola in:
- Un aggregatore PromptContext (BaseModel) con un campo diverso per ogni fonte.
- Un prompt system modulo-fixed per ogni brick che chiamerà il LLM.
- Un user template modulo-variable con placeholder popolati da str.format(...).
Questi tre