Curso
Kimi K2.6 é o modelo open-source mais recente da Moonshot AI, projetado para programação, execuções longas, uso de ferramentas e fluxos de trabalho com agentes. O modelo está disponível via Kimi.com, app Kimi, Kimi Code e API, tornando-o útil para criar aplicações práticas de IA que exigem raciocínio, chamadas de ferramentas e saídas estruturadas.
Neste tutorial, você vai construir o JobFit AI, um assistente de busca de vagas com IA que lê o currículo do candidato, procura vagas ativas, verifica páginas selecionadas e gera um relatório ranqueado de aderência às vagas. O Kimi K2.6 é ideal para este projeto porque oferece suporte a contexto longo, chamadas de ferramentas e modos com ou sem "pensamento" pela plataforma de API do Kimi.
O projeto usa:
- Kimi K2.6 como modelo de raciocínio
- Olostep para busca na web em tempo real e scraping de páginas de vagas
- pypdf para extrair texto do currículo do candidato
- OpenAI Agents SDK para criar o agente que usa ferramentas
- Gradio para transformar o fluxo em um app web simples
Ao final deste tutorial, você terá um app funcional que permite fazer upload do currículo, descrever preferências de vaga e gerar, em menos de um minuto, um relatório ranqueado com oportunidades relevantes.
Se você está começando com IA agentic, recomendo muito se inscrever na nossa trilha de habilidades AI Agents Fundamentals. Ela cobre os fundamentos de padrões de design, MCP e sistemas multiagente.
Pré-requisitos do tutorial
Antes de começar, garanta que você tem:
- Python 3.11+
- Uma chave de API do Kimi
- Ao menos US$ 5 de crédito na sua conta Moonshot AI
- Uma chave de API do Olostep
- Um currículo em PDF
- Conhecimentos básicos de Python
1. Configure seu ambiente Python
Crie uma nova pasta de projeto:
mkdir JobFit-AI
cd JobFit-AI
Depois, instale os pacotes necessários:
pip install gradio openai pypdf openai-agents
Os principais pacotes são:
-
gradio: cria a interface web -
openai: conecta a APIs compatíveis com OpenAI -
pypdf: extrai texto de arquivos PDF -
openai-agents: cria o agente de IA que usa ferramentas
Em seguida, crie contas e gere suas chaves de API:
- Crie uma conta gratuita no Olostep e gere uma chave de API no dashboard do Olostep. Você também pode assinar o Starter por US$ 9/mês, que inclui 5.000 requisições. É o suficiente para testar e colocar seu app no ar.
- Acesse a plataforma Kimi, adicione ao menos US$ 5 de crédito e gere sua chave de API.
Defina suas chaves de API do Kimi e do Olostep como variáveis de ambiente. A MOONSHOT_API_KEY é usada para acessar a API do Kimi K2.6, enquanto a OLOSTEP_API_KEY é usada para buscar e fazer scraping de páginas de vagas ativas.
Introdução aos agentes de IA
2. Defina a configuração do projeto
Abra o Jupyter Notebook, crie uma nova célula e adicione os imports necessários e a configuração do projeto.
import json
import os
import requests
from agents import Agent, AsyncOpenAI, ModelSettings, OpenAIChatCompletionsModel, RunConfig, Runner, function_tool, set_tracing_disabled
from IPython.display import Markdown, display
from pypdf import PdfReader
Agora, defina o nome do modelo, os endpoints de API, o número máximo de interações do agente, o caminho do currículo e as preferências de vaga.
KIMI_MODEL = "kimi-k2.6"
KIMI_BASE_URL = "https://api.moonshot.ai/v1"
OLOSTEP_SEARCH_URL = "https://api.olostep.com/v1/searches"
OLOSTEP_SCRAPE_URL = "https://api.olostep.com/v1/scrapes"
MAX_AGENT_TURNS = 25
cv_path = "abid-resume.pdf"
preferences = """
Remote data science, AI writer, or technical writer roles in AI, machine learning, data science, or cloud.
Prefer technical content, tutorials, developer education, research writing, and AI product storytelling.
""".strip()
set_tracing_disabled(True)
Os valores de KIMI_MODEL e KIMI_BASE_URL informam ao app que deve usar o Kimi K2.6 por meio do endpoint compatível com OpenAI da Moonshot AI. As URLs do Olostep são usadas para busca de vagas em tempo real e scraping de páginas.
A variável cv_path aponta para o PDF do currículo do candidato. Garanta que o PDF esteja salvo na mesma pasta do projeto, ou atualize o caminho se estiver em outro local.
A variável preferences informa ao agente que tipo de vagas buscar. Você pode ajustar conforme cargo-alvo, setor, localização, senioridade ou estilo de trabalho preferido.
Desativamos o tracing com set_tracing_disabled(True) porque o tracing é um recurso do OpenAI Agents SDK ativado por padrão. Como este projeto usa o Kimi em um endpoint compatível com OpenAI, desativar o tracing simplifica o setup local e evita problemas de tracing com um provedor terceirizado.
3. Conecte-se à API do Kimi K2.6
Agora, configure o cliente do Kimi usando a chave de API que você salvou como variável de ambiente.
kimi_client = AsyncOpenAI(
api_key=os.environ["MOONSHOT_API_KEY"],
base_url=KIMI_BASE_URL,
)
Isso cria o cliente da API do Kimi. A api_key é carregada de MOONSHOT_API_KEY e o base_url aponta para o endpoint compatível com OpenAI da Moonshot AI.
Em seguida, encapsule o modelo Kimi para que ele possa ser usado dentro do OpenAI Agents SDK:
kimi_model = OpenAIChatCompletionsModel(
model=KIMI_MODEL,
openai_client=kimi_client,
)
Agora defina as configurações do modelo:
model_settings = ModelSettings(
tool_choice="auto",
parallel_tool_calls=True,
extra_body={"thinking": {"type": "disabled"}},
)
A opção tool_choice="auto" permite que o agente decida quando chamar ferramentas. A opção parallel_tool_calls=True permite executar várias chamadas de ferramenta em paralelo quando necessário.
Também desativamos o modo de "pensamento" do Kimi usando extra_body={"thinking": {"type": "disabled"}}. Isso deixa a saída mais limpa e adequada a um relatório estruturado de aderência a vagas.
Por fim, crie a configuração de execução:
run_config = RunConfig(
workflow_name="JobFit AI Kimi Search",
tracing_disabled=True,
)
O workflow_name dá um rótulo claro a esta execução. Mantemos o tracing desativado aqui também, pois o projeto usa o Kimi via endpoint compatível com OpenAI, não o backend de tracing da OpenAI.
4. Extraia o texto do currículo do candidato
Agora, use o PdfReader para carregar o currículo do candidato e extrair o texto de cada página.
reader = PdfReader(cv_path)
cv_text = "\n".join(page.extract_text() or "" for page in reader.pages)[:12000]
print(f"Loaded {len(cv_text):,} characters from {cv_path}")
Este código lê o arquivo PDF definido em cv_path, extrai o texto de todas as páginas e combina em uma única string.
O limite [:12000] mantém o texto do currículo curto o bastante para caber confortavelmente no prompt do agente, ainda assim oferecendo contexto suficiente sobre a experiência, habilidades e preferências do candidato.
A saída será semelhante a isto, variando conforme o nome e o tamanho do seu arquivo:
Loaded 2,946 characters from abid-resume.pdf
Isso confirma que o currículo foi carregado com sucesso e mostra quantos caracteres foram extraídos do PDF.
5. Crie as instruções do agente
Agora, defina as instruções que controlam como o agente deve buscar, usar ferramentas e formatar o relatório final.
AGENT_INSTRUCTIONS = """
You are JobFit AI, a focused job-search agent.
Tool plan:
- Call search_jobs exactly once with limit 8.
- Read at most 3 direct job pages with read_job_page.
- After reading up to 3 pages, stop using tools and write the report.
- Search again only if the first search returns zero usable jobs.
- Avoid broad search pages, expired jobs, and LinkedIn unless no better source exists.
Report rules:
- Keep the report simple, clear, and practical.
- Use short bullets.
- Do not use em dashes.
- Do not use contractions.
- Do not add text before or after the report.
- End after the final Job Notes entry.
- Include at least 5 ranked jobs if the search results contain at least 5 usable jobs.
- If only 3 pages were scraped, use backup jobs from search results when they look usable.
- Every job must include a clickable Markdown link.
- Every job must have one apply decision: Apply, Maybe, or Do not apply.
Use exactly this Markdown structure:
# JobFit AI Report
## Best Match
- **Role:** <job title>
- **Company:** <company>
- **Apply decision:** Apply / Maybe / Do not apply
- **Fit score:** <score>/100
- **Link:** [Apply here](<job url>)
**Why this is the best match:**
- <specific reason>
- <specific reason>
- <specific reason>
## Ranked Jobs
| Rank | Role | Company | Apply? | Fit | Link |
| --- | --- | --- | --- | --- | --- |
| 1 | <role> | <company> | Apply / Maybe / Do not apply | <score>/100 | [Apply here](<url>) |
## Job Notes
### 1. <Role> at <Company>
- **Apply decision:** Apply / Maybe / Do not apply
- **Fit score:** <score>/100
- **Link:** [Apply here](<job url>)
**Why it fits:**
- <bullet>
- <bullet>
**Concerns:**
- <bullet>
- <bullet>
**Application angle:**
- <how the person should position their CV/application>
""".strip()
Essas instruções mantêm o agente focado. Elas limitam o fluxo a uma busca, até três leituras de páginas de vaga e uma estrutura fixa de relatório em Markdown.
As regras do relatório também deixam a saída mais escaneável ao exigir bullets curtos, links clicáveis, notas de aderência e uma decisão clara de candidatura para cada vaga.
6. Monte o prompt de execução
Depois de definir as instruções do agente, crie o template de prompt que será passado ao agente em cada execução.
RUN_PROMPT_TEMPLATE = """
Find current job postings for this candidate and rank them by fit.
Keep the run simple:
- one search
- up to three page reads
- final report
The final report must follow AGENT_INSTRUCTIONS exactly.
Use simple wording. Do not use em dashes. Do not use contractions.
Candidate CV:
{cv_text}
Preferences:
{preferences}
""".strip()
Este prompt combina, em tempo de execução, o texto do currículo do candidato e as preferências de vaga.
O placeholder cv_text é preenchido com o conteúdo extraído do currículo, enquanto preferences recebe as preferências definidas anteriormente. Juntos, eles dão contexto suficiente para o agente buscar vagas relevantes e ranqueá-las por aderência.
7. Adicione busca na web em tempo real com Olostep
Com as instruções e o prompt prontos, adicione duas ferramentas que permitem ao agente buscar na web e ler páginas de vagas usando o Olostep.
A primeira ferramenta busca listagens de vagas e retorna uma lista compacta de resultados.
@function_tool
def search_jobs(query: str, limit: int = 8) -> str:
"""Search the web for job listings and return compact JSON results."""
response = requests.post(
OLOSTEP_SEARCH_URL,
headers={"Authorization": f"Bearer {os.environ['OLOSTEP_API_KEY']}", "Content-Type": "application/json"},
json={"query": query},
timeout=60,
)
response.raise_for_status()
links = response.json().get("result", {}).get("links", [])[:limit]
results = [
{"title": item.get("title", "Untitled"), "url": item.get("url"), "description": item.get("description", "")}
for item in links
if isinstance(item, dict) and item.get("url")
]
return json.dumps(results, ensure_ascii=False)
O decorator @function_tool torna essa função Python disponível para o agente como uma ferramenta chamável.
Quando o agente precisa de listagens, ele chama search_jobs com uma query. A função envia a query ao endpoint de busca do Olostep, coleta os principais resultados e os retorna em JSON.
Cada resultado inclui:
- título da vaga
- URL da vaga
- breve descrição
A segunda ferramenta permite que o agente abra e leia uma página específica de vaga.
@function_tool
def read_job_page(url: str) -> str:
"""Scrape one job listing URL and return markdown text."""
response = requests.post(
OLOSTEP_SCRAPE_URL,
headers={"Authorization": f"Bearer {os.environ['OLOSTEP_API_KEY']}", "Content-Type": "application/json"},
json={"url_to_scrape": url, "formats": ["markdown"]},
timeout=120,
)
response.raise_for_status()
markdown = response.json().get("result", {}).get("markdown_content") or ""
return markdown[:8000]
Essa função envia uma URL de vaga ao endpoint de scraping do Olostep e retorna o conteúdo da página em Markdown.
O limite [:8000] mantém a página coletada curta o suficiente para o agente processar, capturando os detalhes mais úteis, como responsabilidades, requisitos e informações da empresa.
8. Crie o agente JobFit AI
Agora crie o agente e conecte todas as partes definidas: o modelo Kimi, as configurações, as ferramentas Olostep e as instruções do agente.
agent = Agent(
name="JobFit AI",
model=kimi_model,
model_settings=model_settings,
tools=[search_jobs, read_job_page],
instructions=AGENT_INSTRUCTIONS,
)
O objeto Agent é o controlador principal deste fluxo.
Ele usa:
kimi_modelcomo modelo de raciocíniomodel_settingspara controlar o uso de ferramentas e o comportamento da saídasearch_jobspara encontrar vagas ativasread_job_pagepara fazer scraping de páginas selecionadasAGENT_INSTRUCTIONSpara seguir exatamente as regras de busca e de relatório
A esta altura, o agente está pronto para buscar vagas, compará-las com o currículo do candidato e gerar um relatório estruturado do JobFit AI.
9. Execute o fluxo do agente
Agora execute o agente JobFit AI usando o texto extraído do currículo e as preferências definidas.
Primeiro, formate o prompt de execução:
prompt = RUN_PROMPT_TEMPLATE.format(cv_text=cv_text, preferences=preferences)
Isso preenche o template com o currículo do candidato e as preferências de vaga.
Depois, inicie a execução com streaming:
print("Starting agent run")
result = Runner.run_streamed(
agent,
prompt,
max_turns=MAX_AGENT_TURNS,
run_config=run_config,
)
O método Runner.run_streamed() inicia o fluxo do agente e transmite eventos em tempo real. Assim, você vê quando o agente chama uma ferramenta, recebe a saída e cria a mensagem final.
Agora, adicione o loop de streaming:
async for event in result.stream_events():
if event.type == "agent_updated_stream_event":
print(f"Agent: {event.new_agent.name}")
elif event.type == "run_item_stream_event":
item = event.item
if event.name == "tool_called":
raw = item.raw_item
tool_name = raw.get("name") if isinstance(raw, dict) else getattr(raw, "name", "tool")
arguments = raw.get("arguments") if isinstance(raw, dict) else getattr(raw, "arguments", "")
arguments = str(arguments).replace(chr(10), " ")[:500]
print(f"Tool call: {tool_name}")
if arguments:
print(f"Parameters: {arguments}")
elif event.name == "tool_output":
print(f"Tool output: {len(str(item.output)):,} chars")
elif event.name == "message_output_created":
print("Final message ready")
Esse loop imprime atualizações úteis de progresso enquanto o agente executa. Por exemplo, mostra quando o agente busca vagas, lê uma página ou finaliza o relatório.
Por fim, salve a saída final em uma variável chamada report:
report = result.final_output
globals()["report"] = report
print("Run complete")
print(f"Model responses: {len(result.raw_responses)}")
print(f"Run items: {len(result.new_items)}")
print(f"Final output: {len(str(report)):,} chars")
A variável report guarda o relatório final do JobFit AI, que você pode exibir, salvar ou usar no app Gradio.
A saída fica assim, por exemplo:
Starting agent run
Agent: JobFit AI
Tool call: search_jobs
Parameters: {"query":"remote data science writer technical writer AI machine learning content editor","limit":8}
Tool output: 2,445 chars
Tool call: read_job_page
Parameters: {"url":"https://www.indeed.com/q-data-science-writer-jobs.html"}
Tool output: 8,000 chars
Tool call: read_job_page
Parameters: {"url":"https://www.builtinnyc.com/jobs/remote/data-analytics/data-science"}
Tool output: 8,000 chars
Tool call: read_job_page
Parameters: {"url":"https://www.virtualvocations.com/jobs/q-data+scientist+remote+jobs/c-writing/d-336"}
Tool output: 5,075 chars
Final message ready
Run complete
Model responses: 5
Run items: 13
Final output: 5,931 chars
Isso confirma que o agente buscou vagas, leu páginas selecionadas e gerou o relatório final com sucesso.
10. Exiba o relatório JobFit gerado
Após a execução do agente, exiba o relatório final em formato Markdown.
display(Markdown(report))
Isso renderiza o relatório do JobFit AI diretamente no notebook, facilitando a leitura em comparação com texto puro.
O relatório inclui a melhor vaga, vagas ranqueadas, notas de aderência, decisões de candidatura, preocupações e ângulos de candidatura.

11. Transforme o fluxo em um app web com Gradio
Depois de testar o fluxo no notebook, você pode transformá-lo em um app web simples com Gradio. Crie um arquivo app.py e copie o código do arquivo JobFit-AI/app.py no GitHub para o seu arquivo local.
Execute o app com:
python app.py

Depois, abra o app no navegador pelo URL local exibido (neste caso, http://127.0.0.1:7860/):

O app Gradio oferece uma interface simples para gerar relatórios de aderência às vagas. Ele inclui:
- Campo de upload de PDF do currículo para o usuário enviar seu arquivo.
- Caixa de texto de preferências de vaga para descrever o tipo de oportunidade desejada (cargo, setor, localização, senioridade e temas preferidos).
- Botão Generate JobFit Report para iniciar o fluxo do agente.
- Log de progresso oculto que aparece durante a execução e mostra o que o app está fazendo (lendo o currículo, chamando ferramentas, recebendo saídas etc.).
- Área final em Markdown com o relatório ranqueado assim que o agente termina.
Nos bastidores, o app lê o currículo enviado, extrai o texto, envia currículo e preferências ao agente JobFit AI e busca vagas ativas com o Olostep. Ele lê até três páginas de vaga e retorna um relatório em Markdown com cargos ranqueados, notas de aderência, decisões de candidatura, preocupações e ângulos de candidatura.
12. Envie um currículo e gere um relatório
Agora teste o app web enviando um PDF de currículo e clicando em Generate JobFit Report.
Neste exemplo, enviei um currículo com cerca de três anos de experiência para ver se o app encontraria vagas relevantes conforme o perfil e as preferências do candidato. O relatório foi gerado em menos de um minuto.
Enquanto o app roda, o log de progresso mostra cada etapa do fluxo, incluindo:
- leitura do currículo
- extração de texto de cada página
- início da execução do agente
- chamada da ferramenta de busca de vagas
- retorno da saída da ferramenta

Quando a execução termina, o app exibe o relatório final em formato Markdown.
O relatório começa com a melhor correspondência, seguido por uma tabela de vagas ranqueadas. Depois, traz notas detalhadas para cada cargo, incluindo nota de aderência, decisão de candidatura, motivos da aderência, possíveis preocupações e um ângulo de candidatura.

Neste exemplo, o resultado principal foi uma vaga de Senior Data Science Writer na NannyML. Como a vaga combinava com a bagagem do candidato em ciência de dados, escrita técnica e conteúdo de IA, parecia uma ótima opção.
Você pode clicar no link Apply here no relatório para abrir a página da vaga e revisar a descrição completa antes de decidir se vai se candidatar.

Observação: se tiver qualquer problema ao executar o projeto localmente, confira o repositório no GitHub: kingabzpro/JobFit-AI. Ele inclui o notebook, o arquivo app.py e instruções de setup para instalar dependências e rodar o projeto localmente.
Considerações finais
O JobFit AI usa Kimi K2.6, Olostep e o OpenAI Agent SDK para resolver dois problemas comuns de quem está mudando de área ou procurando vagas ativamente.
O primeiro problema é saber onde se candidatar. Existem muitos job boards, plataformas e páginas de carreira, mas nem sempre é claro quais vagas valem seu tempo. Este app ajuda a filtrar usando o currículo e as preferências do candidato para encontrar oportunidades mais alinhadas à sua experiência.
O segundo problema é lidar com excesso de listagens. Em vez de checar manualmente cada site, o agente busca vagas ativas, lê páginas selecionadas e cria um relatório estruturado com melhor vaga, cargos ranqueados, notas de aderência, preocupações e ângulos de candidatura. Assim fica mais fácil focar no que realmente vale a pena.
A API do Kimi K2.6 também teve ótimo desempenho nesse fluxo com agente: foi rápida, confiável e seguiu bem as instruções estruturadas. Nos testes, quando o agente podia usar até 25 turnos, ele buscou e fez scraping de várias páginas com mais profundidade, mas a execução levou cerca de cinco minutos. Para equilibrar qualidade e velocidade, restringi a uma busca e até três leituras de página, o que ajudou a gerar o relatório em menos de um minuto.
Você pode melhorar a qualidade do relatório aumentando o número de passos, resultados de busca ou páginas lidas. Por exemplo, se elevar o limite do agente para 30 turnos e permitir ler mais páginas, o relatório sai mais profundo, com mais cargos e recomendações mais fortes — mas isso também aumenta o tempo de execução e o uso de API.
Se você tem interesse em criar ferramentas agentic semelhantes, confira outros tutoriais de API sobre como construir:
Perguntas frequentes sobre o Kimi K2.6
O que é o Kimi K2.6?
Kimi K2.6 é o modelo agentic de pesos abertos mais recente da Moonshot AI, lançado em abril de 2026. Ele é baseado em uma arquitetura Mixture-of-Experts (MoE) com ~1 trilhão de parâmetros totais, ativando 32 bilhões por passo de inferência, e é otimizado para programação, uso de ferramentas e tarefas de agentes de longo horizonte.
Qual é a janela de contexto do Kimi K2.6?
O Kimi K2.6 oferece uma janela de contexto de 262.144 tokens (256K). Isso o torna ideal para processar bases de código inteiras, documentos longos ou execuções multiestágio de agentes em uma única sessão.
Quanto custa o Kimi K2.6 via API?
Diretamente pela API do Kimi, tokens de entrada custam US$ 0,95/1M (cache miss) e US$ 0,16/1M (cache hit), e a saída custa US$ 4,00/1M tokens. Provedores terceirizados oferecem tarifas parcialmente menores, começando em torno de US$ 0,60/1M para entrada e US$ 2,80/1M para saída.
O Kimi K2.6 tem modo de pensamento?
Sim, o Kimi K2.6 suporta um modo de "pensamento" (raciocínio estendido) e um modo instantâneo (respostas mais rápidas, sem pensamento). No tutorial, o modo de pensamento é explicitamente desativado via extra_body={"thinking": {"type": "disabled"}} para manter as saídas mais limpas e rápidas.
Como o Kimi K2.6 se sai em benchmarks de programação com agentes?
O Kimi K2.6 marca 80,2 no SWE-Bench Verified, tornando-se o modelo open-source mais forte nesse nível, com desempenho logo atrás de modelos fechados como Claude Opus 4.6 (80,8%) e Gemini 3.1 Pro (80,6%). No BrowseComp, ele marca 83,2, subindo para 86,3 com o modo Agent Swarm, ficando atrás apenas do GPT-5.5 Pro (90,1) e do inédito Claude Mythos Preview (86,9).
Sou um cientista de dados certificado que gosta de criar aplicativos de aprendizado de máquina e escrever blogs sobre ciência de dados. No momento, estou me concentrando na criação e edição de conteúdo e no trabalho com modelos de linguagem de grande porte.




