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:
┌─────────────────┐ ┌─────────────────┐
│ 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:
# ❌ 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 directamenteVentaja con TXT:
# ✅ 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
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 profesionalArchivo 2: servicios.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/horaEstructura de carpetas:
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
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_completoEsquema Visual de la Funci贸n:
┌─────────────────────────────────────┐ │ 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:
Sabe qu茅 libros necesita (lista de archivos)
Toma cada libro de la estanter铆a
Lee todas sus p谩ginas
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:
┌─────────────────────────────────────────────────┐ │ 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:
# 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:
| Pregunta | Archivos Consultados | Respuesta | ¿Correcto? |
|---|---|---|---|
| "Br铆ndame 5 cursos" | cursos.txt | Lista 5 cursos espec铆ficos | ✅ |
| "Cursos de Flutter" | cursos.txt | Menciona curso de Flutter | ✅ |
| "Precios de servicios" | servicios.txt | Muestra precios por hora | ✅ |
| "Cursos de PayPal" | cursos.txt | Menciona integraci贸n PayPal | ✅ |
| "¿Tienen mentor铆a?" | servicios.txt | Describe servicio de mentor铆a | ✅ |
Ejemplo de Conversaci贸n Completa:
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:
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:
# 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, mensualidadesBeneficios para Tu Negocio:
Respuestas consistentes: Todos reciben la misma informaci贸n
Disponible 24/7: Atiende incluso fuera de horario
Escalable: Mismo esfuerzo para 10 o 10,000 consultas
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:
Empieza peque帽o: 1-2 archivos bien estructurados
Organiza por temas: Un archivo por categor铆a
Mant茅n actualizado: Revisa y actualiza peri贸dicamente
Prueba con usuarios reales: Pide feedback de las respuestas
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):
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
Publicar un comentario