Intermediário 20 minPython

Criar um agente de IA local com Python, LangChain e Ollama

Um agente de IA local em Python com LangChain e Ollama não é apenas um chatbot: é um programa que decide sozinho quando chamar uma função, ler um arquivo ou encadear várias etapas para responder. Este guia constrói passo a passo um agente funcional em cerca de vinte minutos, com um modelo Qwen 3.5 9B que roda inteiramente na sua máquina. Nenhuma chave de API, nenhum dado enviado a terceiros.

Por Mohamed Meguedmi·Atualização 2026-08-27·Testado no Windows, macOS e Linux

#Por que um agente de IA local em Python?

Um agente, no sentido do LangChain, é um laço simples: o LLM recebe uma pergunta e a lista de suas ferramentas, escolhe chamar uma delas (ou não), lê o resultado e repete até conseguir responder. Toda a mecânica de “decisão” reside na capacidade do modelo de emitir uma chamada estruturada de ferramenta.

Fazer isso localmente, com Ollama, muda duas coisas concretas: seus dados nunca saem da máquina e cada chamada custa zero euro. É a diferença entre prototipar com a OpenAI e receber uma fatura de 50 € ao final da semana e iterar sem se preocupar com a conta.

Privacidade
Os arquivos que o agente lê (contratos, código proprietário, notas médicas) não saem do computador. Sem DPA para assinar, sem transferência fora da UE.
Custo marginal nulo
Depois de baixar o modelo, você pode iterar centenas de vezes por dia sem que a conta aumente.
Reprodutibilidade
Você fixa a versão exata do modelo (qwen3.5:9b, granite4.2:8b, etc.). Sem drift silencioso como com gpt-4o-2024-11-20 que se transforma em outra coisa um mês depois.
Latência previsível
Sem ida e volta pela rede. Em uma GPU adequada, o primeiro token chega em menos de um segundo.
i
Isso também não é mágico
Um modelo local de 9B ainda é mais fraco que um GPT-5 ou o Claude 4.7 em tarefas muito complexas. Para 80% dos agentes úteis (ler um arquivo, chamar uma API interna, fazer um cálculo, classificar um e-mail), isso é mais do que suficiente. Para o restante, é um ótimo ambiente de aprendizado antes de pagar por tokens.

#Pré-requisitos

O kit Copiloto Local

Este guia leva você ao modelo. O kit leva você ao copiloto que programa no seu editor.

  • Espaço online vitalício
  • PDF + arquivos
  • Atualizações vitalícias
Python 3.10+
A LangChain não é mais testada na versão 3.9. Verifique com python --version.
Ollama instalado e iniciado
Ele deve estar escutando em http://localhost:11434. Ver os guias de instalação do Ollama (Windows, macOS, Linux) se ele ainda não estiver instalado e em execução.
Um modelo que sabe chamar ferramentas
Nem todos os LLMs sabem chamar ferramentas. Qwen 3.5, Granite 4.2, Gemma 4, Devstral e GLM 4.7 Flash oferecem suporte nativo à chamada de ferramentas. Evite os modelos já ultrapassados (Llama 2/3, Qwen 2.5, Mistral 7B).
Hardware
Qwen 3.5 9B Q4 ocupa aproximadamente 6,6 GB de VRAM. Uma GPU de 8 GB (RTX 3060, 4060) é suficiente; uma de 12 GB (4070) dá margem. No Mac, conte com 16 GB de memória unificada para ter folga.
→
A escolha do modelo é crítica
Com um modelo que não sabe chamar ferramentas de forma correta, seu agente vai inventar argumentos ou responder em texto livre em vez de produzir uma chamada de ferramenta. Se você está começando, fique com qwen3.5:9b — é o ponto ideal entre qualidade e VRAM em 2026.

#1. Inicializar o projeto Python

Um ambiente virtual, três pacotes e pronto. Evitamos instalar o LangChain no Python do sistema — ele muda rapidamente e polui esse ambiente.

Criar e ativar o venv
mkdir agent-local && cd agent-local
python -m venv .venv

# macOS / Linux
source .venv/bin/activate

# Windows PowerShell
# .venv\Scripts\Activate.ps1
Instalar as dependências
pip install --upgrade pip
pip install langchain langchain-ollama langgraph
langchain
O núcleo: abstrações de prompts, ferramentas e mensagens.
langchain-ollama
Integração oficial Ollama. Mantida pela equipe LangChain desde 2024.
langgraph
Para o loop do agente. É o motor recomendado hoje, mais estável que os antigos AgentExecutor.
i
Por que langgraph em vez de AgentExecutor?
Os tutoriais antigos do LangChain usam AgentExecutor + create_react_agent (importado de langchain.agents). Essa API está em modo de manutenção. A documentação oficial agora aponta para langgraph.prebuilt.create_react_agent — é o que usaremos aqui. Mais simples, com tipagem melhor e streaming gratuito.

#2. Conectar Ollama via Python

Antes de montar um agente, é preciso verificar se a comunicação com o modelo está funcionando. Baixe o modelo, se ainda não tiver feito isso, e depois teste a chamada mais simples possível.

Baixar Qwen 3.5 9B
ollama pull qwen3.5:9b

O download ocupa aproximadamente 6,6 GB em Q4_K_M (a quantização padrão do Ollama). Após a instalação, crie o primeiro script:

test_ollama.py
from langchain_ollama import ChatOllama

llm = ChatOllama(
    model="qwen3.5:9b",
    temperature=0,
    # base_url="http://localhost:11434",  # par défaut, à changer si Ollama est ailleurs
)

reponse = llm.invoke("En une phrase : qu'est-ce qu'un agent IA ?")
print(reponse.content)
Iniciar o teste
python test_ollama.py

Se você vir uma frase coerente, a conexão Python ↔ Ollama funciona. Se você receber uma ConnectionError, verifique se o Ollama está de fato em execução (ollama ps deve listar um serviço ativo).

→
temperature=0 para agentes
Queremos um comportamento determinístico quando o modelo escolhe uma ferramenta. Uma temperatura alta faz as chamadas de ferramentas variarem de uma execução para outra — é um inferno para depurar. Para respostas criativas, aumente a temperatura para 0,7 mais tarde.

#3. Definir as ferramentas do agente

Uma ferramenta LangChain é simplesmente uma função Python decorada com @tool. O docstring se torna a descrição que o LLM vê — ele usa isso para decidir quando chamá-la. Seja preciso: um docstring vago gera chamadas aleatórias.

Vamos criar duas ferramentas representativas: um avaliador de expressões aritméticas e um leitor de arquivos.

tools.py
from pathlib import Path
from langchain_core.tools import tool


@tool
def calculer(expression: str) -> str:
    """Évalue une expression arithmétique simple.

    Args:
        expression: une expression contenant uniquement des chiffres,
                    des espaces et les opérateurs + - * / ( ).

    Returns:
        Le résultat numérique sous forme de chaîne, ou un message d'erreur.
    """
    autorise = set("0123456789+-*/(). ")
    if not all(c in autorise for c in expression):
        return "Erreur : caractère non autorisé. Seuls 0-9 et + - * / ( ) sont permis."
    try:
        resultat = eval(expression, {"__builtins__": {}}, {})
        return str(resultat)
    except Exception as e:
        return f"Erreur de calcul : {e}"


@tool
def lire_fichier(chemin: str) -> str:
    """Lit le contenu d'un fichier texte du répertoire courant.

    Args:
        chemin: chemin relatif ou absolu vers un fichier texte (.txt, .md, .py, etc.).

    Returns:
        Le contenu du fichier, ou un message d'erreur si introuvable.
    """
    p = Path(chemin)
    if not p.exists():
        return f"Fichier introuvable : {chemin}"
    if not p.is_file():
        return f"Ce n'est pas un fichier : {chemin}"
    try:
        return p.read_text(encoding="utf-8")
    except UnicodeDecodeError:
        return "Fichier binaire ou encodage non UTF-8."
    except Exception as e:
        return f"Erreur de lecture : {e}"
!
eval() é perigoso em produção
O uso de eval(), mesmo com __builtins__ vazio, não é uma verdadeira sandbox. Para um agente que roda no seu computador e que você controla, é aceitável. Para qualquer coisa exposta a usuários externos, use ast.parse com uma lista de operadores permitidos ou a biblioteca simpleeval.

Três regras para que as ferramentas sejam usadas corretamente pelo modelo:

Nome explícito
calculer em vez de process, lire_fichier em vez de get. O LLM escolhe primeiro pelo nome.
Docstring detalhada
Descreva o que a ferramenta faz, o que ela espera receber e o que ela retorna. As anotações de tipo do Python são lidas pelo LangChain e expostas ao modelo.
Retornar uma string
Sempre. Se a função retornar um dicionário ou um objeto, o LangChain o serializa, mas o resultado fica menos legível para o modelo.

#4. Montar o agente

Temos um LLM e temos ferramentas. A função create_react_agent do langgraph conecta os dois e gerencia o ciclo: enquanto o modelo deseja chamar ferramentas, continuamos; quando ele responde em texto, paramos.

agent.py
from langchain_ollama import ChatOllama
from langgraph.prebuilt import create_react_agent
from tools import calculer, lire_fichier

llm = ChatOllama(model="qwen3.5:9b", temperature=0)

SYSTEM_PROMPT = (
    "Tu es un assistant en français. Tu disposes d'outils pour calculer "
    "et lire des fichiers. Utilise-les dès que c'est pertinent, sans jamais "
    "inventer un résultat. Réponds toujours en français."
)

agent = create_react_agent(
    model=llm,
    tools=[calculer, lire_fichier],
    prompt=SYSTEM_PROMPT,
)

if __name__ == "__main__":
    question = (
        "Combien fait 1234 * 5678 ? "
        "Ensuite, lis le fichier notes.txt et résume-le en deux phrases."
    )
    reponse = agent.invoke({"messages": [("user", question)]})

    # Le dernier message est la réponse finale du modèle
    print(reponse["messages"][-1].content)

Crie um pequeno arquivo notes.txt na mesma pasta para testar:

Arquivo de teste
echo "Réunion projet Hermes : on garde Ollama comme runtime principal, on évalue vLLM pour la prod, RAG sur ChromaDB. Décision : POC en 2 semaines." > notes.txt

#5. Executar e observar o loop

Iniciar o agente
python agent.py

Você deveria ver uma resposta que contenha ao mesmo tempo o resultado do cálculo (7.006.652) e um resumo do arquivo. Mas é mais instrutivo ver o que acontece durante a execução. Adicione este modo verboso para acompanhar o loop passo a passo:

Modo streaming detalhado
for evenement in agent.stream(
    {"messages": [("user", question)]},
    stream_mode="values",
):
    dernier = evenement["messages"][-1]
    dernier.pretty_print()
    print("---")

Você vai observar a sequência típica de um agente: o modelo gera uma chamada para calculer, recebe o resultado, gera uma chamada para lire_fichier, recebe o conteúdo e então gera a resposta final. Três iterações para uma única pergunta do usuário.

i
Se o modelo não chamar ferramentas
Duas causas frequentes: (1) o modelo não tem o tool calling ativado no Ollama — execute novamente ollama pull qwen3.5:9b para obter a versão mais recente. (2) O prompt de sistema é muito vago. Especifique explicitamente "use as ferramentas para cálculos" em vez de esperar que ele adivinhe.

#Dicas e solução de problemas

Contexto muito curto
Por padrão, o Ollama trunca para 2048 tokens. Se o seu agente encadear várias ferramentas, esse limite é ultrapassado rapidamente. Defina num_ctx=8192 em ChatOllama(model="...", num_ctx=8192).
Modelo que inventa ferramentas inexistentes
Se o agente inventar nomes de funções, reduza a temperatura para 0 e reformule o prompt de sistema, listando explicitamente as ferramentas disponíveis.
Laço infinito
Defina um limite: create_react_agent(..., recursion_limit=10). Acima disso, o agente encerra corretamente.
Latência muito alta
Em CPU, um 9B faz 5 a 10 tok/s. Mude para qwen3.5:4b (3,4 GB de VRAM, 30+ tok/s em GPU modesta) se a qualidade continuar aceitável para o seu caso.
Erro "context length exceeded"
O resumo de um arquivo longo ultrapassa num_ctx. Adicione uma ferramenta intermediária que particione o arquivo ou aumente num_ctx até 32768, se sua VRAM permitir.
→
Rastrear seus agentes com LangSmith
Para depurar seriamente, o LangSmith registra cada chamada, cada token e cada ferramenta. É gratuito em desenvolvimento. Defina LANGSMITH_TRACING=true e LANGSMITH_API_KEY no seu ambiente e você terá uma linha do tempo completa. Nenhum dado é enviado se você não definir a chave.

#Para se aprofundar

Você tem um agente que calcula, lê, raciocina localmente. Três direções naturais para explorar:

Dar a ele acesso aos seus documentos
Acoplar o agente a uma base vetorial para que ele possa responder com base em um corpus interno — esse é exatamente o tema do guia de introdução ao RAG local.
Viver na CLI para programar
Aider é um agente de desenvolvimento que edita diretamente seus arquivos a partir do terminal. Você pode conectá-lo ao mesmo Ollama e aproveitar o Qwen3-Coder 30B ou Devstral para edição assistida.
Ajustar a quantização do modelo
Se você achar o Qwen 3.5 9B Q4 lento demais ou com qualidade muito limitada, o guia de quantização explica quando passar para Q5_K_M ou reduzir o tamanho do modelo.
Este guia ajudou você?

Um comentário, um erro ou uma observação? Avise-nos; isso ajuda a melhorar o guia para todos.