RAG — Retrieval-Augmented Generation
Per quin motiu es necessita RAG?
Els LLMs tenen dues limitacions fonamentals per a molts casos d'ús empresarials:
-
Coneixement congelat: El model sap el que ha vist durant l'entrenament (fins a la seva data de tall). No coneix les últimes notícies, els teus documents interns, els canvis de preus d'avui.
-
Al·lucinació: El model pot generar informació plausible però falsa, especialment sobre dades específiques, numèriques o molt especialitzades.
La solució: RAG (Retrieval-Augmented Generation) combina la capacitat de recuperació precisa d'informació (de documents reals) amb la capacitat de generar text fluid dels LLMs.
Arquitectura RAG
graph TD
USER[Usuari: pregunta] --> RET[Motor de Recuperacio]
RET --> VS[(Vector Store\ndocuments empresa)]
VS --> DOCS[Documents rellevants recuperats]
DOCS --> CONTEXT[Context augmentat\npregunta + documents]
CONTEXT --> LLM[LLM GPT-4o Claude Gemini]
LLM --> ANS[Resposta fonamentada\namb citacions]
ANS --> USER
Fase 1 — Indexació (offline): 1. Dividir els documents en fragments (chunks) de 200-500 tokens amb solapament 2. Generar un embedding per a cada chunk 3. Emmagatzemar els chunks i els seus embeddings en un vector store
Fase 2 — Recuperació i generació (online): 1. Rebre la consulta de l'usuari 2. Generar l'embedding de la consulta 3. Cercar els k chunks més similars al vector store (k=3-5 típicament) 4. Construir un prompt que inclou la consulta + els documents recuperats 5. Enviar el prompt al LLM 6. El LLM genera una resposta fonamentada en els documents, cita les fonts
Exemple de RAG simplificat
# pip install langchain langchain-openai chromadb sentence-transformers
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_openai import ChatOpenAI
from langchain.chains import RetrievalQA
# 1. Carreguem els documents
documents_text = """
MANUAL DE RECURSOS HUMANS — Institut Sa Palomera
Article 15 — Vacances
Els treballadors tenen dret a 23 dies laborables de vacances anuals.
Les vacances han de sol·licitar-se amb un mínim de 15 dies d'antelació.
Article 16 — Teletreball
S'autoritzen fins a 3 dies de teletreball setmanal per a llocs administratius.
Els docents no poden fer teletreball durant les hores de classe.
Article 20 — Formació contínua
L'empresa cofinança fins al 80% del cost de formacions relacionades amb el lloc
de treball, amb un màxim de 1.500 euros per persona i any.
"""
# 2. Dividim el text en fragments (chunks)
splitter = RecursiveCharacterTextSplitter(
chunk_size=300,
chunk_overlap=50,
separators=["\n\n", "\n", ". ", " "]
)
chunks = splitter.create_documents([documents_text])
print(f"Documents dividits en {len(chunks)} fragments")
# 3. Generem embeddings i creem el vector store
embeddings = HuggingFaceEmbeddings(
model_name="paraphrase-multilingual-mpnet-base-v2"
)
vectorstore = Chroma.from_documents(chunks, embeddings)
# 4. Creem la cadena RAG
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=vectorstore.as_retriever(search_kwargs={"k": 3}),
return_source_documents=True
)
# 5. Fem una pregunta
pregunta = "Quants dies de teletreball puc fer a la setmana?"
resultat = qa_chain.invoke({"query": pregunta})
print(f"\nPregunta: {pregunta}")
print(f"Resposta: {resultat['result']}")
Miniactivitat — AC5071/03/01 (CA3.7) — Sistema RAG bàsic
Implementa un sistema RAG mínim sobre un document de la teva elecció (pot ser el manual de convivència de l'escola, un article de Wikipedia, les instruccions d'un producte, etc.). Ha de poder respondre 5 preguntes sobre el document. Documenta el resultat indicant: quines preguntes ha respost bé, quines ha fallat i per quin motiu creus que ha fallat.