Tutorial: Integracao com IA

O HarbourBuilder fornece dois componentes de IA complementares: TOllama para conectar a grandes modelos de linguagem locais via o servico Ollama, e TTransformer para carregar e executar pesos de modelo transformer diretamente no processo. Este tutorial cobre ambas as abordagens com exemplos completos e funcionais.

Parte 1: TOllama — Chat com um LLM Local

Passo 1: Pre-requisitos

  1. Instale o Ollama na sua maquina.
  2. Baixe um modelo: execute ollama pull llama3 no seu terminal.
  3. Verifique que o Ollama esta em execucao (ele escuta em http://localhost:11434 por padrao).
Sem necessidade de chaves de API

O TOllama conecta a uma instancia Ollama rodando localmente. Toda inferencia acontece na sua maquina — sem servicos em nuvem, sem chaves de API, nenhum dado sai do seu computador.

Passo 2: Criar a UI de Chat

Construa um formulario com um Memo para o historico de conversacao, uma Caixa de Texto para entrada do usuario e um botao Enviar.

#include "hbbuilder.ch"

function Main()

   local oForm, oMemo, oGetPrompt, oBtnSend, oOllama
   local cPrompt := ""

   // --- Conectar ao Ollama ---
   DEFINE OLLAMA oOllama ;
      URL "http://localhost:11434" ;
      MODEL "llama3"

   // --- Construir a UI ---
   DEFINE FORM oForm TITLE "Chat com IA" ;
      SIZE 700, 550 FONT "Segoe UI", 10

   @ 10, 10 MEMO oMemo ;
      OF oForm SIZE 660, 420 ;
      READONLY

   @ 440, 10 GET oGetPrompt VAR cPrompt ;
      OF oForm SIZE 540, 28

   @ 440, 560 BUTTON oBtnSend PROMPT "Enviar" ;
      OF oForm SIZE 110, 32 ;
      ACTION SendMessage( oOllama, oMemo, oGetPrompt )

   ACTIVATE FORM oForm CENTERED

return nil

Passo 3: Enviar uma Mensagem e Obter uma Resposta

Use oOllama:Chat() para uma simples requisicao/resposta, ou oOllama:ChatStream() para receber a resposta token por token conforme e gerada.

Chat simples (bloqueante):

static function SendMessage( oOllama, oMemo, oGetPrompt )

   local cPrompt  := oGetPrompt:GetValue()
   local cResponse

   if Empty( cPrompt )
      return nil
   endif

   // Exibir mensagem do usuario
   oMemo:Append( "Voce: " + cPrompt + Chr( 13 ) + Chr( 10 ) )
   oGetPrompt:SetValue( "" )

   // Obter resposta da IA
   cResponse := oOllama:Chat( cPrompt )

   oMemo:Append( "IA: " + cResponse + Chr( 13 ) + Chr( 10 ) + Chr( 13 ) + Chr( 10 ) )

return nil

Passo 4: Resposta em Streaming para um Memo

Para uma melhor experiencia do usuario, faca streaming da resposta para que os tokens aparecam no Memo conforme sao gerados — exatamente como uma interface de chat real.

static function SendMessageStream( oOllama, oMemo, oGetPrompt )

   local cPrompt := oGetPrompt:GetValue()

   if Empty( cPrompt )
      return nil
   endif

   oMemo:Append( "Voce: " + cPrompt + Chr( 13 ) + Chr( 10 ) )
   oMemo:Append( "IA: " )
   oGetPrompt:SetValue( "" )

   // Stream de tokens um a um no Memo
   oOllama:ChatStream( cPrompt, { |cToken| oMemo:Append( cToken ) } )

   oMemo:Append( Chr( 13 ) + Chr( 10 ) + Chr( 13 ) + Chr( 10 ) )

return nil
Historico de conversacao

O TOllama mantem um historico de conversacao internamente. Cada chamada a Chat() ou ChatStream() inclui mensagens anteriores como contexto. Chame oOllama:ClearHistory() para iniciar uma nova conversa.

Passo 5: Propriedades e Metodos do TOllama

Membro Tipo Descricao
cUrl Propriedade URL do servidor Ollama (padrao "http://localhost:11434").
cModel Propriedade Nome do modelo (ex. "llama3", "mistral", "codellama").
nTemperature Propriedade Temperatura de amostragem (0.0 – 2.0, padrao 0.7).
Chat( cPrompt ) Metodo Enviar um prompt e retornar a resposta completa como string.
ChatStream( cPrompt, bCallback ) Metodo Fazer stream da resposta, chamando bCallback com cada token.
SetSystem( cText ) Metodo Definir o prompt de sistema que orienta o comportamento do modelo.
ClearHistory() Metodo Resetar o historico de conversacao.

Parte 2: TTransformer — Inferencia no Processo

Para cenarios onde voce precisa executar um modelo sem um servico externo, o HarbourBuilder fornece TTransformer. Este componente carrega pesos de modelo (formato GGUF) diretamente na memoria da sua aplicacao e executa inferencia usando a CPU (ou GPU se disponivel).

Passo 1: Obter um Arquivo de Modelo

  1. Baixe um arquivo de modelo GGUF (ex. tinyllama-1.1b-chat.Q4_K_M.gguf do Hugging Face).
  2. Coloque-o na pasta do seu projeto ou em um caminho conhecido.
Tamanho do modelo importa

Modelos quantizados menores (Q4_K_M, Q5_K_M) rodam bem na maioria dos hardwares. Um modelo de 1B–3B parametros com quantizacao Q4 precisa de apenas 1–2 GB de RAM. Modelos maiores requerem mais memoria e uma GPU.

Passo 2: Carregar o Modelo

#include "hbbuilder.ch"

function Main()

   local oForm, oMemo, oGetPrompt, oBtnRun, oTransformer

   // --- Carregar o modelo transformer ---
   DEFINE TRANSFORMER oTransformer ;
      MODEL "models/tinyllama-1.1b-chat.Q4_K_M.gguf" ;
      CONTEXT 2048 ;
      GPU_LAYERS 0  // Defina > 0 para descarregar camadas na GPU

   if .not. oTransformer:lLoaded
      MsgAlert( "Falha ao carregar modelo: " + oTransformer:cError )
      return nil
   endif

   // --- Construir a UI ---
   DEFINE FORM oForm TITLE "Demo TTransformer" ;
      SIZE 700, 550 FONT "Segoe UI", 10

   @ 10, 10 MEMO oMemo ;
      OF oForm SIZE 660, 420 ;
      READONLY

   @ 440, 10 GET oGetPrompt VAR cPrompt ;
      OF oForm SIZE 540, 28

   @ 440, 560 BUTTON oBtnRun PROMPT "Executar" ;
      OF oForm SIZE 110, 32 ;
      ACTION RunInference( oTransformer, oMemo, oGetPrompt )

   ACTIVATE FORM oForm CENTERED

return nil

Passo 3: Executar Inferencia

Use Generate() para uma resposta completa ou GenerateStream() para fazer stream de tokens em um controle Memo conforme sao produzidos.

static function RunInference( oTransformer, oMemo, oGetPrompt )

   local cPrompt := oGetPrompt:GetValue()

   if Empty( cPrompt )
      return nil
   endif

   oMemo:Append( "Prompt: " + cPrompt + Chr( 13 ) + Chr( 10 ) )
   oMemo:Append( "Resposta: " )
   oGetPrompt:SetValue( "" )

   // Stream de saida token por token
   oTransformer:GenerateStream( cPrompt, ;
      { |cToken| oMemo:Append( cToken ) }, ;  // a cada token
      256 )  // max tokens

   oMemo:Append( Chr( 13 ) + Chr( 10 ) + Chr( 13 ) + Chr( 10 ) )

return nil

Passo 4: Propriedades e Metodos do TTransformer

Membro Tipo Descricao
cModel Propriedade Caminho para o arquivo de modelo GGUF.
nContext Propriedade Tamanho da janela de contexto em tokens (padrao 2048).
nGpuLayers Propriedade Numero de camadas para descarregar na GPU (0 = somente CPU).
lLoaded Propriedade .T. se o modelo foi carregado com sucesso.
Generate( cPrompt, nMaxTokens ) Metodo Executar inferencia e retornar a saida completa como string.
GenerateStream( cPrompt, bCallback, nMaxTokens ) Metodo Stream de tokens de saida via callback.
Tokenize( cText ) Metodo Retornar um array de IDs de token para o texto informado.

Quando Usar Cada Um

graph LR A{"Precisa de IA?"} -->|"Chat LLM completo
historico de conversacao"| B["TOllama
Servico Ollama"] A -->|"Inferencia embarcada
sem deps externas"| C["TTransformer
GGUF no processo"] B --> D["Vantagens: config facil
muitos modelos
troca modelos a quente"] C --> E["Vantagens: sem servidor
executavel unico
funciona offline"] style A fill:#d2a8ff,stroke:#bc8cff,color:#0d1117 style B fill:#58a6ff,stroke:#388bfd,color:#0d1117 style C fill:#3fb950,stroke:#2ea043,color:#0d1117 style D fill:#58a6ff,stroke:#388bfd,color:#0d1117 style E fill:#3fb950,stroke:#2ea043,color:#0d1117
Combine ambas as abordagens

Voce pode usar o TOllama para tarefas pesadas de chat e o TTransformer para tarefas leves e rapidas de classificacao ou incorporacao — ambos na mesma aplicacao.

Explore mais

Veja a referencia da Paleta de Componentes de IA para a lista completa de componentes de IA incluindo TEmbedding, TRAGEngine e TSpeechToText.

Nesta Página

Primeiros Passos Paleta de Componentes Recursos da IDE Tutoriais Referencia Plataformas Parte 1: TOllama — Chat com um LLM Local Passo 1: Pre-requisitos Passo 2: Criar a UI de Chat Passo 3: Enviar uma Mensagem e Obter uma Resposta Passo 4: Resposta em Streaming para um Memo Passo 5: Propriedades e Metodos do TOllama Parte 2: TTransformer — Inferencia no Processo Passo 1: Obter um Arquivo de Modelo Passo 2: Carregar o Modelo Passo 3: Executar Inferencia Passo 4: Propriedades e Metodos do TTransformer Quando Usar Cada Um