Creación de un agente de IA para escribir publicaciones de blog con Crewai

Me encanta escribir. Puede notar que si me sigues a mí o a mi blog. Por esa razón, constantemente estoy produciendo nuevo contenido y hablo de ciencia de datos e inteligencia artificial.

Descubrí esta pasión hace un par de años cuando recién comenzaba mi camino en ciencia de datos, aprendiendo y evolucionando mis habilidades. En ese momento, escuché a algunos profesionales más experimentados en el área diciendo que una buena técnica de estudio era practicar nuevas habilidades y escribir sobre ello en algún lugar, enseñando lo que aprendió.

Además, me acababa de mudarme a los Estados Unidos, y nadie me conocía aquí. Así que tuve que comenzar en algún lugar, creando mi imagen profesional en este mercado competitivo. Recuerdo que hablé con mi primo, que también está en la industria de la tecnología, y él me dijo: Escribe publicaciones de blog sobre tus experiencias. Dile a la gente lo que estás haciendo. Y así lo hice.

Y nunca me detuve.

Avance rápido hasta 2025, ahora tengo casi doscientos artículos publicados, muchos de ellos con la ciencia de datos, un libro publicado y una buena audiencia.

La escritura me ayudó mucho en el área de ciencia de datos.

Más recientemente, uno de mis intereses ha sido el increíble procesamiento del lenguaje natural y las materias de los modelos de idiomas grandes. Aprender sobre cómo funcionan estos modelos modernos es fascinante.

Ese interés me llevó a experimentar con AI agente también. Entonces, aprendí sobre Crewaiun paquete fácil y de código abierto que nos ayuda a construir agentes de IA de una manera divertida y fácil, con poco código. Decidí probarlo creando un equipo de agentes para escribir una publicación de blog y luego ver cómo va.

En esta publicación, aprenderemos cómo crear esos agentes y hacer que trabajen juntos para producir una publicación de blog simple.

Hagamos eso.

¿Qué es un equipo?

A multitud De los agentes de IA es una combinación de dos o más agentes, cada uno de ellos realizando una tarea hacia un objetivo final.

En este estudio de caso, crearemos un equipo que trabajará juntos para producir una pequeña publicación de blog sobre un tema determinado que proporcionaremos.

Tripulación del flujo de trabajo de los agentes. Imagen del autor

El flujo funciona así:

  1. Elegimos un tema determinado para que los agentes escriban.
  2. Una vez que se inicie la tripulación, irá a la base de conocimiento, leerá algunos de mis artículos escritos anteriormente e intentará imitar mi estilo de escritura. Luego, genera un conjunto de pautas y la pasa al siguiente agente.
  3. A continuación, el agente del planificador se hace cargo y busca en Internet buscando un buen contenido sobre el tema. Crea un plan de contenido y lo envía al siguiente agente.
  4. El agente del escritor recibe el plan de escritura y lo ejecuta de acuerdo con el contexto y la información recibida.
  5. Finalmente, el contenido se pasa al último agente, el editor, que revisa el contenido y devuelve el documento final como salida.

En la siguiente sección, veremos cómo se puede crear esto.

Código

Crewai es un gran paquete de Python porque simplifica el código para nosotros. Entonces, comencemos instalando los dos paquetes necesarios.

pip install crewai crewai-tools

A continuación, si lo desea, puede seguir las instrucciones de su Inicio rápido página y tener una estructura de proyecto completa creada para usted con solo un par de comandos en una terminal. Básicamente, instalará algunas dependencias, generará la estructura de carpetas sugerida para los proyectos de Crewai, así como generará algunos archivos .yaml y .py.

Personalmente prefiero crearlos yo mismo, pero depende de ti. La página se enumera en la sección REFERENCIAS.

Estructura de carpetas

Entonces, aquí vamos.

Crearemos estas carpetas:

Y estos archivos:

  • En el configuración Carpeta: crea los archivos agents.yaml y tasks.yaml
  • En el conocimiento Carpeta, ahí es donde agregaré los archivos con mi estilo de escritura.
  • En el proyecto raíz: crear crew.py y main.py.
Estructura de carpetas. Imagen del autor.

Asegúrese de crear las carpetas con los nombres mencionados, ya que Crewai busca agentes y tareas dentro del configuración carpeta y para la base de conocimiento dentro de un conocimiento carpeta.

A continuación, establezcamos a nuestros agentes.

Agentes

Los agentes están compuestos de:

  • Nombre del agente: writer_style
  • Role: Los LLM son buenos jugadores de rol, así que aquí puedes decirles qué papel jugar.
  • Meta: Dígale al modelo cuál es el objetivo de ese agente.
  • Historia de fondo: Describa la historia detrás de este agente, quién es, qué hace.
writer_style:
  role: >
    Writing Style Analyst
  goal: >
    Thoroughly read the knowledge base and learn the characteristics of the crew, 
    such as tone, style, vocabulary, mood, and grammar.
  backstory: >
    You are an experienced ghost writer who can mimic any writing style.
    You know how to identify the tone and style of the original writer and mimic 
    their writing style.
    Your work is the basis for the Content Writer to write an article on this topic.

No te aburriré con todos los agentes creados para este equipo. Creo que tienes la idea. Es un conjunto de indicaciones que explican a cada agente lo que van a hacer. Todas las instrucciones de los agentes se almacenan en el archivo agente.yaml.

Piense en ello como si fuera un gerente que contrataba personas para crear un equipo. Piense en qué tipo de profesionales necesitaría y qué habilidades se necesitan.

Necesitamos 4 profesionales que trabajen para el objetivo final de producir contenido escrito: (1) A Estilista de escritor(2) A Planificador(3) A Escritor, y (4) un Editor.

Si desea ver la configuración para ellos, simplemente verifique el código completo en el repositorio de GitHub.

Tareas

Ahora, volviendo a la analogía del gerente contratando personas, una vez que “contratamos” a toda nuestra tripulación, es hora de separar las tareas. Sabemos que queremos producir una publicación de blog, tenemos 4 agentes, pero lo que cada uno de ellos hará.

Bueno, eso se configurará en el archivo tasks.yaml.

Para ilustrar, déjame mostrarte el código para el agente del escritor. Una vez más, estas son las partes necesarias para el aviso:

  • Nombre de la tarea: write
  • Descripción: La descripción es como decirle al profesional cómo desea que se realice esa tarea, al igual que le diríamos a una nueva contratación cómo realizar su nuevo trabajo. Dé instrucciones precisas para obtener el mejor resultado posible.
  • Salida esperada: Así es como queremos ver la salida. Tenga en cuenta que doy instrucciones como el tamaño de la publicación del blog, la cantidad de párrafos y otra información que ayuda a mi agente a darme el resultado esperado.
  • Agente para realizarlo: Aquí, estamos indicando al agente que realizará esta tarea, utilizando el mismo nombre establecido en el agents.yaml archivo.
  • Archivo de salida: Ahora siempre aplicable, pero si es así, este es el argumento a usar. Pedimos un archivo de Markdown como salida.
write:
  description: >
    1. Use the content plan to craft a compelling blog post on {topic}.
    2. Incorporate SEO keywords naturally.
    3. Sections/Subtitles are properly named in an engaging manner. Make sure 
    to add Introduction, Problem Statement, Code, Before You Go, References.
    4. Add a summarizing conclusion - This is the "Before You Go" section.
    5. Proofread for grammatical errors and alignment with the writer's style.
    6. Use analogies to make the article more engaging and complex concepts easier
    to understand.
  expected_output: >
    A well-written blog post in markdown format, ready for publication.
    The article must be within a 7 to 12 minutes read.
    Each section must have at least 3 paragraphs.
    When writing code, you will write a snippet of code and explain what it does. 
    Be careful to not add a huge snippet at a time. Break it in reasonable chunks.
    In the examples, create a sample dataset for the code.
    In the Before You Go section, you will write a conclusion that is engaging
    and factually accurate.
  agent: content_writer
  output_file: blog_post.md

Después de definir los agentes y las tareas, es hora de crear nuestro flujo de tripulación.

Codificando la tripulación

Ahora crearemos el archivo crew.pydonde traduciremos el flujo presentado anteriormente al Pitón código.

Comenzamos importando los módulos necesarios.

#Imports
import os
from crewai import Agent, Task, Process, Crew, LLM
from crewai.project import CrewBase, agent, crew, task
from crewai.knowledge.source.pdf_knowledge_source import PDFKnowledgeSource
from crewai_tools import SerperDevTool

Usaremos el básico Agent, Task, Crew, Process y LLM para crear nuestro flujo. PDFKnowledgeSource Ayudará al primer agente a aprender mi estilo de escritura, y Serperdevtool es la herramienta para buscar en Internet. Para ese, asegúrese de obtener su clave API en https://serper.dev/signup.

Una mejor práctica en el desarrollo de software es mantener sus claves y configuraciones de configuración API separados de su código. Usaremos un .env Archivo para esto, proporcionando un lugar seguro para almacenar estos valores. Aquí está el comando de cargarlos en nuestro entorno.

from dotenv import load_dotenv
load_dotenv()

Entonces, usaremos el PDFKnowledgeSource Para mostrar a la tripulación dónde buscar el estilo del escritor. Por defecto, esa herramienta analiza la carpeta de conocimiento de su proyecto, por lo que la importancia de que el nombre sea la misma.

# Knowledge sources

pdfs = PDFKnowledgeSource(
    file_paths=['article1.pdf',
                'article2.pdf',
                'article3.pdf'
                ]
)

Ahora podemos configurar el LLM que queremos usar para la tripulación. Puede ser cualquiera de ellos. Probé un montón de ellos, y los que más me gustaban eran qwen-qwq-32b y gpt-4o. Si elige OpenAI’s, también necesitará una clave API. Para Qwen-QWQ, solo descomine el código y comente las líneas de OpenAI. Necesita una clave API de Groq.

# LLMs

llm = LLM(
    # model="groq/qwen-qwq-32b",
    # api_key= os.environ.get("GROQ_API_KEY"),
    model= "gpt-4o",
    api_key= os.environ.get("OPENAI_API_KEY"),
    temperature=0.4
)

Ahora tenemos que crear un Base de la tripulaciónmostrando dónde Crewai puede encontrar los archivos de configuración de agentes y tareas.

# Creating the crew: base shows where the agents and tasks are defined

@CrewBase
class BlogWriter():
    """Crew to write a blog post"""
    agents_config = "config/agents.yaml"
    tasks_config = "config/tasks.yaml"

Funciones de los agentes

Y estamos listos para crear el código para cada agente. Están compuestos por un decorador @agent Para mostrar que la siguiente función es un agente. Luego usamos el agente de clase e indicamos el nombre del agente en el archivo de configuración, el nivel de verbosidad, es 1 bajo, 2 alto. También puede usar un valor booleano, como verdadero o falso.

Por último, especificamos si el agente usa alguna herramienta y qué modelo usará.

# Configuring the agents
    @agent
    def writer_style(self) -> Agent:
        return Agent(
                config=self.agents_config['writer_style'],
                verbose=1,
                knowledge_sources=[pdfs]
                )

    @agent
    def planner(self) -> Agent:
        return Agent(
        config=self.agents_config['planner'],
        verbose=True,
        tools=[SerperDevTool()],
        llm=llm
        )

    @agent
    def content_writer(self) -> Agent:
        return Agent(
        config=self.agents_config['content_writer'],
        verbose=1
        )

    @agent
    def editor(self) -> Agent:
        return Agent(
        config=self.agents_config['editor'],
        verbose=1
        )

Funciones de tareas

El siguiente paso es crear las tareas. De manera similar a los agentes, crearemos una función y la decoraremos con @task. Utilizamos la tarea de clase para heredar las funcionalidades de Crewai y luego señalamos la tarea que se utilizará desde nuestro tasks.yaml Archivo que se utilizará para cada tarea creada. Si se espera algún archivo de salida, use el output_file argumento.

# Configuring the tasks    

    @task
    def style(self) -> Task:
        return Task(
        config=self.tasks_config['mystyle'],
        )

    @task
    def plan(self) -> Task:
        return Task(
        config=self.tasks_config['plan'],
        )

    @task
    def write(self) -> Task:
        return Task(
        config=self.tasks_config['write'],
        output_file='output/blog_post.md' # This is the file that will be contain the final blog post.
        )

    @task
    def edit(self) -> Task:
        return Task(
        config=self.tasks_config['edit']
        )

Multitud

Para pegar todo juntos, ahora creamos una función y lo decoramos con el @crew decorador. Esa función alineará a los agentes y las tareas en el orden que se realizará, ya que el proceso elegido aquí es el más simple: Sequential. En otras palabras, todo se ejecuta en secuencia, de principio a fin.

@crew

    def crew(self) -> Crew:
        """Creates the Blog Post crew"""

        return Crew(
            agents= [self.writer_style(), self.planner(), self.content_writer(), self.editor(), self.illustrator()],
            tasks= [self.style(), self.plan(), self.write(), self.edit(), self.illustrate()],
            process=Process.sequential,
            verbose=True
        )

Corriendo la tripulación

Ejecutar la tripulación es muy simple. Creamos el main.py archivar e importar la base de la tripulación BlogWriter creado. Entonces solo usamos las funciones crew().kickoff(inputs) Para ejecutarlo, pasando un diccionario con las entradas que se utilizarán para generar la publicación del blog.

# Script to run the blog writer project

# Warning control
import warnings
warnings.filterwarnings('ignore')
from crew import BlogWriter


def write_blog_post(topic: str):
    # Instantiate the crew
    my_writer = BlogWriter()
    # Run
    result = (my_writer
              .crew()
              .kickoff(inputs = {
                  'topic': topic
                  })
    )

    return result

if __name__ == "__main__":

    write_blog_post("Price Optimization with Python")

Ahí está. El resultado es una buena publicación de blog creada por el LLM. Vea abajo.

Publicación de blog resultante. Gif por el autor.

¡Eso es tan agradable!

Antes de que te vayas

Antes de ir, sepa que esta publicación de blog fue 100% creada por mí. Este equipo que creé fue un experimento que quería hacer para aprender más sobre cómo crear agentes de IA y hacer que trabajen juntos. Y, como dije, me encanta escribir, así que esto es algo que podría leer y evaluar la calidad.

Mi opinión es que este equipo todavía no hizo un muy buen trabajo. Pudieron completar las tareas con éxito, pero me dieron una publicación y código muy superficiales. No publicaría esto, pero al menos podría ser un comienzo, tal vez.

Desde aquí, te animo a que aprendas más sobre Crewai. Tomé su curso gratuito donde João de Moura, el creador del paquete, nos muestra cómo crear diferentes tipos de equipos. Es realmente interesante.

Repositorio de Github

https://github.com/gurezende/crew_writer

Acerca de mí

Si quieres aprender más sobre mi trabajo o seguir mi blog (¡realmente soy yo!), Aquí están mis contactos y cartera.

https://gustavorsantos.me

Referencias

[Quickstart CrewAI](https://docs.crewai.com/quickstart)

[CrewAI Documentation](https://docs.crewai.com/introduction)

[GROQ](https://groq.com/)

[OpenAI](https://openai.com)

[CrewAI Free Course](https://learn.crewai.com/)