lunes, 9 de marzo de 2026

proyecto completo ingesta de pdfs

 lista de acciones a seguir

1- PC necesita https://visualstudio.microsoft.com/es/downloads/ 


específicamente descargar Herramientas de compilación para Visual Studio 2026

2- en anaconda ejecutar los siguientes comandos:

conda create -n ia_proyectos python=3.10 -y

conda activate ia_proyectos

pip install llama-cpp-python

pip install langchain langchain-community langchain-huggingface langchain-chroma pypdf sentence-transformers flask


3- crear ingesta de datos:

import os

from langchain_community.document_loaders import PyPDFLoader

from langchain_text_splitters import RecursiveCharacterTextSplitter

from langchain_huggingface import HuggingFaceEmbeddings

from langchain_chroma import Chroma


def generar_base():

    path_pdfs = "./mis_documentos"

    path_db = "./db_vectorial"

    

    if not os.path.exists(path_pdfs): os.makedirs(path_pdfs)


    print("Cargando y fragmentando PDFs...")

    documentos = []

    # Fragmentos un poco más pequeños para facilitar el procesamiento en CPU

    text_splitter = RecursiveCharacterTextSplitter(chunk_size=700, chunk_overlap=100)


    for archivo in [f for f in os.listdir(path_pdfs) if f.endswith('.pdf')]:

        try:

            loader = PyPDFLoader(os.path.join(path_pdfs, archivo))

            documentos.extend(text_splitter.split_documents(loader.load()))

            print(f" -> {archivo} procesado.")

        except Exception as e:

            print(f"Error en {archivo}: {e}")


    print(f"\nGenerando vectores en '{path_db}' (Usando CPU)...")

    # Este modelo es excelente y muy ligero para CPU

    model_kwargs = {'device': 'cpu'}

    embeddings = HuggingFaceEmbeddings(

        model_name="sentence-transformers/all-MiniLM-L6-v2",

        model_kwargs=model_kwargs

    )

    

    Chroma.from_documents(

        documents=documentos,

        embedding=embeddings,

        persist_directory=path_db

    )

    print("\n¡ÉXITO! Base vectorial lista en disco.")


if __name__ == "__main__":

    generar_base()


4- realizar prueba a la ingesta de datos

from langchain_chroma import Chroma

from langchain_huggingface import HuggingFaceEmbeddings


def realizar_busqueda():

    path_db = "./db_vectorial"

    

    # Forzamos el uso de CPU para los embeddings

    model_kwargs = {'device': 'cpu'}

    embeddings = HuggingFaceEmbeddings(

        model_name="sentence-transformers/all-MiniLM-L6-v2",

        model_kwargs=model_kwargs

    )

    

    vector_db = Chroma(persist_directory=path_db, embedding_function=embeddings)

    

    while True:

        pregunta = input("\n🔎 Consulta (o 'salir'): ")

        if pregunta.lower() == 'salir': break

        

        # Buscamos los 3 fragmentos más relevantes

        resultados = vector_db.similarity_search_with_relevance_scores(pregunta, k=3)

        

        if not resultados:

            print("No se encontró información relacionada.")

            continue


        print("\nTOP 3 FRAGMENTOS ENCONTRADOS:")

        print("="*60)

        for i, (doc, score) in enumerate(resultados):

            print(f"FUENTE {i+1} | Relevancia: {round(score * 100, 2)}%")

            print(f"ARCHIVO: {doc.metadata.get('source')}")

            print(f"CONTENIDO: {doc.page_content[:400]}...")

            print("-" * 60)


if __name__ == "__main__":

    realizar_busqueda()