Cómo crear un chatbot simple con Python

Publicado el: 11/07/2026
Tempo de leitura: 4 minutos
Chatbot simples em Python

Crear un chatbot simple con Python es un proyecto excelente para principiantes porque combina entrada de datos, strings, condiciones, bucles, funciones, diccionarios, archivos y pruebas. El bot de esta guía se ejecuta en el terminal y responde mediante reglas explícitas. No necesita un servicio externo ni un modelo de aprendizaje automático.

Los chatbots basados en reglas funcionan bien cuando las preguntas posibles son limitadas y predecibles, por ejemplo en un menú de ayuda, un asistente de estudio, una herramienta de información o una sección de preguntas frecuentes. También ofrecen una base clara para comprender sistemas conversacionales más avanzados.

Cómo funciona

El programa sigue un ciclo:

  1. Leer un mensaje.
  2. Normalizar el texto.
  3. Identificar una intención o palabra clave.
  4. Seleccionar una respuesta.
  5. Mostrarla.
  6. Continuar hasta recibir una orden de salida.

Esta estructura combina entrada, procesamiento, salida y repetición. La guía de lógica de programación con Python y la introducción a algoritmos explican estos conceptos.

Crear el primer bucle

print("Bot: Hola. Escribe 'salir' para terminar.")

while True:
    mensaje = input("Tú: ")

    if mensaje.casefold() == "salir":
        print("Bot: Hasta luego.")
        break

    print("Bot: Todavía estoy aprendiendo.")

El bucle continúa hasta ejecutar break. La guía de bucles en Python amplía while, break y continue.

Normalizar la entrada

Las personas pueden escribir mayúsculas, espacios adicionales o combinaciones diferentes. Crea una función:

def normalizar(texto: str) -> str:
    return " ".join(
        texto.strip().casefold().split()
    )


print(normalizar("  HOLA   BOT  "))

La función elimina espacios extremos, reduce espacios repetidos y normaliza mayúsculas de forma adecuada para comparaciones.

Añadir reglas exactas

MENSAJES_SALIDA = {"salir", "adiós", "hasta luego"}


def obtener_respuesta(mensaje: str) -> str:
    texto = normalizar(mensaje)

    if texto in {"hola", "buenas", "hey"}:
        return "Hola. ¿En qué puedo ayudarte?"
    if texto == "cómo estás":
        return "Estoy funcionando correctamente."
    if texto in MENSAJES_SALIDA:
        return "Hasta luego."

    return "No entendí ese mensaje."

Un set es adecuado para frases equivalentes. La guía de sets en Python explica pertenencia y valores únicos.

Conectar la función al programa

def main() -> None:
    print("Bot: Hola. Escribe 'salir' para terminar.")

    while True:
        mensaje = input("Tú: ")
        respuesta = obtener_respuesta(mensaje)
        print(f"Bot: {respuesta}")

        if normalizar(mensaje) in MENSAJES_SALIDA:
            break


if __name__ == "__main__":
    main()

El bloque if __name__ == "__main__" permite importar las funciones desde otro archivo sin iniciar la conversación automáticamente.

Buscar palabras clave

def obtener_respuesta(mensaje: str) -> str:
    texto = normalizar(mensaje)

    if texto in {"hola", "buenas", "hey"}:
        return "Hola. ¿En qué puedo ayudarte?"
    if "horario" in texto or "abierto" in texto:
        return "Atendemos de lunes a viernes."
    if "precio" in texto or "coste" in texto:
        return "Indica qué producto deseas consultar."
    if "curso" in texto:
        return "Tenemos cursos para principiantes."
    if texto in MENSAJES_SALIDA:
        return "Hasta luego."

    return "Pregunta por horarios, precios o cursos."

Las búsquedas por fragmentos pueden producir coincidencias accidentales. Para un proyecto mayor, divide el texto en palabras y utiliza reglas más específicas.

Organizar intents con diccionarios

INTENTS = {
    "saludo": {
        "palabras": {"hola", "buenas", "hey"},
        "respuestas": [
            "Hola. ¿En qué puedo ayudarte?",
            "Buenas. ¿Qué deseas consultar?",
        ],
    },
    "horario": {
        "palabras": {"horario", "abierto", "cierre"},
        "respuestas": [
            "Atendemos de lunes a viernes."
        ],
    },
    "precios": {
        "palabras": {"precio", "coste", "tarifa"},
        "respuestas": [
            "Indica el producto que deseas consultar."
        ],
    },
}

Los diccionarios agrupan datos relacionados. Consulta la comparación de estructuras de datos de Python.

Detectar una intención

def detectar_intent(mensaje: str) -> str | None:
    palabras = set(normalizar(mensaje).split())

    for nombre, datos in INTENTS.items():
        if palabras & datos["palabras"]:
            return nombre

    return None

El operador & calcula la intersección. Una intersección no vacía significa que existe al menos una palabra coincidente.

Variar respuestas

import random


def obtener_respuesta(mensaje: str) -> str:
    texto = normalizar(mensaje)

    if texto in MENSAJES_SALIDA:
        return "Hasta luego."

    intent = detectar_intent(mensaje)
    if intent is None:
        return "No entendí. Prueba otra pregunta."

    return random.choice(INTENTS[intent]["respuestas"])

La variación hace la conversación menos repetitiva. La documentación oficial del módulo random explica choice() y otras operaciones. No utilices respuestas aleatorias para información crítica si las alternativas no son equivalentes.

Cargar intents desde JSON

Separar contenido y código facilita el mantenimiento. Crea intents.json:

{
  "saludo": {
    "palabras": ["hola", "buenas", "hey"],
    "respuestas": [
      "Hola. ¿En qué puedo ayudarte?",
      "Buenas. ¿Qué deseas consultar?"
    ]
  },
  "horario": {
    "palabras": ["horario", "abierto", "cierre"],
    "respuestas": [
      "Atendemos de lunes a viernes."
    ]
  }
}

Cárgalo y valida la estructura:

import json
from pathlib import Path


def cargar_intents(ruta: str | Path) -> dict:
    with Path(ruta).open("r", encoding="utf-8") as archivo:
        datos = json.load(archivo)

    if not isinstance(datos, dict):
        raise ValueError("El JSON debe contener un objeto")

    for nombre, intent in datos.items():
        if "palabras" not in intent or "respuestas" not in intent:
            raise ValueError(f"Intent inválido: {nombre}")
        intent["palabras"] = set(intent["palabras"])

    return datos

La documentación oficial del módulo json explica lectura y escritura. Para rutas, consulta pathlib en Python.

Manejar errores de configuración

def main() -> None:
    try:
        intents = cargar_intents("intents.json")
    except FileNotFoundError:
        print("No se encontró la configuración.")
        return
    except (json.JSONDecodeError, ValueError) as error:
        print(f"Configuración inválida: {error}")
        return

    # Iniciar conversación.

Captura errores esperados y muestra instrucciones útiles. La guía de try y except explica este patrón.

Recordar un nombre temporalmente

estado = {"nombre": None}

mensaje = input("Tú: ")
texto = normalizar(mensaje)

if texto.startswith("me llamo "):
    estado["nombre"] = mensaje.strip()[9:].strip().title()
    print(f"Bot: Encantado, {estado['nombre']}.")

Este estado desaparece al cerrar el programa. Para memoria duradera necesitas un archivo o base de datos y reglas sobre privacidad, retención y eliminación.

Probar la lógica

def test_normalizar_espacios():
    assert normalizar("  HOLA   BOT ") == "hola bot"


def test_mensaje_salida():
    assert obtener_respuesta("salir") == "Hasta luego."


def test_detectar_horario():
    assert detectar_intent("¿Cuál es el horario?") == "horario"

La guía de Pytest para principiantes ayuda a organizar estas pruebas. Cuando existen respuestas aleatorias, comprueba que la respuesta pertenece a una lista permitida.

Convertir el motor en otra interfaz

La lógica puede reutilizarse en:

  • una página web;
  • una aplicación de escritorio;
  • una API;
  • un bot de Telegram;
  • un widget de ayuda.

Mantén la entrada y salida separadas de la detección de intents para evitar duplicación.

Limitaciones

Un bot de palabras clave no comprende realmente el lenguaje. Puede fallar con sinónimos, errores de escritura, negación y contexto. Estas limitaciones son aceptables cuando el alcance es pequeño y las respuestas deben ser predecibles.

En un uso público, informa que se trata de un sistema automático y ofrece una alternativa de soporte humano.

Errores frecuentes

  • Crear una cadena enorme de condiciones.
  • No normalizar mayúsculas y espacios.
  • No ofrecer una respuesta de respaldo.
  • Mezclar contenido y código.
  • No definir una salida clara.
  • Guardar datos personales sin necesidad.
  • No probar conflictos entre intents.

Conclusión

Un chatbot simple con Python reúne habilidades fundamentales en un proyecto práctico. Empieza con un bucle y reglas exactas, añade normalización, diccionarios de intents, JSON, estado y pruebas. Mantén el motor de respuestas independiente de la interfaz para reutilizarlo después en una web, un bot de mensajería o una aplicación de escritorio.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Criptografia e segurança de dados em Python
    Proyectos
    Foto de perfil de Leandro Hirt da Academify

    Cómo crear un generador de contraseñas seguro en Python

    Crea un generador de contraseñas seguro en Python con secrets, reglas configurables, CLI, validación, passphrases y pruebas.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Jogo da forca para iniciantes desenvolvido com Python
    Proyectos
    Foto de perfil de Leandro Hirt da Academify

    Cómo crear un juego del ahorcado en Python

    Crea un juego del ahorcado en Python con palabras aleatorias, validación, letras repetidas, vidas, dibujos ASCII, pistas y opción de

    Ler mais

    Tempo de leitura: 3 minutos
    11/07/2026
    Quiz interativo no terminal desenvolvido com Python
    Proyectos
    Foto de perfil de Leandro Hirt da Academify

    Cómo crear un quiz en Python para la terminal

    Crea un quiz en Python para la terminal con preguntas, validación, puntuación, respuestas mezcladas, repetición, JSON y pruebas.

    Ler mais

    Tempo de leitura: 3 minutos
    11/07/2026
    Jogo de adivinhação de números desenvolvido com Python
    Proyectos
    Foto de perfil de Leandro Hirt da Academify

    Juego de adivinar números en Python

    Crea un juego de adivinar números en Python con niveles, pistas, intentos limitados, validación, repetición y funciones fáciles de probar.

    Ler mais

    Tempo de leitura: 3 minutos
    11/07/2026
    Desenhos para iniciantes usando Turtle em Python
    Proyectos
    Foto de perfil de Leandro Hirt da Academify

    Dibujar con Turtle en Python: guía completa

    Aprende a dibujar con Turtle en Python: movimientos, figuras, colores, eventos del teclado y un proyecto interactivo completo.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026