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