8. Responder en Base a Texto Propio - 1

 

8: Responder en Base a Texto Propio - 1

馃幆 Tema: Construyendo Bases de Conocimiento Multiples para Chatbots Especializados

馃摎 Introducci贸n: Del Archivo 脷nico a la Biblioteca de Conocimiento

¡Hola muchachos! Hoy vamos a escalar nuestro proyecto: en lugar de tener un solo archivo de conocimiento, crearemos una biblioteca completa de informaci贸n.

Analog铆a: Si antes ten铆amos un solo libro (info.txt), ahora tendremos una biblioteca con varios libros (info1.txt, info2.txt, etc.) que nuestro asistente puede consultar.


馃攧 Parte 1: La Importancia de Usar Texto Plano (TXT)

¿Por qu茅 TXT y no PDF?

Diagrama de Comparaci贸n:

text
┌─────────────────┐         ┌─────────────────┐
│   ARCHIVO PDF   │         │   ARCHIVO TXT   │
├─────────────────┤         ├─────────────────┤
│ Formato complejo│         │ Texto simple    │
│ Necesita extraer│         │ Listo para usar │
│ │               │         │ │               │
│  PDF → Python   │         │  TXT → Python   │
│  │ (con librer铆a)│         │  │ (directamente)│
│  ↓               │         │  ↓              │
│  Texto → Guardar│         │  Usar           │
│  │ como TXT      │         │                 │
│  ↓               │         │                 │
│  Leer TXT        │         │                 │
└─────────────────┘         └─────────────────┘
      ║                           ║
      ║                           ║
      ╚═══════════════════════════╝
                │
                ▼
          ┌─────────────┐
          │   OLLAMA    │
          │    (IA)     │
          └─────────────┘

Problema con PDF:

python
# ❌ M谩s complejo, m谩s pasos
import PyPDF2  # Necesitas instalar librer铆a adicional
pdf = open("documento.pdf", "rb")
lector = PyPDF2.PdfReader(pdf)
texto = ""
for pagina in lector.pages:
    texto += pagina.extract_text()
# Luego guardas como TXT o usas directamente

Ventaja con TXT:

python
# ✅ Simple y directo
with open("documento.txt", "r", encoding="UTF-8") as archivo:
    texto = archivo.read()  # ¡Listo!

Regla de oro para principiantes:

"Si puedes tener la informaci贸n en TXT desde el principio, evita formatos complejos como PDF."


馃摎 Parte 2: Creando Nuestra Biblioteca de Archivos

Ejemplo de Estructura de Archivos:

Archivo 1: cursos.txt

txt
CURSOS DE ANDERCODE:

Programaci贸n Web:
- API REST con Laravel: Aprende a crear APIs profesionales
- Laravel Blog Real: Desarrolla un blog completo desde cero
- JavaScript Moderno: Dominia ES6+, async/await, frameworks

M贸viles:
- Flutter Completo: Apps iOS y Android con un solo c贸digo
- React Native: Desarrollo nativo con JavaScript

Base de Datos:
- Curso B谩sico de SQL: Desde cero hasta consultas avanzadas
- MongoDB para Principiantes: Bases de datos NoSQL

Bots y Automatizaci贸n:
- Bots con WhatsApp: Automatiza mensajes y respuestas
- Bots con Python: Crea asistentes inteligentes
- Bots con Node.js: Backend para chatbots

Pagos y E-commerce:
- PayPal Integration: Integra pagos en tu aplicaci贸n
- Stripe API: Sistema de pagos profesional

Archivo 2: servicios.txt

txt
SERVICIOS DE ANDERCODE:

Desarrollo a Medida:
- Aplicaciones Web Personalizadas
- Sistemas de Gesti贸n Empresarial
- Plataformas E-learning

Consultor铆a:
- Arquitectura de Software
- Optimizaci贸n de Bases de Datos
- Migraci贸n a la Nube

Mentor铆a:
- Sesiones 1:1 de Programaci贸n
- Revisi贸n de C贸digo
- Plan de Carrera en Tech

Precios:
- Desarrollo: $50/hora
- Consultor铆a: $80/hora  
- Mentor铆a: $40/hora

Estructura de carpetas:

text
mi_chatbot/
├── app.py
├── cursos.txt        ← Archivo 1: Cat谩logo de cursos
├── servicios.txt     ← Archivo 2: Servicios y precios
├── contacto.txt      ← Archivo 3: Informaci贸n de contacto
└── templates/
    └── index.html

馃敡 Parte 3: Mejorando la Funci贸n de Carga

Versi贸n Mejorada: Leer M煤ltiples Archivos

python
def cargar_contenido():
    """
    Lee M脷LTIPLES archivos TXT y los combina en un solo texto
    """
    archivos = ["cursos.txt", "servicios.txt", "contacto.txt"]
    contenido_completo = ""
    
    for nombre_archivo in archivos:
        try:
            with open(nombre_archivo, "r", encoding="UTF-8") as archivo:
                contenido_completo += archivo.read() + "\n\n"
                # \n\n a帽ade espacio entre archivos
        except FileNotFoundError:
            print(f"⚠️ Advertencia: No se encontr贸 {nombre_archivo}")
            continue  # Contin煤a con el siguiente archivo
    
    return contenido_completo

Esquema Visual de la Funci贸n:

text
┌─────────────────────────────────────┐
│ FUNCI脫N cargar_contenido()         │
├─────────────────────────────────────┤
│ 1. Lista de archivos a leer:       │
│    ["cursos.txt", "servicios.txt"] │
│                                    │
│ 2. Para cada archivo en la lista:  │
│    ├── Abrir archivo               │
│    ├── Leer todo su contenido      │
│    └── A帽adir al total             │
│                                    │
│ 3. Si un archivo no existe:        │
│    └── Mostrar advertencia y       │
│        continuar con los dem谩s     │
│                                    │
│ 4. Devolver todo el texto combinado│
└─────────────────────────────────────┘

Analog铆a:
Piensa en esta funci贸n como un bibliotecario que:

  1. Sabe qu茅 libros necesita (lista de archivos)

  2. Toma cada libro de la estanter铆a

  3. Lee todas sus p谩ginas

  4. Junta todo en un gran informe


馃搹 Parte 4: ¡Cuidado con los L铆mites!

El L铆mite de Tokens/Contexto

¿Qu茅 son los tokens?

  • 1 token ≈ 0.75 palabras en espa帽ol

  • 100 tokens ≈ 75 palabras

  • Los modelos tienen l铆mites (ej: 4096, 8192 tokens)

Ejemplo visual del l铆mite:

text
┌─────────────────────────────────────────────────┐
│ L脥MITE DEL MODELO: 8000 CARACTERES             │
├─────────────────────────────────────────────────┤
│                                                 │
│  cursos.txt      │ servicios.txt │ contacto.txt │
│  (3000 chars)    │ (2000 chars)  │ (1000 chars) │
│                  │               │              │
│  ─────────────────────────────────────────────── │
│  TOTAL: 6000 CARACTERES (DENTRO DEL L脥MITE) ✓  │
│                                                 │
│  ─────────────────────────────────────────────── │
│  Si a帽adimos FAQ.txt (3000 chars):              │
│                                                 │
│  cursos.txt │ servicios.txt │ contacto.txt      │
│             │               │ FAQ.txt           │
│  ─────────────────────────────────────────────── │
│  TOTAL: 9000 CARACTERES (EXCEDE L脥MITE) ✗      │
└─────────────────────────────────────────────────┘

Consejo pr谩ctico:

python
# Verifica el tama帽o aproximado
contenido = cargar_contenido()
print(f"Caracteres totales: {len(contenido)}")
print(f"Palabras aproximadas: {len(contenido.split())}")

# Si excede ~8000 caracteres, considera dividir
if len(contenido) > 8000:
    print("⚠️ Advertencia: Podr铆as exceder el l铆mite del modelo")

馃挰 Parte 5: Pruebas con M煤ltiples Archivos

Tabla de Pruebas y Resultados:

PreguntaArchivos ConsultadosRespuesta¿Correcto?
"Br铆ndame 5 cursos"cursos.txtLista 5 cursos espec铆ficos
"Cursos de Flutter"cursos.txtMenciona curso de Flutter
"Precios de servicios"servicios.txtMuestra precios por hora
"Cursos de PayPal"cursos.txtMenciona integraci贸n PayPal
"¿Tienen mentor铆a?"servicios.txtDescribe servicio de mentor铆a

Ejemplo de Conversaci贸n Completa:

text
T煤: ¿Qu茅 cursos de programaci贸n web tienen?
IA: Ofrecemos: API REST con Laravel, Laravel Blog Real, 
    JavaScript Moderno. Todos incluyen proyectos pr谩cticos.

T煤: ¿Cu谩nto cuesta la consultor铆a?
IA: El servicio de consultor铆a tiene un precio de $80/hora. 
    Incluye an谩lisis de arquitectura y optimizaci贸n.

T煤: ¿Y los bots con WhatsApp?
IA: S铆, tenemos el curso "Bots con WhatsApp" donde 
    aprendes a automatizar mensajes y respuestas.

T煤: ¿Qu茅 es Python? (no est谩 en los archivos)
IA: No est谩 en el documento.

馃洜️ Parte 6: Mejoras en el C贸digo

Versi贸n Mejorada con Manejo de Errores:

python
def cargar_contenido_mejorada():
    """
    Versi贸n mejorada que maneja errores y verifica l铆mites
    """
    # Lista TODOS los archivos que quieres incluir
    archivos_a_cargar = [
        "cursos.txt",
        "servicios.txt", 
        "contacto.txt",
        # "faq.txt",  # Puedes descomentar si a帽ades m谩s
        # "testimonios.txt"
    ]
    
    contenido_total = ""
    archivos_cargados = []
    
    for archivo in archivos_a_cargar:
        try:
            with open(archivo, "r", encoding="UTF-8") as f:
                texto = f.read()
                contenido_total += f"\n--- {archivo.upper()} ---\n"
                contenido_total += texto + "\n"
                archivos_cargados.append(archivo)
                
                print(f"✓ Cargado: {archivo} ({len(texto)} caracteres)")
                
        except FileNotFoundError:
            print(f"✗ No encontrado: {archivo}")
        except Exception as e:
            print(f"⚠️ Error leyendo {archivo}: {str(e)}")
    
    print(f"\n馃搳 RESUMEN: {len(archivos_cargados)}/{len(archivos_a_cargar)} archivos cargados")
    print(f"馃搹 Total caracteres: {len(contenido_total)}")
    
    if len(contenido_total) > 8000:
        print("馃敶 ADVERTENCIA: Podr铆a exceder el l铆mite del modelo")
    
    return contenido_total

馃捈 Parte 7: Aplicaciones Empresariales Reales

Ejemplos de Archivos para Diferentes Negocios:

txt
# RESTAURANTE
menu.txt          ← Platos, precios, ingredientes
horarios.txt      ← Horas de atenci贸n, d铆as especiales
ubicacion.txt     ← Direcci贸n, tel茅fono, mapa

# TIENDA ONLINE  
productos.txt     ← Cat谩logo con precios y descripciones
envios.txt        ← Costos de env铆o, tiempos, zonas
garantias.txt     ← Pol铆ticas de devoluci贸n y garant铆a

# CL脥NICA M脡DICA
servicios.txt     ← Consultas, estudios, precios
doctores.txt      ← Especialistas y horarios
seguros.txt       ← Aseguradoras aceptadas

# ESCUELA
cursos.txt        ← Materias, horarios, profesores
requisitos.txt    ← Documentaci贸n necesaria
costos.txt        ← Matr铆culas, mensualidades

Beneficios para Tu Negocio:

  1. Respuestas consistentes: Todos reciben la misma informaci贸n

  2. Disponible 24/7: Atiende incluso fuera de horario

  3. Escalable: Mismo esfuerzo para 10 o 10,000 consultas

  4. Reducci贸n de costos: Menos personal en atenci贸n al cliente


馃摑 Cuestionario de Repaso

Pregunta 1: ¿Por qu茅 es mejor usar TXT que PDF para nuestra base de conocimiento?

a) Los PDF son m谩s seguros
b) Los TXT se leen directamente sin conversi贸n
c) Los PDF tienen mejores colores
Respuesta correcta: b

Pregunta 2: ¿Qu茅 hace el \n\n al final de cada archivo le铆do?

a) Cierra el archivo
b) A帽ade espacio entre archivos (salto de l铆nea doble)
c) Lo convierte a PDF
Respuesta correcta: b

Pregunta 3: Si tenemos 3 archivos de 3000 caracteres cada uno, ¿excedemos el l铆mite de ~8000?

a) S铆 (3000×3 = 9000)
b) No (3000×3 = 6000)
c) Depende del modelo
Respuesta correcta: a

Pregunta 4: ¿Qu茅 significa "continue" en el bucle cuando un archivo no se encuentra?

a) Termina todo el programa
b) Salta ese archivo y contin煤a con los dem谩s
c) Crea el archivo autom谩ticamente
Respuesta correcta: b

Pregunta 5: ¿Para qu茅 sirve el encoding="UTF-8" al abrir archivos?

a) Para leer archivos PDF
b) Para manejar correctamente tildes y caracteres especiales
c) Para hacerlos m谩s r谩pidos
Respuesta correcta: b


馃挕 Consejos para Implementar en Tu Negocio:

  1. Empieza peque帽o: 1-2 archivos bien estructurados

  2. Organiza por temas: Un archivo por categor铆a

  3. Mant茅n actualizado: Revisa y actualiza peri贸dicamente

  4. Prueba con usuarios reales: Pide feedback de las respuestas

  5. Monitorea el tama帽o: No excedas los l铆mites del modelo


馃帀 ¡Tu Chatbot Ahora es un Experto en Varios Temas!

Logros de hoy:
✅ Aprendimos por qu茅 TXT es mejor que PDF
✅ Creamos m煤ltiples archivos de conocimiento
✅ Mejoramos la funci贸n de carga para varios archivos
✅ Entendimos los l铆mites de tama帽o
✅ Probamos con casos empresariales reales

Pr贸ximo paso: ¡Vamos a hacerlo a煤n m谩s inteligente!


馃搨 C贸digo Final Mejorado (app.py):

python
from flask import Flask, render_template, request
import requests

app = Flask(__name__)
conversation = []

OLLAMA_URL = "http://localhost:11434/api/generate"
MODEL_NAME = "gemma3:4b"

# --- FUNCI脫N MEJORADA para m煤ltiples archivos ---
def cargar_contenido():
    """
    Carga y combina M脷LTIPLES archivos TXT
    """
    # Lista TODOS tus archivos de conocimiento aqu铆
    lista_archivos = [
        "cursos.txt",      # Archivo 1: Cat谩logo de cursos
        "servicios.txt",   # Archivo 2: Servicios y precios
        "contacto.txt"     # Archivo 3: Informaci贸n de contacto
    ]
    
    contenido_combinado = ""
    archivos_exitosos = 0
    
    for archivo in lista_archivos:
        try:
            with open(archivo, "r", encoding="UTF-8") as f:
                texto = f.read()
                # A帽ade un separador con el nombre del archivo
                contenido_combinado += f"\n\n[CONTENIDO DE {archivo.upper()}]:\n"
                contenido_combinado += texto
                archivos_exitosos += 1
                print(f"✅ {archivo} cargado correctamente")
                
        except FileNotFoundError:
            print(f"⚠️ {archivo} no encontrado. Continuando...")
        except Exception as e:
            print(f"❌ Error leyendo {archivo}: {e}")
    
    print(f"\n馃搳 Resumen: {archivos_exitosos}/{len(lista_archivos)} archivos cargados")
    print(f"馃搹 Caracteres totales: {len(contenido_combinado)}")
    
    # Advertencia si se acerca al l铆mite
    if len(contenido_combinado) > 7000:
        print("馃毃 ADVERTENCIA: Podr铆as acercarte al l铆mite del modelo")
    
    return contenido_combinado

@app.route("/", methods=["GET", "POST"])
def index():
    if request.method == "POST":
        user_input = request.form["user_input"]
        conversation.append(("T煤", user_input))
        
        try:
            # Cargar TODOS los archivos
            contexto = cargar_contenido()
            
            # Crear prompt con todo el conocimiento
            prompt_especializado = f"""
            Eres un asistente especializado. 
            Responde SOLO bas谩ndote en la siguiente informaci贸n.
            Si la respuesta no est谩 en la informaci贸n, di "No est谩 en el documento".
            
            INFORMACI脫N DISPONIBLE:
            {contexto}
            
            PREGUNTA DEL USUARIO:
            {user_input}
            
            RESPUESTA:
            """
            
            payload = {
                "model": MODEL_NAME,
                "prompt": prompt_especializado,
                "stream": False
            }
            
            response = requests.post(OLLAMA_URL, json=payload, timeout=30)
            
            if response.status_code == 200:
                ai_response = response.json()["response"]
                conversation.append(("IA", ai_response))
            else:
                conversation.append(("IA", "❌ Error al contactar con la IA"))
                
        except Exception as e:
            conversation.append(("IA", f"⚠️ Error del sistema: {str(e)}"))
    
    return render_template("index.html", conversation=conversation)

if __name__ == "__main__":
    app.run(debug=True, port=5000)

馃殌 ¡Ahora tienes un chatbot que conoce toda tu empresa! En la pr贸xima clase exploraremos t茅cnicas a煤n m谩s avanzadas

Comentarios

Entradas m谩s populares de este blog

Tutorial completo de Ollama: Instalaci贸n y uso de modelos locales

1-Instalaci贸n y Primeros Pasos con Ollama

2- C贸mo Usar Ollama con Postman (APIs y Comunicaci贸n)