Creación de un agente de razonamiento ReWOO mediante IBM Granite

Autor

Jobit Varughese

Technical Content Writer

IBM

Los modelos de lenguaje grandes (LLM) y sus variantes mejoradas, los modelos de lenguaje aumentados (ALM), se han convertido en la columna vertebral de los sistemas modernos de IA. Al combinar una potente generación de lenguaje con técnicas externas de recuperación de conocimiento, como la generación aumentada por recuperación (RAG), permiten el razonamiento avanzado, la respuesta a preguntas y la automatización de tareas en diversos dominios. Sin embargo, a pesar de sus notables capacidades, estos modelos a menudo enfrentan desafíos, como una robustez inconsistente en todos los sistemas, un alto uso de tokens, tiempos de respuesta lentos e ineficiencias causadas por instrucciones repetitivas y contexto redundante, al abordar tareas complejas. Tales limitaciones aumentan los costos operativos y dificultan la escalabilidad y el rendimiento en tiempo real.

Para superar estos problemas, la infraestructura ReWOO (razonamiento sin observación) ofrece un enfoque novedoso que se centra en desacoplar el razonamiento de la recuperación de conocimiento externo. En lugar de tener un único LLM que intente razonar, actuar y observar de manera intercalada, ReWOO separa estas preocupaciones en módulos distintos, cada uno potencialmente impulsado por un LLM pero con una función específica. Al modularizar el proceso en distintas etapas de planificación, recopilación de pruebas y síntesis, ReWOO mejora la eficiencia y precisión de los token. También facilita la depuración del sistema y permite flujos de trabajo de IA más ágiles y eficaces.

La metodología detrás de ReWOO

El flujo de trabajo de ReWOO gira en torno a tres componentes clave: razonamiento paso a paso, llamadas a herramientas y resumen. Estos componentes se implementan en una estructura modular que consta de tres partes: el planificador, el trabajador y el solucionador.

Planificador

El planificador desglosa la tarea principal en una secuencia de subpreguntas enfocadas, creando un proyecto técnico. En lugar de pedirle al LLM que responda una pregunta compleja de una vez que puede llevar a un uso abrumador de tokens y respuestas confusas, el planificador crea un proyecto técnico o una hoja de ruta. Este desglose por pasos guía el flujo de trabajo y mantiene estructurado el proceso de razonamiento.

Trabajador

El trabajador llama a herramientas externas, como motores de búsqueda o bases de datos, para recuperar información relevante y pruebas necesarias para responder a las subpreguntas. Utiliza el LLM para formular respuestas claras y concisas basadas únicamente en esta información recuperada. Esta fase de observación externa se mantiene separada del proceso de razonamiento para evitar la repetición innecesaria de las instrucciones y reducir el consumo de tokens.

Solucionador

El solucionador sintetiza todos los insights recopilados para generar una respuesta final fresca y bien estructurada. Esta separación modular ayuda a garantizar un razonamiento eficiente, preciso y escalable con modelos de lenguaje de gran tamaño.

Los marcos como LangChain y LangGraph proporcionan herramientas potentes para implementar la arquitectura ReWOO mediante el uso de modelos de OpenAI, IBM Granite o herramientas especializadas como Serper y Tavily para la búsqueda.

En este tutorial, explorará cómo crear un agente ReWOO que realice la tarea de resumen de contenido. Este agente puede:

  • Desglosar una tarea de alto nivel en subpreguntas
  • Utilizar la búsqueda web para recopilar contexto relevante para cada subpregunta
  • Generar respuestas utilizando IBM Granite
  • Resumir los resultados en una respuesta final

Esta arquitectura es útil para:

  • Tareas de resumen
  • Respuesta a preguntas sobre conocimiento externo
  • Razonamiento dinámico y aumentado por herramientas

Tecnologías empleadas

Este tutorial paso a paso aprovecha las tecnologías de IA de vanguardia, que incluyen:

  1. IBM Granite Instruct: un potente LLM para el seguimiento de instrucciones generales, ideal para asistentes de IA en empresas y otros dominios.
  2. Transformadores: una biblioteca de Python ampliamente utilizada que proporciona herramientas para cargar, tokenizar y ejecutar modelos de lenguaje como IBM Granite. Permite el procesamiento eficaz de entradas de texto y la generación de resultados del modelo.

Pasos

Paso 1: Configurar el entorno

Este tutorial lo guía a través de la configuración de su entorno de desarrollo local para ejecutar una canalización de razonamiento al estilo ReWOO mediante Jupyter Notebook. Utilizará el modelo de lenguaje IBM Granite y Serper.dev para la recuperación de búsquedas web en tiempo real.

Nota: no se requiere GPU, pero la ejecución puede ser más lenta en sistemas basados en CPU. Este paso abre un entorno de notebook donde puede copiar el código de este tutorial. Este tutorial también está disponible en GitHub.

Paso 2: Instalar las dependencias necesarias

Estas bibliotecas son necesarias para ejecutar el pipeline de ReWOO e interactuar con herramientas externas:

Transformadores: cargan y ejecutan el modelo de lenguaje grande IBM Granite.

Torch: un marco de aprendizaje profundo necesario para ejecutar el modelo de manera eficiente.

Aceleradores: optimizan el rendimiento del modelo en todo el hardware (opcional).

Solicitudes: envían solicitudes HTTP POST a API externas (como Serper).

!pip install transformers accelerate torch requests

Paso 3: Importar las bibliotecas necesarias

En este paso, importe las bibliotecas de Python necesarias para crear los componentes principales del pipeline de ReWOO.

transformers.AutoTokenizer: cargan el tokenizador que convierte el texto en tokens compatibles con el modelo de lenguaje.

transformers.AutoModelForCausalLM: cargan el modelo de lenguaje previamente entrenado IBM Granite para generar respuestas.

transformers.pipeline: proporciona una interfaz de alto nivel para crear rápidamente una canalización de generación de texto mediante el tokenizador y el modelo.

import requests
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline

Paso 4: Cargar el modelo de IBM Granite y crear un pipeline de generación de texto

En este paso, cargamos el modelo de lenguaje IBM Granite e inicializamos una canalización de generación de texto mediante la biblioteca de transformadores de Hugging Face. Explore el modelo Granite 3.2 2B Instruct en Hugging Face aquí.

model_id = "ibm-granite/granite-3.2-2b-instruct": especifica el nombre del punto de control del modelo IBM Granite alojado en Hugging Face. Este modelo está optimizado para tareas de seguimiento de instrucciones.

AutoTokenizer.from_pretrained(model_id): carga el tokenizador asociado al modelo especificado. Es responsable de convertir la entrada en tokens y decodificar los resultados nuevamente en texto.

AutoModelForCausalLM.from_pretrained(model_id): carga el modelo de lenguaje (instrucciones Granite 3.2 2B) para tareas de generación de texto, como responder preguntas o resumir.

pipeline("text-generation", model=model, tokenizer=tokenizer): crea un pipeline de generación de texto de alto nivel que combina el modelo y el tokenizador, lo que facilita la generación de respuestas a partir de instrucciones.

model_id = "ibm-granite/granite-3.2-2b-instruct"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id)
generator = pipeline("text-generation", model=model, tokenizer=tokenizer)

Paso 5: Configurar la API de Serper para la recuperación de búsquedas web

En este paso, definimos una función que actúa como el trabajador en la arquitectura ReWoo. Este trabajador utiliza una herramienta de búsqueda web, Serper.dev, para recuperar información relevante y actualizada de Internet para apoyar el razonamiento y la generación de respuestas. Serper.dev es una API rápida y ligera que proporciona resultados de búsqueda de Google en un formato estructurado, lo que la hace ideal para la recuperación de información en tiempo real en flujos de trabajo de IA.

Esta configuración permite que el sistema ReWOO "observe" el mundo real consultando fuentes de conocimiento externas antes de que el LLM tome las decisiones finales.

Para usar Serper en el pipeline de ReWOO:

  1. Visite https://serper.dev y cree una cuenta gratuita.
  2. Después de registrarse, navegue hasta el panel y copie la clave API.
  3. En el código, almacene la clave API de forma segura. Por ahora, asígnelo directamente como se muestra después de esto:

SERPER_API_KEY = "<YOUR_API_KEY>" # Reemplace esto con su clave real

Nota: nunca cargue su clave API en repositorios públicos. Para configuraciones de producción o equipo, use archivos .env o variables de entorno para mantenerla seguro.

def query_serper(question, num_results=3): define una función que toma una pregunta de búsqueda y devuelve fragmentos relevantes de los principales resultados de búsqueda.

payload =:{"q": question, "num": num_results} prepara la carga útil de la consulta con el término de búsqueda y el número de resultados a devolver.

response = tequests.post(...): envía una solicitud POST a la API de Serper con su consulta y encabezados.

response.raise_for_status(): genera un error si la respuesta de la API no es válida o falla.

snippets = [...]: extrae fragmentos de texto de los resultados de búsqueda orgánicos.

return "\n".join(snippets): une y devuelve los fragmentos como una sola cadena, que sirve como contexto para el modelo de lenguaje.

Nota: esta función forma la columna vertebral del paso de "observación" de ReWOO, donde se recopila evidencia externa para un mayor razonamiento. Asegúrese de que su clave de API sea válida y no tenga limitaciones de velocidad al realizar las pruebas.

SERPER_API_KEY = "your_serper_api_key_here" # Replace with your actual key
def query_serper(question, num_results=3):
    url = "https://google.serper.dev/search"
    headers = {
            "X-API-KEY": SERPER_API_KEY,
            "Content-Type": "application/json"
}
    payload = {"q": question, "num": num_results}
    response = requests.post(url, headers=headers, json=payload)
    response.raise_for_status()
    data = response.json()
    snippets = [item.get("snippet", "") for item in data.get("organic", [])]
    return "\n".join(snippets)

Paso 6: Generar respuestas informadas mediante el uso de la función del experto

En este paso, definimos la función experto() , que sirve como solucionador en la arquitectura ReWOO. El solucionador sintetiza la evidencia externa recuperada y genera una respuesta final utilizando el modelo de lenguaje.

def expert(question: str) -> str: La función expert() toma una pregunta (cadena) y devuelve una respuesta (cadena) generada por el modelo Granite. Funciona buscando en la web con Serper.dev, recopilando información relevante y utilizándola para generar una respuesta clara y completa.

context = query_serper(question): utiliza la herramienta de búsqueda web Serper para recuperar información relevante (trabajador).

instrucción = f"""...""": crea una instrucción que indica al modelo que responda utilizando solo el contexto recuperado.

generator(...): llama al modelo Granite para generar una respuesta basada en la instrucción de entrada.

for _ in range(5): este bucle permite que el modelo genere una respuesta en fragmentos, hasta 5 veces. Ayuda si la respuesta es larga y no se puede completar de una sola vez.

generated_text += new_text: agrega cada nuevo fragmento de texto para formar la respuesta completa.

if new_text.endswith(...): si la respuesta parece completa (termina con un punto, un signo de interrogación o un signo de exclamación) y tiene suficientes palabras (más de 50), detiene el ciclo.

return generated_text.strip(): entrega la respuesta final y limpia.

Nota: el formato de las instrucciones es importante, ya que garantiza que el modelo no "alucine" ni se salga del tema. Debe ceñirse a lo que hay en el contexto. Limitamos cada fragmento de generación a 120 tokens para controlar la longitud de los resultados y gestionar el uso de recursos de manera eficiente, al tiempo que evitamos el uso excesivo de tokens.

def expert(question: str) -> str:
    context = query_serper(question) # your retrieval function
    prompt = f"""You are a knowledgeable expert. Based ONLY on the context below, answer the question clearly and concisely in your own words.
Do NOT mention any sources or references.
Context:
{context}
Question: {question}
Answer:"""
    input_prompt = prompt
    generated_text = ""
    last_generated = ""
    for _ in range(5): # up to 5 chunks
        outputs = generator(
            input_prompt,
            max_new_tokens=120,
            do_sample=False,
            eos_token_id=tokenizer.eos_token_id,
            # no invalid flags like 'temperature' here
        )
        text = outputs[0]["generated_text"]
        new_text = text[len(input_prompt):].strip()
        # Stop if no new content
        if new_text == last_generated:
            break
        generated_text += new_text + " "
        input_prompt = prompt + generated_text
        last_generated = new_text
        if new_text.endswith(('.', '!', '?')) and len(generated_text.split()) > 50:
            break
    return generated_text.strip()

Paso 7: Definir el módulo del planificador

En este paso, definimos la función de planificar, que desglosa una tarea de entrada amplia en subpreguntas más pequeñas y bien definidas, un principio básico del razonamiento paso a paso de ReWOO.

def planner(task: str): define una función llamada planificador que acepta una tarea de argumento único (una cadena que describe la tarea a realizar).

topic = task.replace("Summarize", "").replace("the novella", "").strip(): Extrae el asunto principal (por ejemplo, el título o el tema) de la tarea. Limpia la entrada eliminando frases comunes como "Resumir" y "la novela", luego recorta los espacios en blanco iniciales y finales para aislar el tema central.

return [ ... ]: devuelve una lista de preguntas específicas que guían el módulo Worker.

Nota: puede ampliar esta lista con subpreguntas más específicas según la profundidad y la naturaleza del tema de entrada.

def planner(task: str):
topic = task.replace("Summarize", "").replace("the novella", "").strip()
return [
f"What is the main plot related to {topic}?",
f"Who are the key characters in {topic}?",
f"What themes are explored in {topic}?"
]

Paso 8: Definir el resumen final (módulo del solucionador)

En este paso, definimos la función final_summarizer, que actúa como solucionador en el pipeline de ReWOO. Esta función toma las subrespuestas (evidencia) proporcionadas por el trabajador y genera un resumen coherente y recién escrito utilizando el modelo de lenguaje.

def final_summarizer(task: str, sub_answers: dict) -> str: define la función que recibe la tarea original y las subrespuestas, y entrega un resumen conciso.

insights = "\n".join(sub_answers.values()): combina todas las respuestas en una sola cadena separadas por líneas nuevas para incluirlas en la instrucción.

base_prompt = f"""...""": construye la instrucción base que indica al modelo que resuma los insights proporcionados. Guía al modelo para generar un nuevo resumen basado solo en las subrespuestas.

max_total_tokens = 400: establece un límite superior para el recuento de tokens generados para evitar resultados excesivamente largos.

max_loops = 5: permite hasta 5 iteraciones de generación para construir progresivamente el resumen.

for in range(maxloops): bucles para generar fragmentos de texto mediante el modelo de lenguaje.

response = generator(..., max_new_tokens=100, ...): utiliza el generador (objeto de canalización) para generar hasta 100 nuevos tokens en cada bucle. El modo de muestreo (do_sample=True) permite la variación y la creatividad en la respuesta.

if summary.endswith(...) or total_tokens_used >= max_total_tokens: finaliza el ciclo si el resumen concluye con la puntuación adecuada o alcanza el límite del token.

return summary.strip(): entrega el resumen final, pulido y sin espacios finales.

def final_summarizer(task: str, sub_answers: dict) -> str:
    insights = "\n".join(sub_answers.values())
    base_prompt = f"""You are an expert summarizer. Based on the following insights, write a fresh, concise summary of the text. The summary must be newly written and must end in a complete sentence with proper punctuation.
Insights:
{insights}
Summary:"""
    summary = ""
    current_prompt = base_prompt
    max_total_tokens = 400
    total_tokens_used = 0
    max_loops = 5
    for _ in range(max_loops):
        response = generator(current_prompt, max_new_tokens=100, do_sample=True, top_p=0.9, eos_token_id=tokenizer.eos_token_id)
        chunk = response[0]["generated_text"][len(current_prompt):].strip()
        summary += " " + chunk
        summary = summary.strip()
        total_tokens_used += len(chunk.split())
        if summary.endswith(('.', '!', '?')) or total_tokens_used >= max_total_tokens:
            break
        # Prepare prompt for next loop
        current_prompt = base_prompt + summary
    return summary.strip()

Paso 9: Orquestar el agente ReWOO con la función de solucionador

En este paso, definimos la función solucionador, que representa la etapa final en el pipeline de ReWOO. Orquesta todo el proceso utilizando el planificador, llamando al experto (trabajador) y generando un resumen utilizando el final_summarizer (solucionador). La arquitectura ReWOO permite el razonamiento de varios pasos al dividir la tarea principal en subpreguntas mediante el uso de un planificador. Cada subpregunta se aborda de forma independiente por un módulo experto, y el resumen final sintetiza todas las respuestas en una respuesta coherente. Este enfoque modular permite que el sistema aborde tareas complejas de manera más eficaz.

def solver(task: str): define la función del controlador principal para ejecutar el flujo de trabajo completo de ReWOO.

subquestions = planner(task): utiliza el planificador para dividir la tarea de entrada en subpreguntas enfocadas.

ans = expert(q): para cada subpregunta, llama a la función del experto para obtener evidencia basada en la web y generar una respuesta relevante. Cada subpregunta generada por el planificador se pasa al experto como una entrada de herramienta. El módulo experto procesa la entrada mediante el uso de un modelo de lenguaje. Esto puede verse como la ejecución de una herramienta para una subtarea específica.

answers[q] = ans: almacena cada respuesta codificada por su pregunta correspondiente para su posterior resumen.

final_summary = final_summarizer(task, answers): introduce todas las respuestas recopiladas en final_summarizer para generar un resumen limpio y coherente.

print(final_summary) and return final_summary: muestra y entrega el resumen completo de la tarea original.

Nota: el tiempo total que tarda la función solver() puede variar entre sistemas debido a las diferencias en la velocidad de la CPU, la RAM disponible y la eficiencia del modelo en diferentes configuraciones de hardware. Dado que el código utiliza una estrategia de generación en bucle con un modelo de lenguaje, los sistemas con menor potencia o memoria pueden tardar mucho más. La recuperación basada en la red y los tamaños de instrucciones grandes también pueden contribuir a los retrasos. Para mejorar el rendimiento, considere reducir max_loops utilizando un modelo más pequeño o cuantificado, optimizando el tokenizador y la canalización del generador o ejecutando el código en un entorno habilitado para GPU, como Google Colab o Kaggle Notebooks.

def solver(task: str):
    print(f"Planner: Breaking down '{task}' into sub-questions...\n")
    subquestions = planner(task)
    answers = {}
    for q in subquestions:
        print(f"🔎 Expert answering: {q}")
        ans = expert(q)
        print(f"➡ Answer: {ans}\n")
        answers[q] = ans
    print("=== Final Summary ===\n")
    final_summary = final_summarizer(task, answers)
    print(final_summary)
    return final_summary

Paso 10: Ejecutar el pipeline de ReWOO para generar el resumen final

En este paso final, ejecutamos la canalización completa de ReWOO llamando a la función del solucionador con una tarea específica.

solver("Summarize the novella The Metamorphosis"): activa todo el proceso ReWOO; planificación, recuperación de pruebas y generación de un resumen para la tarea de entrada: resumir el conjunto de datos La metamorfosis.

Este paso produce los resultados finales y demuestra cómo los componentes funcionan juntos de extremo a extremo para un caso de uso real.

solver("Summarize the novella The Metamorphosis")

Conclusiones clave

  1. El agente ReWOO descompuso con éxito la tarea ("Resumir la novela La metamorfosis") en subpreguntas significativas sobre la trama, los personajes y los temas, lo que permitió la recuperación de información enfocada.
  2. Cada subpregunta se respondió mediante una búsqueda web en tiempo real (Serper.dev) e IBM Granite, produciendo respuestas relevantes y bien estructuradas que capturaban los elementos centrales del texto.
  3. La respuesta final fue coherente, recién escrita y precisa, lo que demuestra cómo la generación aumentada por recuperación puede producir resúmenes de alta calidad y similares a los humanos para tareas de análisis literario.

Nota: para mejorar el rendimiento y la confiabilidad del pipeline de ReWOO, es importante mejorar las métricas de evaluación, como la calidad del resumen, la coherencia y la latencia de generación. Estas métricas ayudan a evaluar qué tan bien funciona el sistema en diferentes tareas y configuraciones de hardware. La arquitectura se puede ampliar integrando algoritmos inteligentes para dividir las grandes preguntas en otras más pequeñas y clasificar las respuestas más útiles. Estas mejoras permitirían un razonamiento más preciso y eficiente, reducirían el tiempo de generación y mejorarían la calidad general de los resultados finales.

Soluciones relacionadas
Agentes de IA para empresas

Cree, implemente y gestione poderosos asistentes y agentes de IA que automaticen flujos de trabajo y procesos con IA generativa.

    Explore watsonx Orchestrate
    Soluciones de agentes de IA de IBM

    Construya el futuro de su empresa con soluciones de IA en las que pueda confiar.

    Explorar las soluciones de agentes de IA
    Servicios de IA de IBM Consulting

    Los servicios de IA de IBM Consulting ayudan a reinventar la forma en que las empresas trabajan con IA para la transformación.

    Explorar los servicios de inteligencia artificial
    Dé el siguiente paso

    Ya sea que elija personalizar aplicaciones y habilidades predefinidas o crear y desplegar servicios agénticos personalizados utilizando un estudio de IA, la plataforma IBM watsonx responde a sus necesidades.

    Explore watsonx Orchestrate Explore watsonx.ai