Criação de fluxos de trabalho agênticos com o LangGraph e Granite

Autora

Vrunda Gadesha

AI Advocate | Technical Content Author

Os sistemas modernos de IA estão evoluindo além das interações de prompt-resposta. Os agentes de IA atuais podem realizar raciocínio estruturado multietapas, tomada de decisão e coordenar tarefas complexas de forma autônoma. Esse recurso emergente é conhecido como fluxo de trabalho agêntico, uma mudança poderosa no aprendizado de máquina, em que os agentes operam por meio de uma série de etapas lógicas para resolver problemas com mais eficiência.

Neste tutorial, vamos explorar como criar esses fluxos de trabalho agênticos de IA usando duas ferramentas-chave: LangGraph, um framework para construir caminhos de raciocínio baseados em gráficos e modelos IBM® Granite, um modelo robusto que complementa essa estrutura. Cada etapa do fluxo de trabalho (chamada de "nó") é tratada por um agente, geralmente impulsionado por grandes modelos de linguagem. Esses agentes migram entre estados com base em saídas do modelo ou lógica condicional, formando um gráfico dinâmico e orientado por decisões.

Para dar vida a esses fluxos de trabalho agênticos, vamos analisar mais de perto dois componentes essenciais: o LangGraph e o modelo Granite.

Entendendo o LangGraph

Um framework para fluxos de trabalho escaláveis orientados por IA

O LangGraph é um framework poderoso projetado para agilizar o desenvolvimento de fluxos de trabalho orientados por IA, representando modelos de IA como agentes com estado dentro de um gráfico computacional. Ele permite que os desenvolvedores criem sistemas modulares escaláveis em que cada comportamento ou ponto de decisão é definido como um nó no gráfico.

Com o LangGraph, você pode:

  • Definir o comportamento de cada agente como um nó distinto
  • Use algoritmos ou saídas para determinar as próximas etapas
  • Passar o estado entre os nós para preservar a memória e o contexto
  • Visualizar, depurar e controlar o fluxo de raciocínio com facilidade

Sistemas multiagentes e frameworks como o LangGraph, quando aplicados a tarefas de IA generativa (IA gen), normalmente estruturam a execução de tarefas como fluxos de trabalho sequenciais ou condicionais. Não importa se você está trabalhando com o LangChain, os modelos IBM Granite, os modelos GPT da OpenAI ou outras ferramentas de inteligência artificial, o LangGraph ajuda a otimizar seu fluxo de trabalho para obter melhor escalabilidade e desempenho.

Principais componentes do LangGraph para automatizar fluxos de trabalho complexos

O LangGraph introduz uma abordagem moderna para tecnologias de IA de orquestração por meio de Tecnologia, dividindo fluxos de trabalho complexos em componentes modulares e inteligentes. Ao contrário da automação tradicional ou da automação robótica de processos (RPA), o LangGraph permite a execução dinâmica de tarefas com reconhecimento de contexto usando lógica e memória em tempo real. Aqui estão os quatro componentes principais que alimentam esse framework:

  • Nós: os nós representam unidades individuais de lógica ou ação, como chamar uma ferramenta de IA, consultar fontes de dados ou realizar uma tarefa específica. Elas são ideais para automatizar tarefas repetitivas em processos de negócios maiores.
  • Edges: as edges definem o fluxo entre os nós, orientando como as tarefas são conectadas e executadas. Essa estrutura é compatível com processos flexíveis de tomada de decisão e permite que os fluxos de trabalho se adaptem com base nos resultados.
  • Edges condicionais (gráficos cíclicos): os gráficos cíclicos permitem loops e ramificações condicionais, permitindo que o sistema revise os nós com base na lógica ou nas saídas do modelo. Essa capacidade é fundamental para lidar com tarefas iterativas e tomar decisões embasadas em ambientes dinâmicos.
  • Estado (gráficos com estado): o estado atua como memória compartilhada, preservando o contexto e permitindo o uso de dados em tempo real entre os nós. Essa capacidade permite que o LangGraph vá além dos fluxos estáticos e seja compatível com avanços adaptáveis e inteligentes na automação de fluxos de trabalho.

Juntos, esses componentes permitem que o LangGraph transforme a forma como as organizações projetam e executam fluxos de trabalho orientados por IA, preenchendo a lacuna entre as ferramentas de IA e os processos de negócios do mundo real.

Principais componentes do LangGraph para automatizar fluxos de trabalho complexos Figura 1 Principais componentes do LangGraph para automatizar fluxos de trabalho complexos

Modelo Granite — LLM leve para solução de problemas do mundo real

O Granite-4.0-Tiny-Preview, desenvolvido pela IBM Research, é um modelo de linguagem de código aberto leve e capaz, projetado para resolver problemas complexos e tarefas práticas de processamento de linguagem natural (NLP). Embora seja menor do que modelos comerciais como o GPT-4, o Granite é rápido, eficiente e totalmente compatível com o Hugging Face, o que o torna uma ótima opção para desenvolvedores que buscam eficiência operacional sem sacrificar o desempenho.

O Granite se destaca em:

  • Classificação de intenção – identificação dos objetivos do usuário em chatbots ou sistemas baseados em tarefas
  • Geração criativa – produzindo resumos, diálogos ou conteúdo resumido
  • Raciocínio e sumarização – ideal para fluxos de trabalho que envolvem RAG ou análise de dados

Neste tutorial, o modelo Granite desempenha um papel fundamental em vários estágios do fluxo de trabalho agêntico, auxiliando tanto na solução de problemas quanto na geração de conteúdo. Seu design leve o torna adequado para aplicações do mundo real, onde a intervenção humana pode ser limitada e onde padrões de design escaláveis são essenciais para construir soluções robustas de IA em diversos conjuntos de dados e provedores.

Caso de uso

Neste tutorial, criaremos um fluxo de trabalho agêntico que atua como um assistente criativo para escrever roteiros animados curtos.

Objetivo

Considerando uma ideia de história do usuário, o agente irá:

  • Identificar o gênero e o tom adequados para a história
  • Gerar um breve esboço da trama
  • Expandir para uma cena-chave (por exemplo, clímax ou ponto de inflexão)
  • Escrever o diálogo para aquela cena no formato de roteiro

Este caso de uso foi criado para mostrar o raciocínio e os recursos generativos de um modelo de linguagem, estruturados por meio do fluxo de trabalho composicional do LangGraph.

Como o fluxo de trabalho opera

Cada uma das etapas a seguir é implementada como um nó do LangGraph:

  • Entrada do usuário: o usuário fornece uma ideia de história de alto nível para iniciar o fluxo de trabalho.
  • Detecção de gênero (node_name - select_genre): um LLM analisa a entrada para inferir o gênero e o tom apropriados para a história.
  • Geração de esboços (node_name - generate_outline): o LLM gera um breve resumo da trama com base no gênero selecionado.
  • Escrita de cena (node_name - generate_scene):  o LLM escreve uma cena crucial em prosa, dando vida à história.
  • Escrita de diálogo (node_name - write_dialogue): o LLM reescreve a cena como diálogo de roteiro formatado, adequado para produção ou edição adicional.

Esses nós são conectados sequencialmente em um LangGraph, e o modelo se move por eles enquanto leva adiante um dicionário de estados mutável.

Este fluxo de trabalho estabelece um equilíbrio entre a geração criativa e o planejamento estrutural. Ele demonstra:

  • Coordenação do LLM por meio do LangGraph
  • Narração de histórias multietapas com intervenção manual mínima
  • Automação criativa em um domínio onde a imaginação humana é essencial

Como ele também escala bem, você pode estendê-lo facilmente adicionando etapas de revisão, vários geradores de cenas ou até mesmo ramificação baseada em caracteres.

Pré-requisitos

Você precisa de uma conta do IBM® Cloud para criar um projeto do watsonx.ai .

Etapas

Etapa 1. Configure seu ambiente

Embora você possa escolher entre várias ferramentas, este tutorial explica como configurar uma conta da IBM para usar um Jupyter Notebook.

  1. Faça login no watsonx.ai usando sua conta do IBM Cloud.
  2. Crie um projeto do watsonx.ai. Você pode obter a ID do projeto a partir de seu projeto. Clique na guia Gerenciar. Em seguida, copie a ID do projeto da seção Detalhes da página Geral. Você precisa dessa ID para este tutorial.
  3. Crie um Jupyter Notebook.

Essa etapa abre um ambiente do Notebook, onde você poderá copiar o código deste tutorial. Ou então, você pode baixar esse Notebook em seu sistema local e carregá-lo como um ativo em seu projeto do watsonx.ai. Para ver mais tutoriais do Granite, consulte a Comunidade IBM Granite. Este tutorial também está disponível no GitHub

Etapa 2. Configure o serviço watsonx.ai Runtime e a chave de API

  1. Crie uma instância do serviço watsonx.ai Runtime (escolha o plano Lite, que é uma instância gratuita).
  2. Gere uma chave de interface de programação de aplicativos (Chave de API).
  3. Associe o serviço watsonx.ai Runtime ao projeto que você criou no watsonx.ai

Etapa 3. Instalação das bibliotecas necessárias

Essa célula instala as bibliotecas principais necessárias para usar o modelo IBM Granite hospedado no Hugging Face:

  • transformers: Essa é a principal biblioteca para carregar e interagir com modelos de linguagem pré-treinados, incluindogranite-4.0-tiny-preview .
  • accelerate:  Auxilia no carregamento eficiente de modelos e no posicionamento de dispositivos, sendo especialmente útil para usar as GPUs de maneira contínua.

O-q sinalizador executa a instalação silenciosamente, suprimindo a saída detalhada para uma interface de notebook mais limpa. Essas bibliotecas são essenciais para baixar o modelo e lidar com a inferência de forma eficiente neste tutorial.

Observação: se você estiver executando este tutorial em um ambiente virtual e não tiver o langgrapg pré-instalado, use pip install langgraph para instalá-lo em seu ambiente local.

!pip install -q transformers accelerate
Captura de tela de um terminal notificando sobre uma nova versão do PiP Trecho de saída: criar fluxo de trabalho agêntico — instalação das bibliotecas

Etapa 4. Importação das bibliotecas necessárias

Essa célula importa todas as bibliotecas principais necessárias para criar e executar o fluxo de trabalho agêntico:

AutoTokenizer eAutoModelForCausalLM detransformers : usado para carregar o modelo Granite e tokenizar os prompts de entrada para geração.

torch : fornece aceleração de GPU e operações de tensor necessárias para inferência de modelo.

time: Habilite o rastreamento de tempo e o monitoramento de desempenho opcionais.

StateGraph eEND delanggraph.graph : são utilizados para definir e compilar o gráfico de fluxos de trabalho agênticos.

IPython.display ,base64: Usado para renderizar a saída de forma organizada e habilitar funcionalidades opcionais de download para o conteúdo gerado nos Jupyter Notebooks.

Juntas, essas importações preparam o ambiente para interação com o modelo, estruturação do fluxo de trabalho e apresentação da saída.

# Import libraries
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
import time
from langgraph.graph import StateGraph, END
from IPython.display import display, HTML
import base64

Etapa 5. Carregue o modelo Granite e o tokenizador

Essa célula carrega os dados do modelogranite-4.0-tiny-preview da IBM e seu tokenizador correspondente do Hugging Face:

model_id: Especifica o identificador do modelo pré-treinado hospedado no Hugging Face.

AutoTokenizer.from_pretrained(model_id): Carrega o tokenizer associado ao modelo Granite. O tokenizador é responsável por converter texto legível por seres humanos em tokens de entrada para o modelo.

AutoModelForCausalLM.from_pretrained(...): Carrega o modelo de linguagem real para modelagem de linguagem causal (ou seja, generativa). Esse modelo pode prever e gerar saídas de texto com base na entrada.

Otorch_dtype=torch.float32 o argumento define explicitamente o tipo de dado como float32, que é mais eficiente em termos de memória e amplamente compatível, especialmente útil em ambientes restritos à GPU.

Essa etapa inicializa efetivamente o modelo Granite como o "mecanismo de raciocínio" por trás de nosso fluxo de trabalho agêntico.

#Load Granite-4.0-Tiny-Preview model and tokenizer from Hugging Face
model_id = "ibm-granite/granite-4.0-tiny-preview"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype=torch.float32)
Trecho de saída dizendo que o caminho rápido não está disponível Trecho de saída: criar fluxo de trabalho agêntico — carregamento do modelo Granite

Etapa 6. Função utility para gerar texto com o Granite

Essa função,generate_with_granite , envolve o processo de geração de texto utilizando o modelo Granite. Aceita o prompt que é o texto de entrada para orientar a resposta do modelo.

max_tokens : o número máximo de tokens a serem gerados na saída (padrão: 200).

use_gpu : um sinalizador que indica se é necessário executar a inferência na GPU (se disponível).

Informações importantes:

device = torch.device(...): Seleciona dinamicamente a GPU (cuda) se solicitada e disponível; caso contrário, o padrão é CPU.

model.to(device): Carrega o modelo no dispositivo apropriado na hora certa, ajudando a economizar memória.

tokenizer(prompt, return_tensors="pt"): Converte a string de entrada em tensores de tokens para processamento do modelo.

model.generate(...): Inicia a geração de texto com estratégias de amostragem, incluindo:

  • do_sample=True: Ativa a aleatoriedade para saídas mais criativas.

  • temperature=0.7 etop_p=0.9: Controla a diversidade do texto gerado.

tokenizer.decode(...): Converte os tokens gerados de volta em texto legível, removendo todos os tokens especiais.

Essa função será reutilizada em todo o fluxo de trabalho agêntico para invocar o modelo Granite em vários nós de decisão ou geração.

def generate_with_granite(prompt: str, max_tokens: int = 200, use_gpu: bool = False) -> str:
    device = torch.device("cuda" if use_gpu and torch.cuda.is_available() else "cpu")

    # Move model to device only at generation time
    model.to(device)
    inputs = tokenizer(prompt, return_tensors="pt").to(device)

    outputs = model.generate(
        **inputs,
        max_new_tokens=max_tokens,
        do_sample=True,
        temperature=0.7,
        top_p=0.9,
        pad_token_id=tokenizer.eos_token_id
    )

    return tokenizer.decode(outputs[0], skip_special_tokens=True).strip()

 

Etapa 7. Crie nó para selecionar gênero e tom (nó - 1)

Essa função,select_genre_node , define o primeiro nó no nosso fluxo de trabalho de geração de roteiros agênticos. Usa o modelo Granite para determinar o gênero e o tom da história com base na entrada do usuário.

Entrada:state , um dicionário que inclui"user_input" (por exemplo, "Quero escrever uma história de fantasia extravagante para crianças").

Construção do prompt: o prompt solicita que o modelo:

  • Atue como assistente criativo.
  • Analise a entrada do usuário.
  • Recomende um gênero e tom usando um formato de saída específico:Genre: <genre> eTone: <tone>

Geração de texto: o prompt é passado para agenerate_with_granite() função utility para gerar uma resposta criativa.

Análise de saída: um loop simples extrai o gênero e o tom da resposta do modelo com base nos prefixos de linha ("Genre:" e"Tone:" ).

Atualização de estado: os valoresgenre etone extraídos são inseridos de volta no dicionário de estado que será passado para o próximo nó.

Esse nó atua como um classificador criativo, permitindo que os nós subsequentes gerem esboços, estruturas e cenas alinhados contextualmente usando gênero e tom como parâmetros fundamentais.

def select_genre_node(state: dict) -> dict:
    prompt = f"""
You are a creative assistant. The user wants to write a short animated story.
Based on the following input, suggest a suitable genre and tone for the story.
User Input: {state['user_input']}

Respond in this format:
Genre: <genre>
Tone: <tone>
""".strip()

    response = generate_with_granite(prompt)

    # Basic parsing of output
    genre, tone = None, None
    for line in response.splitlines():
        if "Genre:" in line:
            genre = line.split("Genre:")[1].strip()
        elif "Tone:" in line:
            tone = line.split("Tone:")[1].strip()

    # Update state
    state["genre"] = genre
    state["tone"] = tone
    return state

Etapa 8. Crie nó para gerar o esboço da trama (nó - 2)

Ogenerate_outline_node define o segundo nó no fluxo de trabalho de geração de roteiro. Ele se baseia no gênero e no tom selecionados para gerar um esboço de enredo conciso para a história.

Entrada: a função recebe o dicionário de estado contendo:

  • user_input: a ideia original da história.
  • gênero: selecionado no nó anterior.
  • tom: selecionado no nó anterior.

Construção do prompt: o modelo é instruído a:

  • Agir como um assistente de redação criativa.
  • Considerar a ideia, o gênero e o tom do usuário.
  • Gerar um breve esboço da trama (três a cinco frases) adequado para um roteiro de animação curto.

Geração de texto: o prompt é enviado paragenerate_with_granite() com um maiortoken limit (max_tokens=250) para permitir espaço para um esboço de várias frases.

Atualização de estado: o esboço da trama gerado é adicionado ao estado sob a chave"outline" , pronto para uso na próxima fase de expansão da estrutura.

Esse nó traduz a intenção criativa abstrata em um esboço narrativo, fornecendo um andaime para a estrutura detalhada de três atos que se segue. Ele garante que os nós trabalhem a partir de uma linha de base coerente e imaginativa.

def generate_outline_node(state: dict) -> dict:
    prompt = f"""
You are a creative writing assistant helping to write a short animated screenplay.
The user wants to write a story with the following details:
Genre: {state.get('genre')}
Tone: {state.get('tone')}
Idea: {state.get('user_input')}

Write a brief plot outline (3–5 sentences) for the story.
""".strip()

    response = generate_with_granite(prompt, max_tokens=250)
    state["outline"] = response
    return state

Etapa 9. Crie um nó para gerar uma cena-chave a partir do esboço (nó - 3)

Ogenerate_scene_node define a terceira etapa do fluxo de trabalho, em que o esboço da trama é transformado em uma cena narrativa rica. Essa cena serve como uma dramatização vívida de um ponto de virada na história, passando a ideia de resumo para narrativa.

Entrada: o nó utiliza o dicionário de estado, que agora inclui:

  • genre etone
  • Oplot outline do nó anterior

Construção do prompt: o modelo é instruído a:

  • Atue como roteirista
  • Crie um ponto de inflexão ou uma cena de clímax usando a históriagenre ,tone eoutline
  • Escreva em formato de prosa para preservar a legibilidade e a descrição amigável para animações

Requisitos da cena:

  • Vívido e descritivo (adequado para animação)
  • Central para o arco emocional ou narrativo (por exemplo, descoberta, conflito ou resolução)

Geração de texto:generate_with_granite é chamado commax_tokens=300 , permitindo espaço suficiente para a construção de cenas imersivas.

Atualização de estado: a cena gerada é adicionada ao dicionário de estado sob a"scene" chave.

Introduz a imersão narrativa e a narrativa visual no fluxo de trabalho. Em vez de simplesmente resumir a história, esse nó a traz à vida com detalhes sensoriais e emocionais, essenciais para a criação de roteiros de curtas-metragens animados.

def generate_scene_node(state: dict) -> dict:
    prompt = f"""
You are a screenwriter.
Based on the following plot outline, write a key scene from the story.
Focus on a turning point or climax moment. Make the scene vivid, descriptive, and suitable for an animated short film.

Genre: {state.get('genre')}
Tone: {state.get('tone')}
Outline: {state.get('outline')}

Write the scene in prose format (not screenplay format).
""".strip()

    response = generate_with_granite(prompt, max_tokens=300)
    state["scene"] = response
    return state

Etapa 10. Crie nó para redigir o diálogo dos personagens no formato de roteiro (nó - 4)

Owrite_dialogue_node função define o quarto passo criativo no fluxo de trabalho da narrativa: converter uma cena narrativa em diálogo formatado de personagens. Essa etapa preenche a lacuna entre a escrita de roteiros em prosa e prontos para a tela, dando voz aos personagens.

Entrada: o nó espera o estadoscene para conter um momento vívido da história (normalmente um ponto de inflexão ou clímax).

Construção do prompt: o modelo é orientado para:

  • Atuar como redator de diálogos
  • Extrair e adaptar o diálogo da cena
  • Formate a saída no estilo de roteiro usando:CHARACTER: Dialogue line

Diretrizes para o diálogo:

  • Mantenha a conversa curta e expressiva
  • Garanta que seja apropriada para a animação (visual, emocional, concisa)
  • Invente nomes, se necessário, para maior clareza

Geração: Agenerate_with_granite() chamada usamax_tokens=300 , que equilibra expressividade com brevidade — ideal para roteiros animados curtos.

Atualização de estado: a caixa de diálogo é salva no estado sob adialogue chave para etapas futuras (por exemplo, exibição ou edição).

def write_dialogue_node(state: dict) -> dict:
    prompt = f"""
You are a dialogue writer for an animated screenplay.

Below is a scene from the story:
{state.get('scene')}

Write the dialogue between the characters in screenplay format.
Keep it short, expressive, and suitable for a short animated film.

Use character names (you may invent them if needed), and format as:

CHARACTER:
Dialogue line

CHARACTER:
Dialogue line
""".strip()

    response = generate_with_granite(prompt, max_tokens=300)
    state["dialogue"] = response
    return state

Etapa 11. Adição de relatórios de progresso a cada nó

Essa função auxiliarwith_progress foi projetada para envolver cada nó do fluxo de trabalho com indicadores de progresso em tempo real. Ela não altera a lógica da função original — simplesmente rastreia e imprime o status e o tempo de execução para tornar os fluxos de trabalho longos mais transparentes.

Objetivo da função: agrupar um nó (por exemplo, generate_scene_node) com um decorador que registra:

  • Qual etapa está sendo executada
  • Índice de etapas e contagem total
  • Quanto tempo a etapa leva

Parâmetros:

  • fn : a função real do nó (por exemplo, write_dialogue_node)
  • label : um rótulo legível por seres humanos para essa função
  • index : número da etapa na sequência (por exemplo, 2)
  • total : número total de etapas no fluxo de trabalho

Wrapper interno:

  • Imprime uma mensagem inicial
  • Registra o horário inicial
  • Chama a função original
  • Imprime uma mensagem de conclusão com a duração decorrida

Retornos: uma versão modificada da função que adiciona mensagens de progresso, mas, fora isso, se comporta de forma idêntica.

À medida que os fluxos de trabalho crescem, torna-se importante rastrear qual etapa está sendo executada, especialmente se algumas etapas (como geração ou edição) demorarem mais ou causarem problemas como sobrecarga de memória. Esse wrapper de progresso garante transparência e é útil para depuração e diagnóstico de tempo de execução.

# Wrap with progress reporting

def with_progress(fn, label, index, total):
    def wrapper(state):
        print(f"\n[{index}/{total}] Starting: {label}")
        start = time.time()
        result = fn(state)
        duration = time.time() - start
        print(f"[{index}/{total}] Completed: {label} in {duration:.2f} seconds")
        return result
    return wrapper

Etapa 12. Definição do fluxo de trabalho do LangGraph

Essa célula define a lógica do fluxo de trabalho para gerar uma breve história animada usando o LangGraph, um framework de programação baseado em gráficos de composição projetada para fluxos de trabalho de LLMs. Cada etapa do gráfico representa uma tarefa criativa e é executada em uma sequência específica para produzir o roteiro final.

Componentes do fluxo de trabalho:StateGraph(dict)  - Inicializa o fluxo de trabalho com um estado baseado em dicionário (ou seja, a memória de trabalho é um dict passado de nó para nó).

Registro de nó com rastreamento de progresso: cada etapa (seleção de gênero, geração de estrutura de tópicos, escrita de cenas, escrita de diálogos) é adicionada como um nó com o wrapper with_progress() - 

graph.add_node("select_genre", with_progress(select_genre_node, "Select Genre", 1, 4)) 

Essa abordagem garante que cada nó registre seu tempo de execução e progresso quando executado.

Edges do fluxo de trabalho (sequenciamento de nós): a sequência do pipeline criativo é claramente definida:

select_genre → generate_outline → generate_scene → write_dialogue

 

set_entry_point() eset_finish_point(): Elas definem os nós inicial e final do fluxo de trabalho.

graph.compile(): Compila o fluxo de trabalho em uma forma executável (fluxo de trabalho), que agora pode ser invocado com um estado inicial.

Essa estrutura permite um fluxo de trabalho de LLM modular, legível e depurável. Cada estágio em seu processo criativo é isolado, pode ter perfis separados e posteriormente pode ser trocado ou estendido (por exemplo, adicionando uma etapa de “revisar cena” ou um nó de “resumir saída”). Oworkflow agora está pronto para ser executado com um prompt e executará seu pipeline criativo passo a passo, mostrando o progresso em tempo real.

# Define LangGraph

graph = StateGraph(dict)
graph.add_node("select_genre", with_progress(select_genre_node, "Select Genre", 1, 4))
graph.add_node("generate_outline", with_progress(generate_outline_node, "Generate Outline", 2, 4))
graph.add_node("generate_scene", with_progress(generate_scene_node, "Generate Scene", 3, 4))
graph.add_node("write_dialogue", with_progress(write_dialogue_node, "Write Dialogue", 4, 4))

graph.set_entry_point("select_genre")
graph.add_edge("select_genre", "generate_outline")
graph.add_edge("generate_outline", "generate_scene")
graph.add_edge("generate_scene", "write_dialogue")
graph.set_finish_point("write_dialogue")

workflow = graph.compile()

 

Etapa 13. Execução do fluxo de trabalho do LangGraph e exibição da saída

Essa célula de código final é onde você executa todo o fluxo de trabalho criativo e exibe os resultados de cada estágio da geração de histórias.

initial_state: Esse comando é o ponto de início do fluxo de trabalho, onde o usuário apresenta uma ideia criativa ou tema. O user_input serve como semente para o pipeline de histórias.

final_state: Esse comando aciona o pipeline completo do LangGraph. A entrada é passada por meio de cada nó registrado (select_genre, gerar_outline, gerar_scena e write_dialogue) em sequência.

Exibição de resultados: o dicionário de estado final agora contém chaves preenchidas por vários nós:

  • "genre": O gênero identificado com base na entrada do usuário.
  • "tone": A qualidade tonal da história.
  • "outline": um resumo da trama de três a cinco frases.
  • "scene": Uma cena vívida de ponto de inflexão escrita em prosa.
  • "dialogue": Diálogo de personagens formatado como um roteiro.

Esta seção demonstra como a intenção do usuário é transformada em um miniscript completo por meio de um fluxo de trabalho de LLM modular em etapas. É um pipeline criativo de ponta a ponta, interativo, interpretável e personalizável.

Observação: o código levará aproximadamente de 15 a 17 minutos para ser executado se você estiver usando GPU ou TPU. Levará cerca de 65 a 70 minutos em um ambiente virtual local para executar e gerar a saída com base na infraestrutura usada para executar o cede.

# Run workflow
initial_state = {
    "user_input": "I want to write a whimsical fantasy story for children about a lost dragon finding its home."
}
final_state = workflow.invoke(initial_state)

# Display Results
print("\n=== Final Output ===")
print("Genre:", final_state.get("genre"))
print("Tone:", final_state.get("tone"))
print("\nPlot Outline:\n", final_state.get("outline"))
print("\nKey Scene:\n", final_state.get("scene"))
print("\nDialogue:\n", final_state.get("dialogue"))
Trecho de saída registrando quanto tempo levou para cada etapa (90 a 260 segundos)
Saída do esboço da trama e cenas-chave de uma história de fantasia
Trechos de saída de uma história de ficção
Trechos de saída de uma história de ficção
Trechos de saída de uma história de ficção

Vamos entender como o sistema transforma o prompt do usuário ("Quero escrever uma história de fantasia extravagante para crianças sobre um dragão perdido que encontra seu lar") em uma história animada completa. Cada etapa se baseia na anterior, guiada pelos nós criativos do fluxo de trabalho e alimentada pelo Granite.

1. Gênero e tom. O fluxo de trabalho começa interpretando o prompt original do usuário: Quero escrever uma história de fantasia para crianças sobre um dragão perdido que encontra seu lar. Com base nessa entrada, o select_genre_node classifica corretamente a narrativa como fantasia extravagante e identifica o tom encantador e comovente apropriado. Esse resultado é preciso e contextualmente alinhado, pois o uso de frases como “extravagante”, “para crianças” e “dragão perdido encontrando seu lar” sinaliza claramente um estilo de narrativa mágico, porém suave. O gênero e o tom atuam como parâmetros fundamentais, que moldam cada etapa de geração subsequente no fluxo de trabalho.

2. Esboço da trama e descrições dos personagens. Na próxima etapa, é solicitado que o modelo crie um esboço do gráfico com base no gênero identificado, no tom e na ideia original do usuário. A saída não inclui apenas um resumo da história de três a cinco frases, mas também inclui descrições de personagens bônus, provavelmente devido a vazamento de prompts ou formatação de instruções retidas de iterações anteriores.

O esboço da trama centra-se em torno de uma menina chamada Lily, que descobre um dragão ferido e o ajuda a retornar à floresta encantada com a orientação de um botânico idoso. Este enredo reflete exatamente a intenção do usuário — focar em uma jornada mágica para crianças com tons emocionais sobre cura, pertencimento e amizade. Os esboços dos personagens do dragão, de Lily e do botânico acrescentam profundidade, transformando uma ideia vaga em um conceito estruturado com funções, personalidades e responsabilidades narrativas definidas. Essa etapa garante que a história migre de uma intenção abstrata para uma estrutura tangível adequada para adaptação na tela.

3. Cena principal. Dado o esboço completo da trama, ogenerate_scene_node escreve uma cena vívida em formato de prosa que captura um ponto de inflexão na história — outro elemento explicitamente solicitado na intenção original do usuário de desenvolver um script de animação curta.

O momento escolhido é quando Lily cuida do dragão ferido na floresta encantada, estabelecendo afinidade emocional e compreensão mútua entre os personagens. Esse momento é crítico, pois direciona a história para o retorno do dragão para casa. A cena é rica em imagens e emoções, aderindo às restrições "extravagantes" e "comoventes" e, ao mesmo tempo, sendo visualmente expressiva, perfeitamente adequada para um formato animado curto.

A capacidade do modelo de manter a consistência do tom e do gênero em todos os estágios demonstra o valor do fluxo de trabalho de passagem de estado do LangGraph e os recursos de raciocínio do modelo Granite.

4. Diálogo em formato de roteiro. Por fim, owrite_dialogue_node converte a cena em prosa em um diálogo estruturado no formato de roteiro. O prompt do usuário (focado na criação de uma história para animação) exige implicitamente que a narrativa seja apresentada em um formato pronto para produção ou visualização. Esse nó cumpre esse objetivo, apresentando um diálogo bem formatado entre Lívia, Drago (o dragão) e o botânico idoso em duas cenas distintas: a casa de campo e a floresta encantada. O diálogo preserva as deixas emocionais e a intenção dos personagens, e é formatado para corresponder às convenções de escrita do script de animação (por exemplo, nomes de personagens em maiúsculas, cabeçalhos de cenas como[INT. LILY’S COTTAGE - DAY]) . A saída permanece curta, expressiva e emocionalmente ressoante, o que é essencial para envolver a audiência jovem em um ambiente animado.

Cada estágio do fluxo de trabalho traduz o prompt original ("uma história de fantasia extravagante para crianças sobre um dragão perdido que encontra seu lar") em uma produção narrativa estruturada, criativa e expressiva. Da seleção de gêneros à formatação de diálogos, o sistema constrói incrementalmente um arco de narrativa coerente. O framework LangGraph garante que as transições entre tarefas estejam logicamente conectadas, e o modelo IBM Granite permite a geração de texto sensível ao contexto com um tom consistente. O resultado é uma história curta de animação compacta e pronta para a tela que emerge inteiramente de uma única linha de entrada, demonstrando o poder prático dos fluxos de trabalho agênticos em aplicações de IA criativas.

Para tornar a experiência de contar histórias ainda mais envolvente, aqui está uma visualização simples baseada em HTML que formata de forma atraente os elementos da história gerados: gênero, tom, trama, cena e diálogo. Além disso, com apenas um clique, você pode baixar o script inteiro como arquivo de texto para uso ou compartilhamento futuro. Vamos dar vida à história nas telas!

# Beautification and Downloadable option creation for user

def display_output_with_download(final_state):
    genre = final_state.get("genre", "")
    tone = final_state.get("tone", "")
    outline = final_state.get("outline", "")
    scene = final_state.get("scene", "")
    dialogue = final_state.get("dialogue", "")

    # Combine scene and dialogue into a full script
    script = f"""Genre: {genre}
Tone: {tone}
Outline:
{outline}
Scene:
{scene}
Dialogue:
{dialogue}
"""

    # Encode to base64
    b64_script = base64.b64encode(script.encode()).decode()

    # Create downloadable HTML content
    html = f"""
    <h2>Genre & Tone</h2>
    <p><strong>Genre:</strong> {genre}</p>
    <p><strong>Tone:</strong> {tone}</p>

    <h2>Outline</h2>
    <pre>{outline}</pre>

    <h2>Scene</h2>
    <pre>{scene}</pre>

    <h2>Dialogue</h2>
    <pre>{dialogue}</pre>

    <a download="screenplay_script.txt" href="data:text/plain;base64,{b64_script}">
        <button style="margin-top: 20px; padding: 10px 20px; font-size: 16px;">Download Script as .txt</button>
    </a>
    """
    display(HTML(html))

# Run this after workflow.invoke()
display_output_with_download(final_state)

Observações sobre o uso da GPU e a infraestrutura

Este tutorial usa o modelo Granite-4.0-Tiny-Preview para geração de texto. Embora seja um dos modelos menores da família Granite, ele ainda requer um ambiente habilitado para GPU para funcionar com eficiência, especialmente ao executar vários nós em um fluxo de trabalho do LangGraph.

Configuração recomendada:

  • Pelo menos uma GPU NVIDIA V100 ou A100
  • Memória de GPU de 16 GB ou mais para desempenho estável
  • Python 3.8+ com Torch, transformers e LangGraph instalados

Observações de desempenho:

  • Você pode encontrar erros de falta de memória do CUDA se executar todos os nós sequencialmente sem limpar a memória da GPU.
  • Para minimizar problemas de memória:
    • Migre o modelo para a GPU somente durante a geração e de volta para a CPU depois.
    • Mantenha os tokens de geração modestos (max_tokens=200–300).
    • Opcionalmente, remova ou simplifique os nós, como revisão ou expansão detalhada de cena.

Se você estiver executando este tutorial em um ambiente de notebook hospedado (por exemplo, IBM watsonx.ai ou Google Colab Pro), certifique-se de que a GPU esteja ativada nas configurações de tempo de execução.

Para ambientes com poucos recursos, considere:

  • Descarregar a inferência do modelo para a API de inferência do Hugging Face.
  • Reduzir a complexidade dos fluxos de trabalho.
  • Usar uma CPU (com tempos de geração mais longos).

Resumo

Neste tutorial, criamos um fluxo de trabalho modular agêntico de narrativa usando o modelo de linguagem LangGraph e o Granite-4.0-Tiny-Preview da IBM. Partindo de um prompt criativo simples, construímos um pipeline passo a passo que classifica o gênero e o tom, gera um esboço da trama, escreve uma cena-chave e termina com um diálogo estilo roteiro. Durante o processo, demonstramos como:

  • Estruturar fluxos de trabalho dinâmicos com o LangGraph
  • Integrar LLMs leves como o Granite para raciocínio criativo
  • Lidar com restrições de memória da GPU com carregamento de modelo ad hoc
  • Exiba e exporte a saída da história em um formato fácil de usar

Esse framework agêntico não é apenas poderoso para oeteiros de cinema, mas pode ser estendido a uma ampla gama de casos de uso criativos ou de roteamento de tarefas. Com apenas alguns nós, você criou um assistente de redação em miniatura capaz de transformar uma ideia caprichosa em uma história pronta para um roteiro.

Quer seja você um desenvolvedor, contador de histórias ou pesquisador, este tutorial oferece uma base prática para explorar a engenharia de fluxos de trabalho baseada em LLMs em domínios criativos.

Pronto para criar seus próprios agentes? Deixe a criatividade fluir com os modelos IBM Granite e IBM watsonx Orchestrate.

Soluções relacionadas
Agentes de IA para empresas

Crie, implemente e gerencie assistentes e agentes de IA potentes que automatizam fluxos de trabalho e processos com a IA generativa.

    Explore o watsonx Orchestrate
    Soluções de agentes de IA da IBM

    Construa o futuro do seu negócio com soluções de IA em que você pode confiar.

    Explore soluções de agentes de IA
    Serviços de IA do IBM® Consulting

    Os serviços de IA da IBM Consulting ajudam a reinventar a forma como as empresas trabalham com IA para gerar transformação.

    Explore os serviços de inteligência artificial
    Dê o próximo passo

    Se você optar por personalizar aplicativos e habilidades criados previamente ou criar e implementar serviços agênticos personalizados usando um estúdio de IA, a plataforma IBM watsonx tem aquilo de que você precisa.

    Explore o watsonx Orchestrate Explore o watsonx.ai
    Notas de rodapé

    1 Lang Cao. 2024. GraphReason: Enhancing Reasoning Capabilities of Large Language Models through A Graph-Based Verification Approach. In Proceedings of the 2nd Workshop on Natural Language Reasoning and Structured Explanations (@ACL 2024), pages 1–12, Bangkok, Tailândia. Association for Computational Linguistics.