Saltar al contenido principal

Capítulo 1: Construcción de un Sistema de Preguntas y Respuestas sobre Documentos

Descripción general del proyecto​

Construya un sistema completo de preguntas y respuestas sobre archivos PDF con:

  • Carga y procesamiento de archivos PDF
  • Interfaz de chat con historial
  • Citación de fuentes

Arquitectura​

Paso 1: Configuración​

# requirements.txt
langchain==0.1.0
openai==1.3.0
chromadb==0.4.0
streamlit==1.28.0
pypdf==3.17.0

Paso 2: Procesamiento de documentos​

# document_processor.py
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma

def process_pdf(pdf_path, collection_name="docs"):
# Load
loader = PyPDFLoader(pdf_path)
documents = loader.load()

# Split
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
chunks = splitter.split_documents(documents)

# Embed and store
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(
chunks,
embeddings,
collection_name=collection_name,
persist_directory="./chroma_db"
)

return vectorstore

Paso 3: Cadena RAG​

# rag_chain.py
from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationalRetrievalChain
from langchain.memory import ConversationBufferMemory

def create_qa_chain(vectorstore):
llm = ChatOpenAI(model="gpt-4", temperature=0)

memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True,
output_key="answer"
)

chain = ConversationalRetrievalChain.from_llm(
llm=llm,
retriever=vectorstore.as_retriever(search_kwargs={"k": 3}),
memory=memory,
return_source_documents=True
)

return chain

Paso 4: Interfaz de usuario con Streamlit​

# app.py
import streamlit as st
from document_processor import process_pdf
from rag_chain import create_qa_chain

st.title("📄 Preguntas y Respuestas sobre Documentos")

# File upload
uploaded_file = st.file_uploader("Cargar PDF", type="pdf")

if uploaded_file:
# Process PDF
with st.spinner("Procesando..."):
vectorstore = process_pdf(uploaded_file)
chain = create_qa_chain(vectorstore)

# Chat interface
if "messages" not in st.session_state:
st.session_state.messages = []

for msg in st.session_state.messages:
st.chat_message(msg["role"]).write(msg["content"])

if prompt := st.chat_input("Pregunte sobre su documento"):
st.session_state.messages.append({"role": "user", "content": prompt})
st.chat_message("user").write(prompt)

response = chain({"question": prompt})
answer = response["answer"]

st.session_state.messages.append({"role": "assistant", "content": answer})
st.chat_message("assistant").write(answer)

# Show sources
with st.expander("Fuentes"):
for doc in response["source_documents"]:
st.write(f"Página {doc.metadata.get('page', 'N/A')}")
st.write(doc.page_content[:200] + "...")

Ejecución de la aplicación​

streamlit run app.py

Mejoras​

  • Añadir autenticación
  • Soporte para múltiples archivos PDF
  • Exportar conversaciones
  • Añadir reranking