Overview

RAG Chatbot

Componente Angular <wuic-rag-chatbot> che permette di interrogare il codebase

WUIC in linguaggio naturale, con due modalita' operative: retrieval pure

(top-K snippet del codice) e RAG + LLM (risposta generata da Claude usando

i top-K come contesto). Degrada automaticamente in retrieval-only se la API

key Claude non e' configurata sul server.

Architettura

Stack a 3 layer, tutti gia' deployati nel progetto:

  • Layer 1 — Server Python FastAPI rag_server.py su 127.0.0.1:8765,

carica al boot l'indice ibrido BM25 + bge-m3 + LoRA cross-encoder Phase C

da c:/src/Wuic/codebase_embeddings/.

  • Layer 2 — Bridge C# RagController in KonvergenceCore (/api/Rag/Query,

/api/Rag/Chat, /api/Rag/Health, /api/Rag/Reload), proxy autenticato

via cookie k-user.

  • Layer 3 — Componente Angular standalone <wuic-rag-chatbot> esportato

da wuic-framework-lib.

Vedi anche la skill operativa skills/rag-chatbot-creation/SKILL.md per il

playbook end-to-end di creazione/manutenzione del componente, e

skills/rag-rebuild-pipeline/SKILL.md per il rebuild dell'indice/LoRA.

Contesto pagina e retrieval dinamico dei metadata

Quando l'utente chatta da una pagina dell'app, il componente inietta nel prompt

un contesto pagina minimale: solo la route/pagina corrente (es. cities/list,

cities/edit, designer). NON inlinea l'elenco colonne, l'identita' SQL o i

dettagli dei lookup — inlinearli gonfiava ogni richiesta a prescindere dal prompt

e saturava il context window.

I dettagli mancanti vengono recuperati on-demand dal modello tramite il tool

non-terminale request_metadata_detail, risolto lato backend da

RagController.ResolveMetadataDetail (l'engine non ha accesso al DB metadata). Il

modello chiama il tool, riceve il risultato come tool_result e SOLO DOPO emette

il propose_* con i nomi reali. Il loop multi-turn e' gestito dall'engine (max 3

turni di retrieval).

detail supportati:

detailRitornaQuando
columnsidentita' SQL (schema/tabella + full qualifier) e l'elenco colonne reali (nome, tipo, lookup, required, pk, nome SQL)servono i nomi reali delle colonne di una route
lookup_columnsjoin_alias, value_field, text_field, related_route, related_columns[] di una colonna lookupByIDsi compone uno snippet SQL su un lookup

Convenzione alias di join (lookup): la query autogenerata WUIC joina la tabella

correlata di una colonna lookupByID con alias <column>_<entity> (es. la colonna

StateProvinceID lookup verso stateprovinces ha alias StateProvinceID_stateprovinces).

Negli snippet SQL i campi della tabella correlata si referenziano come

[<join_alias>].[<col>], es. [StateProvinceID_stateprovinces].[StateProvinceName].

Il valore esatto dell'alias va sempre ottenuto via

request_metadata_detail{detail:'lookup_columns'}, mai dedotto a mano.

Il meccanismo e' estendibile: nuovi detail (es. physical_columns, related_routes,

enum_values) si aggiungono nel resolver senza toccare il componente Angular ne'

gonfiare il contesto.

Modalita'

mode inputComportamento
auto (default)Usa chat se il backend espone Claude API key, altrimenti retrieval
chatForza RAG + LLM. Se la API key manca, il backend ritorna mode=retrieval-only con warning visibile
retrievalForza retrieval-only, salta la chiamata LLM (utile per ridurre costi)

Inputs

InputTipoDefaultDescrizione
titlestring'Assistente codebase WUIC'Etichetta header
mode'auto' | 'chat' | 'retrieval''auto'Modalita' operativa
topKnumber5Numero di chunk da retrieve dal RAG
showSourcesbooleantrueMostra/nasconde i source chip nei messaggi assistant
maxHistorynumber20Numero massimo di turn mantenuti in memoria
placeholderstring'Chiedi qualcosa...'Placeholder dell'input
modelstring'claude-haiku-4-5-20251001'Modello Claude per la modalita' chat
chatHeightstring'420px'Altezza fissa area chat
showClearButtonbooleantrueMostra bottone "Svuota cronologia"

Outputs

OutputPayloadDescrizione
resultSelectedRagSourceClick su un source chip; il componente tenta anche un deep-link vscode://file/...
errorOccurred{message, details?}Errori HTTP non recuperabili
turnAddedRagChatbotTurnEmette dopo ogni turn (user o assistant) aggiunto alla history

Esempio d'uso

Standalone import nel componente parent:

  • selector HTML: <wuic-rag-chatbot mode="auto" [topK]="5" (resultSelected)="onSrc($event)"></wuic-rag-chatbot>
  • import TypeScript: import { WuicRagChatbotComponent, RagSource } from 'wuic-framework-lib';
  • aggiungere WuicRagChatbotComponent agli imports del componente standalone parent.

Per una pagina demo completa con aside debug e gestione eventi, vedi

WuicTest/wwwroot/src/app/component/rag-chatbot-demo-page/.

Auth

Tutte le chiamate HTTP partono con withCredentials: true e il bridge C#

applica gli stessi check di autenticazione degli altri controller WUIC

(cookie di sessione k-user, regola 10 di AGENTS). Mai esporre il server

Python 127.0.0.1:8765 direttamente al browser: deve sempre essere proxiato

dal C#.

Service WuicRagService

API tipizzata sopra RagController, esportata da wuic-framework-lib.

Tre metodi principali:

  • query(text, {topK, useLora}) -> Observable<RagQueryResponse>
  • chat(text, history, {topK, model}) -> Observable<RagChatResponse>
  • health() -> Observable<RagHealthResponse>
  • reload() -> Observable<{status, ...}> (post rebuild RAG)

Varianti *Async ritornano Promise via firstValueFrom().

Tutte le interfacce RagSource, RagQueryResponse, RagChatResponse,

RagHealthResponse, RagChatTurn sono esportate.

Modello Claude

Default: claude-haiku-4-5-20251001 (veloce, italiano nativo, ~$0.001 per

query da 5 chunk). Override possibile via input [model] del componente

oppure passando options.model al metodo chat() del service.

System prompt usato server-side:

> Sei un assistente esperto del codebase WUIC. Rispondi alla domanda dell'utente

> usando ESCLUSIVAMENTE il contesto fornito. Se la risposta non e' nel contesto,

> rispondi 'Non ho trovato informazioni sufficienti nel codebase per rispondere.'

> Cita sempre i file rilevanti tra parentesi quadre nel formato

> [file.ext::SimboloOpzionale]. Rispondi in italiano salvo richiesta esplicita

> di un'altra lingua. Non inventare API o nomi di metodi: se non sono nel

> contesto, dillo esplicitamente.

Fallback automatico

Quando il backend rileva una di queste condizioni, il response include

mode: 'retrieval-only' + warning + sources:

  • ANTHROPIC_API_KEY non settata sul server Python
  • chiamata Claude fallita (errore HTTP, rate limit, modello sconosciuto, ecc.)

Il componente Angular interpreta response.mode === 'retrieval-only' e mostra

nel turn assistant un summary testuale dei top-K chunk + il banner warning,

cosi' l'utente vede comunque dei risultati utili.

Prerequisiti runtime

  • Server Python rag_server.py attivo su 127.0.0.1:8765 (vedi skill

rag-chatbot-creation per il setup NSSM in produzione)

  • KonvergenceCore in esecuzione (espone /api/Rag/...)
  • Login con cookie k-user di sessione valido
  • (Opzionale) ANTHROPIC_API_KEY env var sul server Python per modalita' chat

Avvio (primo utilizzo)

Se accedendo alla route rag-chatbot dal menu vedi il banner

"Server RAG non raggiungibile" con stato RAG offline, significa che il

server Python non e' in ascolto.

Prerequisiti: Python 3.12 (winget install Python.Python.3.12)

Setup e avvio con rag-setup.ps1

Lo script rag-setup.ps1 automatizza la creazione del venv e l'installazione

delle dipendenze. Funziona sia dal repository sorgente che da un pacchetto

ZIP di deploy (i file RAG sono inclusi in entrambi).

Snippet 1PowerShell
# Setup (una sola volta) — crea venv, installa torch + dipendenze
pwsh scripts/rag-setup.ps1

# Per GPU CUDA (opzionale, piu' veloce)
pwsh scripts/rag-setup.ps1 -CudaVersion 12.1

# Avvio server

Il cold start richiede ~13 secondi (caricamento indice + LoRA). Una volta

che il log mostra Uvicorn running on http://127.0.0.1:8765, ricarica la

pagina nel browser: il banner scompare e il chatbot passa in modalita'

operativa.

Per produzione (Windows service persistente) vedi la skill

skills/rag-chatbot-deploy/SKILL.md.

Hot-reload post rebuild RAG

Dopo aver rigenerato l'indice/LoRA con la skill rag-rebuild-pipeline, basta

chiamare:

  • POST /api/Rag/Reload (via WuicRagService.reload())
  • oppure restartare il servizio Python

per ricaricare il nuovo indice senza downtime applicativo.

Test

I test del service e del componente sono in:

  • projects/wuic-framework-lib/src/lib/service/wuic-rag.service.spec.ts (14 test)
  • projects/wuic-framework-lib/src/lib/component/rag-chatbot/rag-chatbot.component.spec.ts (18 test)

Eseguibili con npm run test:unit:wuic-lib (vitest, runner di default del lib

post-migrazione karma->vitest).

Riferimenti

  • Skill creazione: skills/rag-chatbot-creation/SKILL.md
  • Skill rebuild RAG: skills/rag-rebuild-pipeline/SKILL.md
  • Server Python: c:/src/Wuic/codebase_embeddings/rag_server.py
  • Bridge C#: c:/src/Wuic/KonvergenceCore/Controllers/RagController.cs
  • Service Angular: projects/wuic-framework-lib/src/lib/service/wuic-rag.service.ts
  • Componente: projects/wuic-framework-lib/src/lib/component/rag-chatbot/rag-chatbot.component.ts
  • Demo page: c:/src/Wuic/WuicTest/wwwroot/src/app/component/rag-chatbot-demo-page/