Pular para o conteúdo principal

Kimi K2 Thinking: guia do LLM open-source, benchmarks e ferramentas

Tutorial mão na massa para rodar o Kimi K2 Thinking, criar fluxos com chamadas de ferramentas, ver o raciocínio transparente e comparar com GPT-5 e Claude 4.5.
· 15 min leer

Explore com IA

Um modelo open-source supera o GPT-5 e o Claude Sonnet 4.5 nos principais benchmarks por uma fração do custo. Esse modelo é o Kimi K2 Thinking, a variante de raciocínio da Moonshot AI, lançada em novembro de 2025.

O Kimi K2 Thinking consegue executar de 200 a 300 chamadas de ferramenta sequenciais de forma autônoma, o que o torna ideal para fluxos de trabalho agentivos complexos. Ele também expõe seu processo de raciocínio por meio de um campo dedicado na API, para você ver exatamente como pensa ao resolver problemas.

Este tutorial mostra como usar a API do Kimi K2 Thinking para tarefas de raciocínio. Você vai implementar fluxos com chamadas de ferramentas, construir um app de chat comparativo para testar o K2 contra o GPT-5 e o Claude, e entender quando as forças do K2 fazem dele a melhor escolha.  Se você quer se aprofundar em como construir apps com LLMs, recomendo o curso Developing LLM Applications with LangChain. Você também pode conferir nossos outros projetos sobre GPT-5.1-Codex e Qwen3-Max-Thinking. E vale conhecer nosso guia do novo Kimi K2.5 com Agent Swarm.

Aqui está a prévia do app:

Antes de partir para a prática, vamos entender o que torna o K2 Thinking diferente dos modelos de linguagem tradicionais.

O que é o Kimi K2 Thinking?

A maioria dos modelos de linguagem gera respostas imediatamente. O K2 Thinking funciona de outra forma. Ele foi criado para problemas de múltiplas etapas, em que o modelo precisa planejar, raciocinar e agir por conta própria.

Arquitetura e design

O modelo usa uma arquitetura Mixture-of-Experts (MoE) com 1 trilhão de parâmetros totais. Apenas 32 bilhões são ativados para cada entrada. Isso dá ao K2 a potência de um modelo massivo sem os altos custos de inferência. A janela de contexto de 256.000 tokens permite inserir bases de código inteiras, documentos longos ou históricos extensos de conversas sem precisar fragmentar.

A Moonshot AI lançou duas versões. K2 Instruct cuida de tarefas diretas como geração de texto, classificação e perguntas e respostas simples, quando a velocidade é prioridade. O K2 Thinking é para tarefas complexas de raciocínio.

Duas capacidades de destaque

A primeira grande funcionalidade do K2 Thinking é o raciocínio transparente. Você consegue ver como ele decompõe problemas, avalia opções e chega às conclusões.

A segunda é a orquestração de ferramentas. O K2 lida com chamadas extensas e sequenciais de ferramentas, muito além do que a maioria dos modelos suporta. Ele decide quais ferramentas usar, quando usar e como combinar os resultados, sem precisar que você intervenha em cada etapa.

Recursos adicionais

O K2 inclui recursos para diferentes necessidades de implantação. Para cenários de produção em que a precisão é crítica, o Heavy Mode executa oito trilhas de raciocínio em paralelo e seleciona a melhor resposta, embora com custo computacional maior. 

Para aplicações sensíveis à latência, a quantização INT4 dobra a velocidade de inferência com perda mínima de acurácia, tornando-o prático para ambientes de alto throughput.

Kimi K2 Thinking vs GPT-5 vs Claude Sonnet 4.5 vs DeepSeek

Veja como o K2 se compara ao GPT-5, Claude Sonnet 4.5 e DeepSeek V3.2.

Métrica

Kimi K2 Thinking

GPT-5 (High)

Claude Sonnet 4.5

DeepSeek-V3.2

HLE (c/ tools)

44,9

41,7

32

20,3

HLE Heavy Mode

51

42

—

—

AIME25 (c/ python)

99,1 %

99,6 %

100 %

58,1 %

GPQA

84,5

85,7

83,4

79,9

BrowseComp

60,2

54,9

24,1

40,1

Frames

87

86

85

80,2

SWE-bench Verified

71,3 %

74,9 %

77,2 %

67,8 %

LiveCodeBench

83,1 %

87,0 %

64,0 %

74,1 %

Janela de contexto

256 k tokens

400 k tokens

200 k tokens

128 k tokens

Preço de entrada

US$ 0,60 / 1 M

US$ 1,25 / 1 M

US$ 3,00 / 1 M

US$ 0,55 / 1 M

Preço de saída

US$ 2,50 / 1 M

US$ 10,00 / 1 M

US$ 15,00 / 1 M

US$ 2,19 / 1 M

Máx. de chamadas de ferramenta

200–300

Dezenas +

Dezenas +

Não especificado

Definições rápidas dos benchmarks: HLE testa conhecimento em nível de pós-graduação; AIME25 usa problemas de matemática de competições; BrowseComp e Frames testam navegação e síntese na web; SWE-bench Verified mede correção de bugs em código open-source; LiveCodeBench testa geração de código; GPQA cobre questões de ciências em nível de pós-graduação.

O treinamento do K2 com ferramentas se destaca principalmente em benchmarks agentivos. O Heavy Mode supera o GPT-5 por 9 pontos no HLE porque roda oito trilhas de raciocínio em paralelo. Já o foco em código do Claude dá a ele vantagem no SWE-bench Verified, tornando-o a melhor escolha para projetos de engenharia de software.

Em tarefas de raciocínio puro, os três modelos têm desempenho semelhante. As diferenças aparecem quando entram ferramentas em cena. A capacidade de 200–300 chamadas de ferramenta do K2 permite conduzir pesquisas autônomas, pipelines de debugging e análises de dados em múltiplas etapas sem você precisar intervir a cada fase.

Quando escolher cada modelo

  • Escolha o K2 Thinking para fluxos agentivos que exijam orquestração extensa de ferramentas, pesquisa na web e tarefas de síntese de informação, ou quando você precisa de cadeias de raciocínio transparentes para debugging ou conformidade.
  • Escolha o GPT-5 para a maior janela de contexto (400k tokens) ou quando você precisa de desempenho equilibrado entre tarefas com um ecossistema maduro.
  • Escolha o Claude Sonnet 4.5 para projetos de engenharia de software em que debugging e correções de código são prioridade.
  • Escolha o DeepSeek quando o orçamento for prioridade e houver requisito de open-source sob licença MIT.

Como configurar o acesso à API do Kimi K2 Thinking

Você tem duas opções para acessar o K2 Thinking: diretamente pela platform.moonshot.ai da Moonshot AI, ou via OpenRouter, um gateway de API unificado. Vamos usar o OpenRouter porque ele dá acesso ao K2, GPT-5, Claude e dezenas de outros modelos com uma única chave de API. Esse acesso unificado se torna essencial mais adiante, quando você construir o app de comparação. O OpenRouter também cuida automaticamente de rate limiting e failover, sem você precisar gerenciar várias contas de provedores.

Primeiro, acesse openrouter.ai e crie uma conta. Você pode entrar com Google ou GitHub. Depois, vá à seção “Keys” no dashboard e gere uma nova chave de API. 

O OpenRouter oferece US$ 5 em créditos gratuitos no cadastro, o suficiente para testar o K2 Thinking em várias consultas. Se precisar de mais créditos, adicione um método de pagamento na seção “Credits”.

Copie sua chave de API e guarde em um local seguro. Você vai precisar dela em instantes. Não faça commit dessa chave no controle de versão nem a compartilhe publicamente, pois qualquer pessoa com a chave pode fazer chamadas de API na sua conta.

Agora vamos configurar seu ambiente Python. Você vai precisar do SDK Python da OpenAI, que funciona com a API do OpenRouter, já que ele mantém compatibilidade com OpenAI. Também vale instalar o python-dotenv para gerenciar sua chave com segurança. Instale ambos os pacotes:

!pip install openai python-dotenv

Crie um arquivo .env no diretório do projeto e adicione sua chave de API do OpenRouter:

OPENROUTER_API_KEY=your_key_here

Se você usa git, adicione .env ao seu arquivo .gitignore para não cometer as credenciais por engano.

Aqui vai um teste rápido para verificar se está tudo ok:

import os
from openai import OpenAI
from dotenv import load_dotenv

# Carrega a chave da API do arquivo .env
load_dotenv()

# Configura o client para o OpenRouter
client = OpenAI(
   base_url="https://openrouter.ai/api/v1",
   api_key=os.getenv("OPENROUTER_API_KEY")
)

# Chamada de teste ao K2 Thinking
response = client.chat.completions.create(
   model="moonshotai/kimi-k2-thinking",
   messages=[
       {"role": "user", "content": "What is 15 * 24?"}
   ]
)

print(response.choices[0].message.content)

Saída:

15 * 24 = **360**

Se você viu a resposta, está tudo pronto.

Entendendo o Thinking Mode do Kimi K2

Mais acima, mencionamos o raciocínio transparente do K2. Agora vamos ver exatamente como acessar e usar isso no seu código. O K2 Thinking expõe automaticamente seu processo de raciocínio por meio de um campo dedicado na API. 

Diferente de alguns outros modelos, em que você precisa ativar o thinking mode manualmente, o K2 inclui o conteúdo de raciocínio em toda resposta por padrão.

Como acessar o conteúdo de raciocínio

Quando você faz uma chamada à API do K2 Thinking, a resposta contém dois campos. O campo content traz a resposta final, e o campo reasoning mostra o passo a passo do raciocínio. Aqui vai um exemplo prático com um cálculo de desconto que exige várias etapas:

import os
from openai import OpenAI
from dotenv import load_dotenv

load_dotenv()

client = OpenAI(
   base_url="https://openrouter.ai/api/v1",
   api_key=os.getenv("OPENROUTER_API_KEY")
)

response = client.chat.completions.create(
   model="moonshotai/kimi-k2-thinking",
   messages=[
       {"role": "user", "content": "A laptop costs $850. There's a 20% discount today, then 8% sales tax applies to the discounted price. What's the final amount I pay?"}
   ],
   temperature=1.0
)

print("Final answer:")
print(response.choices[0].message.content)
print("\nReasoning process:")
print(response.choices[0].message.reasoning)

Saída:

Final answer:
The final amount you pay is **$734.40**.

Here's the breakdown:

1. **Discount:** 20% of $850 = $170
2. **Discounted price:** $850 - $170 = $680
3. **Sales tax:** 8% of $680 = $54.40
4. **Final amount:** $680 + $54.40 = **$734.40**

Processo de raciocínio (truncado para facilitar a leitura):

The user wants to know the final amount they will pay for a laptop with a discount and then sales tax applied.

Step 1: Calculate the discount amount.
Discount amount = $850 * 0.20 = $170

Step 2: Calculate the discounted price.
Discounted price = $850 - $170 = $680

Step 3: Calculate the sales tax amount.
Sales tax amount = $680 * 0.08 = $54.40

Step 4: Calculate the final amount to pay.
Final amount = $680 + $54.40 = $734.40

Let me double-check the calculations...
[verification steps omitted]

The final amount is $734.40

O campo content fornece a resposta limpa que seus usuários veem. O campo reasoning mostra como o K2 trabalhou o problema, ajudando você a entender se o modelo realmente raciocinou corretamente ou apenas teve sorte.

O K2 gera tokens de raciocínio durante a inferência, não depois. Isso significa que o modelo pensa sobre o problema antes de assumir uma resposta — como você resolveria um cálculo no rascunho antes de escrever o resultado final. O raciocínio acontece em tempo real como parte do processo de geração.

Parâmetros recomendados para o Thinking mode

Defina temperature=1.0 ao usar o K2 Thinking. Temperaturas menores restringem a exploração do raciocínio, o que vai contra o objetivo do Thinking mode. Você também vai querer max_tokens=4096 ou mais, já que as cadeias de raciocínio consomem tokens antes mesmo da resposta final começar.

response = client.chat.completions.create(
   model="moonshotai/kimi-k2-thinking",
   messages=[{"role": "user", "content": "Your question here"}],
   temperature=1.0,
   max_tokens=4096
)

Agora que você entendeu o thinking mode, vamos explorar outra capacidade essencial do K2: chamadas de ferramentas. Embora muitos modelos suportem uso básico de ferramentas, a abordagem do K2 é diferente em escala e autonomia.

Capacidades de chamadas de ferramentas do Kimi K2

Chamadas de ferramentas permitem que o K2 execute funções durante o raciocínio. Você define ferramentas como schemas JSON descrevendo o que cada função faz e quais parâmetros ela precisa. Quando o K2 precisa de dados externos ou computação, ele chama a ferramenta certa e aguarda os resultados.

Isso cria um loop de ida e volta: o K2 lê seu prompt e raciocina sobre ele. Se precisar de uma ferramenta, ele retorna finish_reason: "tool_calls". Você executa a função, envia os resultados de volta com role: "tool", e o K2 continua. Isso se repete até o K2 retornar finish_reason: "stop" com a resposta final.

O schema segue o formato da OpenAI com nome, descrição e parâmetros. O K2 lê essas informações para entender quando usar cada ferramenta. Descrições claras são importantes porque orientam as decisões do modelo.

Construindo a ferramenta de análise de CSV

Vamos criar uma ferramenta prática que analisa arquivos CSV, uma tarefa comum em ciência de dados. Essa ferramenta lê um CSV, extrai as informações de colunas e retorna estatísticas de resumo. Ela demonstra como o K2 pode acessar dados externos durante o raciocínio — essencial para aplicações orientadas por dados.

Aqui está a implementação completa:

import csv
import os
import json

# Define o schema da ferramenta
tools = [
   {
       "type": "function",
       "function": {
           "name": "analyze_csv",
           "description": "Read and analyze the first few rows of a CSV file. Returns columns, sample rows, total row count, and file size.",
           "parameters": {
               "type": "object",
               "properties": {
                   "filepath": {
                       "type": "string",
                       "description": "Path to the CSV file"
                   },
                   "num_rows": {
                       "type": "integer",
                       "description": "Number of rows to read",
                       "default": 10
                   }
               },
               "required": ["filepath"]
           }
       }
   }
]

O schema define uma ferramenta de função seguindo o formato da OpenAI. O campo description informa ao K2 o que a ferramenta faz e orienta a decisão de quando usá-la. 

O objeto parameters especifica as entradas: filepath é obrigatório, enquanto num_rows é opcional, com valor padrão 10. Descrições claras ajudam o K2 a entender quando essa ferramenta corresponde à necessidade do usuário.

A implementação cuida do processamento real do arquivo:

# Implementa a função
def analyze_csv(filepath: str, num_rows: int = 10) -> dict:
   if not os.path.exists(filepath):
       return {"error": f"File not found: {filepath}"}

   try:
       with open(filepath, 'r') as f:
           reader = csv.DictReader(f)
           columns = reader.fieldnames
           sample_rows = [dict(row) for i, row in enumerate(reader) if i < num_rows]
           f.seek(0)
           total_rows = sum(1 for _ in f) - 1

       return {
           "columns": list(columns),
           "sample_rows": sample_rows,
           "total_rows": total_rows,
           "file_size_kb": round(os.path.getsize(filepath) / 1024, 2)
       }
   except Exception as e:
       return {"error": str(e)}

A função valida o caminho do arquivo e usa csv.DictReader para analisar os dados do CSV em dicionários com os nomes das colunas como chaves. Ela lê as primeiras num_rows entradas, reseta o ponteiro do arquivo com seek(0) e conta o total de linhas. 

O dicionário de retorno inclui nomes de colunas, amostra de dados, contagem de linhas e tamanho do arquivo em kilobytes. O tratamento de erros garante retorno útil caso algo falhe.

Implementando o loop de execução da ferramenta

Com a ferramenta definida e implementada, você precisa de um loop que conduza a conversa entre o K2 e suas funções. Chamadas de ferramentas não são operação única. O K2 pode precisar de múltiplas iterações: chamar uma ferramenta, analisar os resultados, decidir se outra ferramenta é necessária e repetir. Isso requer um loop que gerencie o vai e vem até o K2 chegar à resposta final.

Aqui vai a implementação completa com um exemplo real:

from openai import OpenAI

client = OpenAI(
   base_url="https://openrouter.ai/api/v1",
   api_key=os.getenv("OPENROUTER_API_KEY")
)

messages = [
   {"role": "user", "content": "Analyze sample_employees.csv and tell me the average salary for Engineering department employees."}
]

Isso inicializa o client da OpenAI configurado para a API do OpenRouter e cria a lista inicial de mensagens com a solicitação do usuário sobre analisar salários de funcionários.

while True:
   response = client.chat.completions.create(
       model="moonshotai/kimi-k2-thinking",
       messages=messages,
       tools=tools,
       temperature=1.0
   )

   message = response.choices[0].message
   finish_reason = response.choices[0].finish_reason

   messages.append({
       "role": "assistant",
       "content": message.content,
       "tool_calls": message.tool_calls
   })

O loop principal envia o histórico da conversa ao K2 junto com as ferramentas disponíveis. Depois de extrair a resposta do assistente e a finish_reason, adiciona ao histórico para manter o contexto da conversa.

  if finish_reason == "tool_calls":
       for tool_call in message.tool_calls:
           function_name = tool_call.function.name
           arguments = json.loads(tool_call.function.arguments)

           if function_name == "analyze_csv":
               result = analyze_csv(**arguments)

           messages.append({
               "role": "tool",
               "content": json.dumps(result),
               "tool_call_id": tool_call.id
           })

   elif finish_reason == "stop":
       print(message.content)
       break

Quando o K2 solicita chamadas de ferramenta, executamos cada função com os argumentos fornecidos e adicionamos os resultados de volta à conversa com os respectivos valores de tool_call_id. Quando o K2 termina o raciocínio e retorna "stop", imprimimos a resposta final e saímos do loop.

Para este exemplo, crie um arquivo sample_employees.csv com dados de funcionários, incluindo nome, departamento e salário. Use cerca de 12 funcionários distribuídos entre Engineering, Marketing, Sales e HR para o teste. Ao rodar o código, o K2 normalmente chama analyze_csv() com num_rows definido para 12 ou mais para cobrir todos os dados, depois identifica os funcionários de Engineering e calcula o salário médio deles.

Saída:

Based on the CSV data, I found 5 Engineering employees in the sample:
- Alice Johnson: $95,000
- Carol White: $110,000
- Eve Davis: $88,000
- Iris Martinez: $102,000
- Kate Thomas: $92,000

The average salary for Engineering department employees is $97,400.

O tool_call_id em cada resposta vincula os resultados às suas respectivas chamadas. O K2 pode solicitar várias ferramentas em uma única resposta, então cada uma precisa do seu ID para casar corretamente. Preservar todo o histórico da conversa dá ao K2 o contexto necessário para um raciocínio coerente ao longo das chamadas de ferramentas.

Entendendo a orquestração independente do K2

Depois que você domina as chamadas básicas, a verdadeira força do K2 fica evidente: orquestração estendida. O K2 foi treinado para orquestrar ferramentas desde o início, não como um complemento. Isso muda como ele lida com tarefas de múltiplas etapas. A maioria dos modelos gerencia 20–50 chamadas sequenciais antes de o desempenho cair. O K2 mantém o raciocínio coerente em 200–300.

Essa capacidade é crucial para fluxos independentes em que o modelo decide, coleta informações, valida resultados e itera até resolver o problema. Pense em tarefas de pesquisa nas quais o K2 consulta bases, faz referências cruzadas, identifica lacunas, refina consultas e sintetiza tudo. Ou pipelines de dados que exigem validação em cada passo. Ou fluxos de debugging que testam múltiplas hipóteses.

Se seu caso de uso é “faça esta única ação”, a maioria dos modelos dá conta. Se é “continue até resolver”, a capacidade estendida de ferramentas do K2 vira o fator decisivo.

Construindo um app de chat comparativo multi-modelo

Você viu como o K2 Thinking lida com tarefas individuais com chamadas de ferramentas e raciocínio transparente. Agora vamos colocá-lo à prova contra os concorrentes. Você vai construir um app em Streamlit que consulta o Kimi K2 Thinking, o GPT-5 e o Claude Sonnet 4.5 com o mesmo prompt de uma só vez. A interface mostra as três respostas lado a lado para comparar como cada modelo ataca o mesmo problema.

Você encontra o script completo do aplicativo neste GitHub Gist. Se você só quer ver os resultados dos testes do app, pode pular esta seção. Os passos a seguir detalham o script (com mais de 200 linhas), então você pode deixar a leitura para quando puder acompanhar na prática. Dito isso, vamos lá.

Passo 1: setup do projeto e dependências

Este app comparativo exige acesso à API dos três modelos. Você vai precisar da sua conta no OpenRouter (já com US$ 5 em créditos gratuitos) e, opcionalmente, das chaves de API da OpenAI e da Anthropic. Os US$ 5 do OpenRouter devem bastar para testar os três modelos em várias consultas. Se você tiver apenas o OpenRouter, ainda dá para comparar o K2 com outros modelos disponíveis por lá.

Instale o Streamlit para a interface web e o SDK da Anthropic para acesso ao Claude:

pip install streamlit anthropic

Crie um arquivo chamado model_comparison_chat.py. Todo o aplicativo fica neste único arquivo. Comece com os imports:

import os
import time
from typing import Dict, List
from concurrent.futures import ThreadPoolExecutor, as_completed
from dotenv import load_dotenv
import streamlit as st
from openai import OpenAI
from anthropic import Anthropic

load_dotenv()

Passo 2: configurar conexões de API

Você já tem OPENROUTER_API_KEY no seu arquivo .env. Adicione as chaves do GPT-5 e do Claude:

OPENROUTER_API_KEY=your_openrouter_key  # Já configurada
OPENAI_API_KEY=your_openai_key           # Adicione aqui
ANTHROPIC_API_KEY=your_anthropic_key     # Adicione aqui

Pegue sua chave da OpenAI em platform.openai.com e a da Anthropic em console.anthropic.com. Para mais detalhes do setup do GPT-5, veja o guia do GPT-5. Para o Claude Sonnet 4.5, confira a visão geral do Claude Sonnet 4.5.

Inicialize os três clients:

KIMI_CLIENT = OpenAI(
   api_key=os.getenv("OPENROUTER_API_KEY"),
   base_url="https://openrouter.ai/api/v1"
)
GPT_CLIENT = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
CLAUDE_CLIENT = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))

Passo 3: criar funções helper para cada modelo

Crie uma função unificada que direcione para o modelo certo com base no nome. Isso mantém o código limpo e facilita adicionar mais modelos depois.

Comece com a chamada ao Kimi K2:

def call_model(model_name: str, messages: List[Dict], **kwargs) -> Dict:
   """Call any model with unified interface."""
   try:
       start_time = time.time()

       if model_name == "Kimi K2 Thinking":
           enable_thinking = kwargs.get("enable_thinking", True)

           completion = KIMI_CLIENT.chat.completions.create(
               model="moonshotai/kimi-k2-thinking",
               messages=messages,
               temperature=1.0,
               extra_body={"include_reasoning": True}
           )

           message = completion.choices[0].message
           content = message.content

           # Extrai o raciocínio do campo dedicado
           reasoning_content = None
           if enable_thinking and hasattr(message, 'reasoning') and message.reasoning:
               reasoning_content = message.reasoning

           return {
               "content": content,
               "reasoning_content": reasoning_content,
               "response_time": time.time() - start_time,
               "tokens_used": {
                   "input": completion.usage.prompt_tokens,
                   "output": completion.usage.completion_tokens,
                   "total": completion.usage.total_tokens
               },
               "error": None
           }

O GPT-5 segue outra abordagem com um endpoint de responses e um nível configurável de esforço de raciocínio:

      elif model_name == "GPT-5":
           reasoning_effort = kwargs.get("reasoning_effort", "medium")
           input_messages = [
               {"role": m["role"], "content": m["content"]}
               for m in messages
           ]

           response = GPT_CLIENT.responses.create(
               model="gpt-5",
               input=input_messages,
               reasoning={
                   "effort": reasoning_effort,
                   "summary": "auto"
               }
           )

           # Faz o parsing da estrutura da resposta
           reasoning_text = None
           content_text = ""

           for item in response.output:
               if item.type == "reasoning" and hasattr(item, "summary"):
                   summaries = [s.text for s in item.summary if hasattr(s, "text")]
                   reasoning_text = "\n\n".join(summaries) if summaries else None
               elif item.type == "message" and hasattr(item, "content"):
                   content_text += "".join(c.text for c in item.content if hasattr(c, "text"))

           return {
               "content": content_text,
               "reasoning_content": reasoning_text,
               "response_time": time.time() - start_time,
               "tokens_used": {
                   "input": getattr(response.usage, "input_tokens", 0),
                   "output": getattr(response.usage, "output_tokens", 0),
                   "total": getattr(response.usage, "total_tokens", 0)
               },
               "error": None
           }

O GPT-5 oferece quatro níveis de esforço de raciocínio: minimal, low, medium e high. A estrutura separa o raciocínio em blocos de resumo e o conteúdo em blocos de mensagem; você faz o parsing de ambos antes de retornar o mesmo dicionário padronizado do Kimi K2.

O Claude Sonnet 4.5 implementa um modo de thinking estendido com abordagem de orçamento de tokens:

    else:  # Claude Sonnet 4.5
           enable_thinking = kwargs.get("enable_thinking", True)
           params = {
               "model": "claude-sonnet-4-5",
               "max_tokens": 10000,
               "messages": messages
           }
           if enable_thinking:
               params["thinking"] = {
                   "type": "enabled",
                   "budget_tokens": 5000
               }

           message = CLAUDE_CLIENT.messages.create(**params)

           # Extrai blocos de conteúdo e de thinking
           content_text = ""
           thinking_text = None

           for block in message.content:
               if block.type == "thinking":
                   thinking_text = block.thinking
               elif block.type == "text":
                   content_text += block.text

           return {
               "content": content_text,
               "reasoning_content": thinking_text,
               "response_time": time.time() - start_time,
               "tokens_used": {
                   "input": message.usage.input_tokens,
                   "output": message.usage.output_tokens,
                   "total": message.usage.input_tokens + message.usage.output_tokens
               },
               "error": None
           }

   except Exception as e:
       return {
           "content": None,
           "reasoning_content": None,
           "response_time": 0,
           "tokens_used": {"input": 0, "output": 0, "total": 0},
           "error": f"{model_name} Error: {str(e)}"
       }

O Claude aloca um orçamento de tokens para o raciocínio interno antes de gerar a resposta final. A resposta contém múltiplos blocos de conteúdo que você percorre, separando thinking de texto. O tratamento de erros no final retorna a mesma estrutura padronizada com uma mensagem, garantindo que falhas na API não quebrem a interface.

Passo 4: construir a interface no Streamlit

Com a camada de API pronta, você pode montar a interface web. Configure a página do Streamlit primeiro:

def main():
   st.set_page_config(
       page_title="Multi-Model Comparison Chat",
       page_icon="🤖",
       layout="wide",
       initial_sidebar_state="expanded"
   )

   st.session_state.setdefault("messages", [])
   st.session_state.setdefault("model_responses", [])

O layout wide cria espaço para três colunas lado a lado. O session state preserva o histórico da conversa e as respostas quando o Streamlit reexecuta o script.

Adicione o título e os controles da barra lateral:

st.title("🤖 Multi-Model Comparison Chat")
   st.markdown("""
   Compare **Kimi K2 Thinking**, **GPT-5**, and **Claude Sonnet 4.5** side-by-side.
   All three models support reasoning modes - see how they approach problems differently.
   """)

   with st.sidebar:
       st.header("⚙️ Settings")

       st.subheader("Thinking Mode")
       kimi_thinking = st.checkbox("Enable Kimi K2 Thinking", value=True)
       gpt5_reasoning = st.selectbox(
           "GPT-5 Reasoning Effort",
           options=["minimal", "low", "medium", "high"],
           index=2
       )
       claude_thinking = st.checkbox("Enable Claude Thinking", value=True)

A barra lateral dá controle sobre os modos de raciocínio. Kimi K2 e Claude têm toggles binários. O GPT-5 traz quatro níveis por expor esse ajuste granular na API.

Abaixo dos controles de thinking, inclua um indicador de status das APIs para o usuário saber o que está conectado:

st.subheader("API Status")
       st.markdown(f"""
       - Kimi K2: {"✅" if os.getenv("OPENROUTER_API_KEY") else "❌"}
       - GPT-5: {"✅" if os.getenv("OPENAI_API_KEY") else "❌"}
       - Claude: {"✅" if os.getenv("ANTHROPIC_API_KEY") else "❌"}
       """)

Os checks aparecem quando as variáveis de ambiente estão definidas. O X vermelho indica que você precisa adicionar a chave correspondente ao seu .env.

Passo 5: implementar a lógica de comparação

Agora vem o núcleo da funcionalidade. Quando o usuário envia uma mensagem, você chama os três modelos em paralelo e mostra os resultados lado a lado.

def call_models_parallel(messages: List[Dict], selected_models: List[str],
                       kimi_thinking: bool, gpt5_reasoning: str,
                       claude_thinking: bool) -> Dict[str, Dict]:
   """Call multiple models in parallel."""
   model_kwargs = {
       "Kimi K2 Thinking": {"enable_thinking": kimi_thinking},
       "GPT-5": {"reasoning_effort": gpt5_reasoning},
       "Claude Sonnet 4.5": {"enable_thinking": claude_thinking}
   }

   with ThreadPoolExecutor(max_workers=3) as executor:
       futures = {
           executor.submit(call_model, m, messages, **model_kwargs[m]): m
           for m in selected_models if m in model_kwargs
       }
       return {futures[f]: f.result() for f in as_completed(futures)}

A função dispara três chamadas de API de uma vez e coleta os resultados conforme forem concluídos. Chamadas sequenciais levariam 15–30 segundos. A execução paralela reduz para 5–10 segundos, pois você espera apenas o mais lento, e não a soma dos três.

Integre a execução paralela na interface de chat:

   if prompt := st.chat_input("Ask a question to all models..."):
       st.session_state.messages.append({"role": "user", "content": prompt})

       with st.chat_message("user"):
           st.markdown(prompt)

       api_messages = [
           {"role": m["role"], "content": m["content"]}
           for m in st.session_state.messages
       ]

       with st.spinner("🤔 Models are thinking..."):
           responses = call_models_parallel(
               api_messages,
               ["Kimi K2 Thinking", "GPT-5", "Claude Sonnet 4.5"],
               kimi_thinking,
               gpt5_reasoning,
               claude_thinking
           )

       cols = st.columns(3)
       for idx, (model_name, response_data) in enumerate(responses.items()):
           with cols[idx]:
               st.markdown(f"### {model_name}")
               if response_data["reasoning_content"]:
                   with st.expander("🧠 Thinking Process", expanded=False):
                       st.markdown(response_data["reasoning_content"])
               st.markdown(response_data["content"])

Isso cria três colunas e exibe a resposta de cada modelo na sua respectiva coluna. O processo de raciocínio começa recolhido, para que o usuário veja primeiro as respostas finais. Ele pode expandir quando quiser inspecionar o raciocínio.

Passo 6: testar e refinar

Rode o app com:

streamlit run model_comparison_chat.py

Comece com um teste básico para confirmar que está tudo funcionando:

What is 2+2?

Os três modelos devem responder em poucos segundos. Isso verifica as conexões de API e confirma que a execução paralela está ativa. O app roda localmente, dando controle total sobre quando as APIs são chamadas. Cada consulta gera custo (aprox. US$ 0,01–0,05 por comparação entre três modelos, dependendo do tamanho da resposta), mas rodando localmente você decide quando gastar.

Testando o app com prompts complexos

Você construiu o app de comparação e viu funcionar com perguntas simples. Mas as diferenças reais entre os modelos aparecem quando você eleva a dificuldade. Para demonstrar, testei os três modelos com prompts complexos. Você pode rodar os mesmos testes no seu app para ver os resultados de perto. Aqui estão os principais insights.

Os prompts de teste

Escolhemos três desafios diferentes para testar habilidades de raciocínio distintas.

Teste 1: raciocínio matemático avançado

Um jardim retangular tem 24 pés de comprimento e 18 pés de largura. Um caminho de 2 pés de largura contorna o perímetro externo do jardim. Se Sarah planta flores no jardim com densidade de 4 flores por pé quadrado e decide adicionar pedras decorativas em 30% da área plantada (removendo essas flores), quantas flores permanecem? Além disso, qual é a área total (em pés quadrados) coberta pelo caminho?

Teste 2: raciocínio lógico em múltiplas etapas

Quatro amigos — Alice, Bob, Carol e David — precisam se alinhar para uma foto. As regras são:

1. Alice deve ficar ao lado de Bob

2. Carol não pode ficar nas pontas

3. David deve ficar à esquerda de Alice

Liste todos os arranjos válidos da esquerda para a direita.

Teste 3: geração de código com restrições

Escreva uma função em Python que verifique se uma string é um IPv4 válido, com estes requisitos:

1. Validar o formato (quatro octetos separados por pontos)

2. Cada octeto deve ser 0–255 (sem zeros à esquerda, exceto "0" isolado)

3. Rejeitar formatos inválidos (strings vazias, octetos a mais/menos, caracteres não numéricos)

4. Complexidade de tempo O(n), onde n é o tamanho da string

5. Incluir docstring completa com exemplos

6. Usar type hints para todos os parâmetros e retorno

7. Tratar edge cases (string vazia, None, caracteres especiais)

Explique também sua abordagem de validação e por que é O(n).

Resultados

Os três modelos resolveram todos os problemas corretamente, mas percorreram caminhos bem diferentes. Aqui vai o resumo de performance:

Teste

Modelo

Tempo (s)

Tokens

Resultado

Problema do jardim

Kimi K2

28,5

3.420

✓ Correto (1.209,6 flores, 184 ft²)

 

GPT-5

44,6

1.476

✓ Correto (1.209,6 flores, 184 ft²)

 

Claude

19,7

1.386

✓ Correto (1.210 flores, 184 ft²)

Arranjo para foto

Kimi K2

50,5

6.249

✓ Encontrou os 2 arranjos válidos

 

GPT-5

39,4

1.914

✓ Encontrou os 2 arranjos válidos

 

Claude

31,3

2.310

✓ Encontrou os 2 arranjos válidos

Validador IPv4

Kimi K2

192,6

5.245

✓ Solução O(n) funcional

 

GPT-5

73,7

4.233

✓ Solução O(n) funcional

 

Claude

43,1

3.330

✓ Solução O(n) funcional

Veja o que cada modelo faz nesse tempo.

A abordagem do Kimi K2

Ele explora e se questiona o tempo todo. No problema do jardim, visualizou o cenário, fez as contas e então disse “Espera, deixa eu conferir...” antes de seguir. No arranjo da foto, testou cada restrição uma a uma, mostrando o trabalho em cada possibilidade. 

O validador IPv4 levou mais de 3 minutos porque considerou casos de borda um a um, percorreu a prova de complexidade O(n) e verificou a lógica várias vezes. É como ver alguém pensar em voz alta, se corrigir e validar o raciocínio a cada passo.

A abordagem do GPT-5

É metódico e organizado. Decompôs o problema do jardim em seções claras, numerou os passos e os seguiu em ordem. No arranjo da foto, fez um passo a passo estruturado, posicionando as pessoas enquanto verificava as regras. 

O código veio com explicações claras e documentação bem organizada. Não se questiona tanto quanto o K2 e não corre tanto quanto o Claude. Você tem um equilíbrio entre transparência do raciocínio e objetividade.

A abordagem do Claude

É rápido. Identificou o caminho da solução rapidamente em cada teste e executou com precisão. No problema da foto, organizou por casos e percorreu cada um sem se alongar. O código IPv4 ficou limpo e bem documentado, indo direto ao ponto. 

O Claude mostra seu raciocínio, mas não se alonga nas verificações. A velocidade vem da confiança na abordagem e do mínimo de retrabalho.

Essas abordagens geram um trade-off claro. Escolha o K2 quando você precisa de raciocínio detalhado para aprendizado, debugging ou auditoria. Escolha o Claude quando a velocidade importa e você confia no resultado sem inspecionar as cadeias de raciocínio. Escolha o GPT-5 quando quiser um meio-termo entre a verbosidade do K2 e a agilidade do Claude.

Observação: encare os resultados com cautela — estes testes não cobrem todo o potencial dos três modelos.

Conclusão

Você configurou o Kimi K2 Thinking via OpenRouter, explorou suas capacidades de raciocínio, construiu fluxos com chamadas de ferramentas e criou um app de comparação para testá-lo contra o GPT-5 e o Claude. Os pontos fortes do K2 são a orquestração independente de ferramentas e o raciocínio transparente, ideais para fluxos complexos em que é necessário verificar as decisões do modelo.

A capacidade e o custo do K2 tornam isso viável. Ele executa longas sequências de chamadas de ferramentas em comparação a poucas dezenas na maioria dos concorrentes, e o campo reasoning_content expõe cada passo do pensamento. Com custo de saída de tokens por volta de 1/4 do GPT-5 e 1/6 do Claude, você pode rodar experimentos extensos sem estourar o orçamento.

O app de comparação que você construiu oferece evidências diretas desses trade-offs. Teste com seus próprios problemas e fluxos para criar intuição sobre quando o raciocínio detalhado do K2 compensa tempos de resposta maiores. Testes no mundo real, com seus casos específicos, vão revelar padrões que benchmarks genéricos não capturam.

Para se aprofundar, confira o tutorial de OpenRouter da DataCamp sobre como gerenciar múltiplos provedores de LLM, o guia do GPT-5 sobre níveis de esforço de raciocínio e o guia do Claude Sonnet 4 para o modo de thinking estendido.

Bexruz (Bex) Tuychiev

Autor

Bexruz (Bex) Tuychiev

Sou criador de conteúdo em ciência de dados há mais de 2 anos e um dos perfis com maior alcance no Medium. Gosto de escrever artigos detalhados sobre IA e ML, com uma pitada de sarcasmo — porque alguém precisa deixar o assunto menos monótono. Já publiquei mais de 130 artigos e um curso na DataCamp, com outro em andamento. Meu conteúdo já alcançou mais de 5 milhões de visualizações, e 20 mil pessoas passaram a me seguir no Medium e no LinkedIn. 

Temas

Relacionado

An avian AI exits its cage

blog

12 Alternativas de código aberto ao GPT-4

Tutorial

Guia de Introdução ao Ajuste Fino de LLMs