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
- Instale o Ollama na sua maquina.
- Baixe um modelo: execute
ollama pull llama3no seu terminal. - Verifique que o Ollama esta em execucao (ele escuta em
http://localhost:11434por padrao).
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
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
- Baixe um arquivo de modelo GGUF (ex.
tinyllama-1.1b-chat.Q4_K_M.ggufdo Hugging Face). - Coloque-o na pasta do seu projeto ou em um caminho conhecido.
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
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
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.
Veja a referencia da Paleta de Componentes de IA para a lista completa de componentes de IA incluindo TEmbedding, TRAGEngine e TSpeechToText.