En primer lugar hay que tener el modelo correspondiente instalado y ejecutándose.
Lo modelos disponibles para funcionar con langchain están en https://python.langchain.com/docs/integrations/chat/
En mi caso trabajo habitualmente con Ollama en local, usando el modelo Llama 3.2 de 3 mil millones de parámetros, uno de los modelos pequeños que no son multimodales. Por ello, haré los ejemplos usando éste.
# Cargamos las librerías de langchain del modelo from langchain_ollama import ChatOllama from langchain_core.prompts import ChatPromptTemplate # Instanciamos el chat del modelo definiendo sus opciones chat = ChatOllama( model = "llama3.2", temperature = 0.1 )
Las plantillas definen prompts por defecto que tienen algunas “variables” { entre llaves }, a las que se les puede asignar diferentes valores. De este modo, puede usarse para tareas recurrentes.
prompt = """Quiero que sugieras una receta \ de cocina para {hora_comida} que tenga al menos \ los siguientes ingredientes: {ingredientes}""" # Definimos la plantilla de prompt plantilla_prompt = ChatPromptTemplate.from_template(prompt) # Como el programa va de obtener recetas, vamos a incluir en las variables un código numérico # que indique la fecha para la que estamos calculando la receta hora_comida_111024 = "comer" # Otras posibilidades: cenar, almorzar, merendar, desayunar ingredientes_111024 = "arroz, curry, pollo" # Creamos el mensaje a pasar al modelo, indicando en la plantilla las variables correspondientes mensaje = plantilla_prompt.format_messages( hora_comida = hora_comida_111024, ingredientes = ingredientes_111024) # Obtenemos y visualizamos la receta respuesta = chat.invoke(mensaje) receta_111024 = respuesta.content print(receta_111024)
Se entiende por parser la capacidad de devolver respuestas estructuradas, con las que python pueda trabajar en programación tradicional, por ejemplo en formato JSON o como listas o diccionarios.
Langchain tiene sus propios parsers que pueden consultarse en su documentación, por ejemplo para extraer información del formato JSON:
from langchain_core.prompts import ChatPromptTemplate # En primer lugar podríamos hacer que el modelo nos diese directamente una cadena de # texto //string// en formato JSON y convertirla a través de un parser predefinido para # este tipo de archivos, en una variable de tipo diccionario import json plantilla_instrucciones = """\ De la siguiente receta extrae la siguiente información y no indiques nada más: nombre: extrae el título de la receta. ingredientes: extrae los ingredientes de la receta como una lista de python. pasos: extrae el número de pasos necesarios para cocinar la receta. comensales: extrae el número de comensales para los que está preparada la receta, si no se especifica, indicar -1. Formatea la salida como JSON con las siguientes keys, sólo el contenido del JSON: nombre ingredientes pasos comensales receta = {receta} """ # Suponemos que tenemos la variable receta_111024 del apartado anterior, copiarla para la realización del ejemplo. # Trabajamos como vimos en el apartado anterior plantilla_prompt = ChatPromptTemplate.from_template(plantilla_instrucciones) mensaje = plantilla_prompt.format_messages(receta=receta_111024) chat = ChatOllama ( model = "llama3.2", temperature = 0.0 ) respuesta = chat.invoke(mensaje) datos_json = respuesta.content try: dato_dict = json.loads(datos_json) print(dato_dict) print(type(dato_dict)) print(dato_dict["ingredientes"]) print(type(dato_dict["ingredientes"])) except json.JSONDecodeError: print("ERROR: No es un formato JSON válido") except Exception as e: print(f"Error inesperado: {e}")
Puede que en ocasiones necesitemos crear nuestros parsers personalizados, que se harían usando la biblioteca de langchain output_parsers
from langchain_core.prompts import ChatPromptTemplate from langchain.output_parsers import ResponseSchema from langchain.output_parsers import StructuredOutputParser # De nuevo, suponemos que tenemos la variable receta_111024 del apartado anterior, copiarla para la realización del ejemplo. # Definimos la estructura que tendrá el JSON, a patir de la información contenida en el texto de la receta esquema_nombre = ResponseSchema(name = "nombre", description = "Nombre de la receta.") esquema_ingredientes = ResponseSchema(name = "ingredientes", description = "Ingredientes necesarios para cocinar la receta.") esquema_pasos = ResponseSchema(name = "pasos", description = "Número de pasos necearios para cocinar la receta.") esquema_comensales = ResponseSchema(name = "comensales", description = "Número de comensales para los que está preparada la receta.\ Si no se especifican, el valor es -1.") esquema_respuesta = [esquema_nombre, esquema_ingredientes, esquema_pasos, esquema_comensales] # Una vez tenemos el esquema del JSON definido, creamos el parser de salida parser_de_salida = StructuredOutputParser.from_response_schemas(esquema_respuesta) instrucciones_de_formato = parser_de_salida.get_format_instructions() # Definimos las instrucciones para extraer la información, a partir del esquema que hemos hecho plantilla_instrucciones = """\ De la siguiente receta extrae la siguiente información: nombre: extrae el título de la receta. ingredientes: extrae los ingredientes de la receta como una lista de python. pasos: extrae el número de pasos necesarios para cocinar la receta. comensales: extrae el número de comensales para los que está preparada la receta, si no se especifica, indicar -1. receta = {receta} {instrucciones_de_formato} """ # Creamos como hemos hecho antes, la plantilla del prompt y el mensaje a enviar al modelo prompt = ChatPromptTemplate.from_template(template=plantilla_instrucciones) mensaje = prompt.format_messages(receta=receta_111024, instrucciones_de_formato = instrucciones_de_formato) respuesta = chat.invoke(mensaje) # Por último pasamos a una variable el parseo de la respuesta obtenida, ya que gracias # al esquema que hicimos en un principio, puede interpretar de la forma adecuada, que en # este caso será un diccionario Python, en el que además el elemento "ingredientes" es una lista diccionario_de_salida = parser_de_salida.parse(respuesta.content) print(diccionario_de_salida) print (type(diccionario_de_salida)) print(diccionario_de_salida.get("ingredientes")) print(type(diccionario_de_salida.get("ingredientes")))