Pular para o conteúdo principal
O QUE VOCÊ DEVE TER EM MÃOS
  1. Um link de convite do cluster enviado a você pelo administrador do seu cluster. Ele torna você o proprietário de uma organização totalmente nova.
  2. Este guia tudo o que você precisa para ir desse link a uma integração funcional.
Links rápidos

Bem-vindo ao MKA1

MKA1 é uma plataforma para criar aplicações de IA. Ela dá à sua equipe um único gateway para grandes modelos de linguagem, além dos blocos de construção de alto nível de que produtos reais precisam: agentes, conversas armazenadas, memória de longo prazo, recuperação de documentos (RAG), ferramentas e servidores MCP, prompts, habilidades, guardrails, fala e avaliações. Você trabalha com o MKA1 por meio de duas superfícies que compartilham as mesmas contas, equipes e recursos:
  • O Console - um painel web para criar e inspecionar tudo manualmente: executar prompts no Playground, salvar agentes, indexar arquivos, gerar chaves de API, gerenciar sua organização e equipes. O console fica no endereço do seu cluster (por exemplo platform.mka1.com).
  • A API e os SDKs - as mesmas capacidades via HTTPS, chamadas do seu próprio código pelo SDK TypeScript, Python ou C#, pela CLI mka1 ou por curl puro. É assim que sua aplicação conversa com o MKA1 em produção.
Este guia percorre todo o caminho em ordem. Os passos 1–7 levam você do link de convite até sua primeira requisição bem-sucedida; as seções seguintes percorrem cada bloco de construção com exemplos prontos para copiar e colar.

Antes de começar

Você só precisa de duas coisas para começar, e já tem ambas:
  1. Um link de convite do cluster. Seu administrador criou um convite no cluster e enviou o link para você. Abri-lo torna você o proprietário de uma nova organização dentro daquele cluster.
  2. Este guia. Ele leva você do convite a uma integração funcional com o SDK.
Nada para instalar de antemão. O console roda no seu navegador, e você só instala um SDK quando estiver pronto para escrever código. O caminho abaixo leva cerca de 15 minutos:
Configuração em 15 minutos
  • Passo 1 Aceite seu convite do cluster e crie sua organização.
  • Passo 2 Oriente-se no console.
  • Passo 3 Convide colegas e crie uma equipe (as chaves de API vivem nas equipes).
  • Passo 4 Crie uma chave de API.
  • Passo 5 Instale um SDK.
  • Passo 6 Autentique suas requisições.
  • Passo 7 Faça sua primeira requisição.

Passo 1 · Aceite seu convite do cluster

Abra o link de convite do cluster que seu administrador enviou. Ele carrega um token de uso único e leva você à página Set up your organization. Um convite de cluster é um convite de proprietário - aceitá-lo cria uma nova organização e define você como o proprietário.

Faça isto

  1. Abra o link de convite. A página valida o token e mostra um selo de Owner invite (e uma data de expiração, se houver). Se disser que o convite está indisponível, o token de convite expirou ou foi revogado. Peça um link novo ao seu administrador.
  2. Nomeie sua organização. Digite um nome como Acme Inc. Um slug de URL do workspace é gerado para você (p. ex. acme-inc); expanda Customize se quiser editá-lo. Apenas letras minúsculas, números e hífens.
  3. Escolha como entrar. Crie uma conta com e-mail e senha, ou continue com o Google. Se o convite estava vinculado ao seu endereço de e-mail, esse endereço aparece pré-preenchido e travado.
  4. Verifique seu e-mail. Se você se cadastrou com senha, o MKA1 envia um e-mail de verificação. Clique no link para confirmar; você então cai direto na sua nova organização.
  5. Você está dentro. Você chega ao console como proprietário da sua organização, pronto para convidar colegas e criar chaves.
Agora você é o proprietário da organizaçãoO proprietário tem controle total. Uso, membros, equipes e configurações. Todos os demais que você trouxer serão administradores ou membros (coberto no Passo 3). Se você já estava conectado ao MKA1 com um e-mail diferente do convite, saia primeiro: os convites são vinculados a um endereço específico.

Passo 2 · Conheça o console

Reserve um minuto para se orientar. A barra lateral esquerda agrupa cada superfície em Access, LLM, Agents e Admin. Veja para que serve cada seção. Você usará várias delas nos próximos passos. Configurações de organizações no console do MKA1

Access

SeçãoO que você faz lá
API KeysCrie e gerencie as chaves de autenticação que seu código usa (Passo 4).
OrganizationsGerencie membros, papéis, equipes e convites pendentes.
TeamsCrie equipes e gerencie seus membros. Cada chave de API é limitada a uma equipe.
Service AccountsCrie identidades não humanas para produção e vincule-as a equipes.

LLM

SeçãoO que você faz lá
PlaygroundConverse com modelos interativamente. Transmita respostas em tempo real. Configure ferramentas, habilidades e guardrails, com um painel de configurações avançadas.
ModelsExplore os modelos disponíveis pelo gateway, agrupados por modalidade, com detalhes de registro para administradores.
ResponsesCrie respostas individuais e inspecione histórico armazenado, saída, chamadas de ferramentas e uso de tokens.
EvalsMonte suítes de avaliação e lance execuções duráveis para medir e comparar a qualidade dos modelos.
ConversationsCrie e inspecione o estado de conversas armazenadas, pesquisável por metadados.
Text to speechSintetize fala a partir de texto e inspecione o histórico de geração.
Speech to textTranscreva áudio para texto e inspecione o histórico de transcrições.
PromptsCrie, versione e reverta modelos de prompt reutilizáveis com {{variables}}.
GuardrailsConfigure políticas de palavras banidas, injeção de prompt e vazamento, e depois teste-as.
FilesEnvie, inspecione e exclua arquivos usados por fluxos de trabalho LLM.
Vector StoresCrie lojas, anexe arquivos e pesquise trechos de documentos indexados para recuperação (RAG).
FeedbackRegistre e atualize feedback humano sobre a saída do modelo; consulte registros ou exporte um snapshot em parquet.
SkillsEnvie, versione e gerencie habilidades reutilizáveis, cada uma empacotada atrás de um manifesto SKILL.md.
MCP ServersRegistre definições de servidores MCP que agentes salvos podem anexar como ferramentas; os segredos ficam em Credentials.
CredentialsArmazene os segredos de que seus servidores MCP e integrações precisam, separados de suas definições.

Agents

SeçãoO que você faz lá
QuickstartColoque um agente salvo no ar rapidamente - escolha um modelo, escreva instruções, anexe ferramentas e execute-o.
AgentsCrie e execute agentes salvos que agrupam um modelo, instruções, ferramentas e metadados.
SessionsRastreie e depure execuções de agentes. Reproduza a transcrição e percorra os eventos brutos.
Memory StoresExplore as memórias em markdown que os agentes leem e escrevem entre execuções.

Admin

SeçãoO que você faz lá
AuditRevise requisições de auditoria do gateway, monte casos e exporte respostas (administradores do cluster veem todas as organizações; administradores de organização veem a atividade da sua org).
AlertsRegistre endpoints de webhook que disparam quando respostas falham, com escopo de cluster, organização ou equipe.
Model RegistryAdicione e configure os modelos personalizados disponíveis no registro da sua organização.
PricingMantenha o livro de preços de modelos: moeda do cluster, preços por modelo e substituições por organização (apenas administradores do cluster).
BudgetsCrie orçamentos de gasto da org com limiares de alerta/bloqueio e status de gasto ao vivo (orçamentos de chaves de API são geridos pelo administrador do cluster).
UsageRevise o uso de tokens, requisições e armazenamento da org e equipe ativas.
Fine-tuningLance e monitore execuções de fine-tuning e checkpoints (em breve).
ServingImplante modelos no cluster: implantações com escalonamento e reversão, registros de modelos, imagens, trabalhos de fine-tuning, aceleradores e segredos (administradores).

Passo 3 · Convide sua equipe e organize o acesso

Página de detalhe de equipe em Access → Teams O acesso ao MKA1 é organizado como uma hierarquia simples: organização → equipes → membros, com papéis controlando o que cada pessoa pode fazer e contas de serviço representando os chamadores não humanos.

A organização e seu proprietário

Quando você aceita o convite do cluster, torna-se o proprietário da sua organização. O proprietário tem controle total: métricas de uso, membros, equipes e configurações. Todos os demais que você trouxer são administradores ou membros:
PapelO que podem fazer
ProprietárioControle total da organização - uso, membros e configurações.
AdministradorGerencia membros, equipes e chaves de API em toda a organização.
MembroAcessa os modelos, arquivos e chaves de API da sua equipe.

Equipes

Dentro de uma organização você cria equipes, e os membros pertencem a uma ou mais delas. As equipes são onde o trabalho e o acesso realmente vivem: chaves de API, agentes e outros recursos são limitados a uma única equipe. Uma chave gerada em uma equipe concede acesso apenas aos recursos daquela equipe. Remover alguém (ou uma conta de serviço) de uma equipe revoga o acesso que vinha com ela, e as chaves ligadas àquela equipe param de funcionar. Isso torna as equipes a fronteira natural para separar projetos, ambientes ou unidades de negócio. Gerencie-as em Access → Teams, onde você pode criar uma equipe e gerenciar sua lista simples de membros.

Convidando colegas

Diálogo de convidar pessoas com seleção de papel e equipes Para adicionar uma pessoa, envie a ela um convite de organização por e-mail. Você pode fazer isso navegando até Access → Organizations e clicando em Invite people no canto superior direito. Compartilhe o link gerado que abre a página Accept invite, que mostra a organização, quem convidou, o papel que a pessoa receberá e quando o convite expira. O que a pessoa faz para aceitar depende do seu estado:
  • Ainda sem conta (Este é o cenário mais provável) - ela se cadastra (e-mail/senha ou Google) com o e-mail convidado, verifica-o e volta ao convite para concluir a entrada.
  • Já conectada com o e-mail convidado - um clique em Accept & join a adiciona à organização.
  • Conectada com um e-mail diferente - ela é orientada a trocar primeiro para a conta convidada, já que os convites são vinculados a um endereço específico.
Convites podem expirar ou ser revogados, então envie um link novo se alguém relatar um link morto.

Contas de serviço para produção

Para sistemas de produção, executores de CI, serviços de backend e trabalhos agendados, use uma conta de serviço em vez das credenciais de uma pessoa. Uma conta de serviço é uma identidade de máquina não humana que você vincula a uma ou mais equipes e para a qual gera chaves de API. Você pode criar uma navegando até Access → Service accounts e clicando em New service account no canto superior direito. Como as chaves herdam o escopo da equipe, desvincular uma conta de serviço de uma equipe (ou excluí-la) interrompe imediatamente todas as chaves geradas para ela naquela equipe, dando a você um interruptor de desligamento limpo para credenciais de produção.

Passo 4 · Crie uma chave de API

Formulário de nova chave de API com etapas de identidade, vinculação de escopo e permissões Uma chave de API é a credencial que seu código envia em cada requisição. No console, abra Access → API Keys e clique em Create API key. O formulário percorre quatro etapas.

1 · Identidade

Nomeie a chave (p. ex. Production gateway) e escolha o principal como o qual ela age: My user (usa seu papel na org e a equipe selecionada) ou uma Service account (uma identidade não humana dedicada. Contas de serviço são recomendadas para casos de uso em produção).

2 · Vinculação de escopo

Escolha a organização e a equipe às quais a chave pertence. Uma chave só pode ver recursos dentro daquela única equipe naquela única org — então escolha a equipe cujos modelos, arquivos e agentes esta chave deve alcançar. (Se você ainda não tem equipe, crie uma primeiro em Access → Teams; as chaves precisam ser limitadas a uma equipe.)

3 · Permissões (scopes)

Escolha quais recursos a chave pode ler e escrever. Os scopes são verificados em cada requisição. Use um preset para avançar rápido e depois ajuste:
  • Standard - os scopes cotidianos de leitura/escrita para criar apps (respostas, conversas, arquivos, lojas vetoriais, prompts, agentes e mais).
  • Read-only - todos os scopes read: e nada mais.
  • All - todos os scopes, incluindo os exclusivos de administrador. Disponível apenas para proprietários e administradores da org.
Alguns scopes são exclusivos de administrador (fine-tuning, registro de modelos, guardrails, busca, lotes, sandbox, autorização refinada) e aparecem apenas se você for proprietário ou administrador. Conceda o conjunto mais restrito de que a chave realmente precisa.

4 · Limite de taxa (opcional)

Opcionalmente limite a chave a um número máximo de requisições por minuto, hora ou dia. O gateway aplica o limite e retorna 429 Too Many Requests antes de a requisição chegar a um modelo, então chamadas acima do limite não custam nada.
Copie o segredo agora — ele é mostrado apenas uma vezQuando você clica em Create key, o segredo completo é revelado uma única vez. Copie-o imediatamente e guarde-o em um lugar seguro (um gerenciador de segredos ou seu .env). Se você o perder, não poderá vê-lo novamente. Regenere a chave para obter um novo segredo. Trate-o como uma senha: nunca o envie para o controle de versão nem o exponha em código de navegador.

Passo 5 · Instale um SDK

O MKA1 oferece SDKs para TypeScript, Python e C#, além de uma CLI mka1 independente. Cada cliente se autentica com sua chave de API como token Bearer e aponta para o gateway da API. O gateway hospedado padrão é https://apigw.mka1.com.
Clusters privadosEm uma implantação privada, substitua https://apigw.mka1.com pelo host do gateway do seu próprio cluster em tudo abaixo. Passe-o como a opção serverURL / server_url / serverUrl do SDK, ou configure-o uma vez para a CLI. Seu administrador pode informar a URL do gateway (é a contraparte de API do endereço do seu console).

TypeScript - @meetkai/mka1

O SDK TypeScript é instalado a partir do registro de pacotes npm:
npm add @meetkai/mka1
import { SDK } from '@meetkai/mka1';

const mka1 = new SDK({ bearerAuth: 'Bearer YOUR_API_KEY' });

Python - meetkai-mka1

Requer Python 3.10 ou mais recente:
pip install meetkai-mka1
from meetkai_mka1 import SDK

sdk = SDK(bearer_auth="Bearer YOUR_API_KEY")

C# - MeetKai.MKA1

using MeetKai.MKA1;

var sdk = new SDK(bearerAuth: "Bearer YOUR_API_KEY");

CLI - mka1

Binários pré-compilados são servidos em downloads.mka1.com. No macOS (Apple silicon):
curl -fsSL https://downloads.mka1.com/darwin/mka1_darwin_arm64-latest.tar.gz \
  | tar -xz -C /usr/local/bin mka1
mka1 version
Troque arm64 por x86_64 no Intel; pacotes .deb/.rpm e um .zip para Windows estão vinculados no guia da CLI. Depois configure sua chave e execute qualquer comando:
export MKA1_BEARER_AUTH="Bearer YOUR_API_KEY"
mka1 llm models list
Para uma configuração persistente que armazena segredos no chaveiro do seu SO, veja autenticar a CLI.

Passo 6 · Autentique suas requisições

Cada requisição carrega sua chave de API como token bearer no cabeçalho Authorization. Para apps multiusuário do lado do servidor você também envia X-On-Behalf-Of para identificar para qual dos seus usuários finais a requisição é.
Authorization: Bearer YOUR_API_KEY

Quando enviar X-On-Behalf-Of

Defina X-On-Behalf-Of com um identificador estável do seu próprio sistema (p. ex. user_123) sempre que seu servidor estiver agindo por um usuário final específico. Isso mantém as requisições, arquivos, memória e uso desse usuário corretamente atribuídos. Use um ID que não muda. Nunca use um e-mail ou nome de exibição.
  • Somente Authorization - seu próprio fluxo de trabalho de backend, não vinculado a nenhum usuário final.
  • Authorization + X-On-Behalf-Of - seu servidor agindo por um dos seus usuários finais; o uso e os recursos ficam associados a ele.
import type { ResponseObject } from '@meetkai/mka1/models/components';

const result = await mka1.llm.responses.create({
  xOnBehalfOf: 'user_123',
  responsesCreateRequest: {
    model: 'meetkai:functionary-pt',
    input: 'Resuma este ticket de suporte.',
  },
}) as ResponseObject;
console.log(result.outputText);
response = sdk.llm.responses.create(
    model="meetkai:functionary-pt",
    input="Resuma este ticket de suporte.",
    x_on_behalf_of="user_123",
)

Emita tokens de curta duração (opcional)

Quando um serviço downstream ou um cliente de navegador precisa chamar o MKA1 sem possuir sua chave de API, troque a chave por um JWT de curta duração via POST /api/v1/authentication/api-keys/exchange-token, e então use esse JWT como token bearer. Veja o guia de autenticação e o aprofundamento.
curl -X POST https://apigw.mka1.com/api/v1/authentication/api-keys/exchange-token \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{ "audience": "https://your-app.example.com", "externalUserId": "user_123" }'
# → { "token": "<jwt>" } — depois envie Authorization: Bearer <jwt>
const jwt = await mka1.auth.apiKeys.exchangeToken({
  requestBody: {
    audience: 'https://your-app.example.com',
    externalUserId: 'user_123',
  },
});

// jwt.token é o JWT de curta duração — use-o como bearer
const asEndUser = new SDK({ bearerAuth: `Bearer ${jwt.token}` });
jwt = sdk.auth.api_keys.exchange_token(body={
    "audience": "https://your-app.example.com",
    "external_user_id": "user_123",
})

# jwt.token é o JWT de curta duração — use-o como bearer
as_end_user = SDK(bearer_auth=f"Bearer {jwt.token}")

Passo 7 · Faça sua primeira requisição

Com uma chave em mãos, gere sua primeira resposta. Usar model: 'auto' deixa o gateway escolher o modelo certo para a requisição. Uma resposta concluída no console com entrada, raciocínio e saída
mka1 llm responses create \
  --model meetkai:functionary-pt \
  --input '"Qual é a capital da França?"' \
  -H 'X-On-Behalf-Of: <end-user-id>'
import { SDK } from '@meetkai/mka1';
import type { ResponseObject } from '@meetkai/mka1/models/components';

const mka1 = new SDK({ bearerAuth: 'Bearer YOUR_API_KEY' });

const result = await mka1.llm.responses.create({
  responsesCreateRequest: {
    model: 'meetkai:functionary-pt',
    input: 'Qual é a capital da França?',
  },
}) as ResponseObject;
console.log(result.outputText);
from meetkai_mka1 import SDK

sdk = SDK(bearer_auth="Bearer YOUR_API_KEY")

res = sdk.llm.responses.create(
    model="meetkai:functionary-pt",
    input="Qual é a capital da França?",
)
curl https://apigw.mka1.com/api/v1/llm/responses \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data '{ "model": "meetkai:functionary-pt", "input": "Qual é a capital da França?" }'
Esse é o caminho completo a partir do zero. Você tem uma organização, uma equipe, uma chave de API, um SDK e uma requisição funcionando. O restante deste guia percorre os blocos de construção que você montará em aplicações reais.

Construa com a plataforma

Tudo abaixo pode ser chamado com a chave de API que você acabou de criar. Cada seção se baseia nos guias oficiais em docs.mka1.com. Siga os links incorporados para a referência completa.

Gerar respostas (a chamada principal)

Playground com o painel de configurações avançadas aberto O recurso Responses é como você gera texto com o MKA1. Passe uma string simples em input para um prompt de turno único; o resultado inclui o texto gerado em output_text. Use auto_routing: true para deixar o gateway escolher o modelo certo por você.

Chamada básica

import { SDK } from '@meetkai/mka1';

const mka1 = new SDK({
  bearerAuth: `Bearer ${YOUR_API_KEY}`,
});

const result = await mka1.llm.responses.create({
  xOnBehalfOf: '<end-user-id>',
  responsesCreateRequest: {
    model: 'meetkai:functionary-pt',
    input: 'Escreva um resumo de uma frase da API do MKA1.',
  },
});
from meetkai_mka1 import SDK

sdk = SDK(bearer_auth="Bearer YOUR_API_KEY")

res = sdk.llm.responses.create(
    model="meetkai:functionary-pt",
    input="Escreva um resumo de uma frase da API do MKA1.",
    http_headers={"X-On-Behalf-Of": "<end-user-id>"},
)
Passe X-On-Behalf-Of quando estiver agindo por um usuário final; omita-o caso contrário.

O que auto_routing faz

auto_routing é um sinalizador de requisição opcional, separado do alias de modelo auto. Quando você define auto_routing: true, o gateway pontua a complexidade da requisição e a roteia para o melhor irmão quantizado, MoE ou denso dentro da família de modelos que você solicitou. Ele nunca troca para um modelo não relacionado, e recorre ao modelo que você pediu se aquela família não tiver um irmão compatível. A pontuação é aditiva. Ela sobe com o comprimento do prompt, muitas ferramentas ou ferramentas de alta agência (p. ex. code_interpreter, mcp), tool_choice: 'required', saída estruturada, um max_output_tokens grande, contexto de múltiplos turnos e sinais de raciocínio complexo no texto (debug, refactor, plan, incident, code); ela desce com prompts curtos e tarefas simples reconhecidas (traduzir, resumir, classificar, extrair). O total escolhe o nível. Pontuações mais altas roteiam para dense, médias para moe, baixas para quantized. Um reasoning.effort correspondente é definido (de minimal até xhigh) a menos que você mesmo tenha definido o esforço. Assim, um curto “resuma isto” é roteado para quantized com esforço minimal, enquanto um longo relato de incidente é roteado para dense com esforço high (ou xhigh). Sempre que o roteamento é executado, os metadados da resposta registram routed_model - a variante realmente usada. Adicione auto_routing_debug: true para obter também um campo de metadados auto_routing_debug: uma string JSON compacta com o modelo solicitado e o roteado, o nível escolhido, o esforço de raciocínio, a pontuação e as razões por trás da decisão. Ele é registrado mesmo quando nenhuma variante irmã está disponível, então é útil para validar o comportamento do rollout. Deixe este campo desligado para o tráfego normal de produção.

Transmita texto conforme ele é gerado

Defina stream: true para receber eventos enviados pelo servidor em vez de esperar a resposta completa. Use isso para renderizar a saída parcial conforme ela chega.
import { CreateAcceptEnum } from '@meetkai/mka1/sdk/responses';
import { EventStream } from '@meetkai/mka1/lib/event-streams';

const stream = await mka1.llm.responses.create({
  responsesCreateRequest: {
    model: 'meetkai:functionary-pt',
    input: 'Escreva três itens de notas de versão para nossa atualização de docs.',
    stream: true,
  },
}, { acceptHeaderOverride: CreateAcceptEnum.textEventStream });

if (stream instanceof EventStream) {
  for await (const event of stream) {
    if (event.data.type === 'response.output_text.delta') {
      process.stdout.write(event.data.delta);
    }
  }
}
stream = sdk.llm.responses.create(
    model="meetkai:functionary-pt",
    input="Escreva três itens de notas de versão para nossa atualização de docs.",
    stream=True,
)

for event in stream:
    if event.data.type == "response.output_text.delta":
        print(event.data.delta, end="", flush=True)

Entrada multimodal (imagem + texto)

A API de Responses aceita texto, imagens, áudio e arquivos em uma única requisição. Use um array input estruturado de itens de mensagem, onde content é um array que mistura input_text e input_image (imagem via URL, URI de dados base64 ou um file_id enviado).
const result = await mka1.llm.responses.create({
  xOnBehalfOf: '<end-user-id>',
  responsesCreateRequest: {
    model: 'openai:gpt-4.1', // com visão — 'auto' descarta imagens hoje
    input: [
      {
        type: 'message',
        role: 'user',
        content: [
          { type: 'input_text', text: 'Descreva o que você vê nesta imagem.' },
          {
            type: 'input_image',
            imageUrl: 'https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg',
          },
        ],
      },
    ],
  },
});
res = sdk.llm.responses.create(
    model="openai:gpt-4.1",  # com visão — 'auto' descarta imagens hoje
    input=[
        {
            "type": "message",
            "role": "user",
            "content": [
                {"type": "input_text", "text": "Descreva o que você vê nesta imagem."},
                {
                    "type": "input_image",
                    "image_url": "https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg",
                },
            ],
        },
    ],
    x_on_behalf_of="<end-user-id>",
)

Respostas em segundo plano

Para trabalho de longa duração, defina background: true (com stream: false) para obter imediatamente uma resposta enfileirada, e depois recupere o resultado fazendo polling com mka1.llm.responses.get(...) ou por streaming. Veja o guia de respostas em segundo plano.
import type { ResponseObject } from '@meetkai/mka1/models/components';

const queued = await mka1.llm.responses.create({
  responsesCreateRequest: {
    model: 'meetkai:functionary-pt',
    input: 'Escreva uma história do fax em duas frases.',
    background: true,
    stream: false,
  },
}) as ResponseObject;

// queued.status === 'queued'

let response = queued;
while (response.status === 'queued' || response.status === 'in_progress') {
  await new Promise((r) => setTimeout(r, 2000));
  response = await mka1.llm.responses.get({ responseId: queued.id }) as ResponseObject;
}
console.log(response.outputText);
import time

queued = sdk.llm.responses.create(
    model="meetkai:functionary-pt",
    input="Escreva uma história do fax em duas frases.",
    background=True,
    stream=False,
)  # queued.status == "queued"

response = queued
while response.status in ("queued", "in_progress"):
    time.sleep(2)
    response = sdk.llm.responses.get(response_id=queued.id)

print(response.output_text)

Webhooks em vez de polling

Em vez de fazer polling, passe webhook_url (e opcionalmente webhook_secret) ao criar uma resposta em segundo plano. O gateway envia por POST cada mudança de status ao seu endpoint — response.queued, response.in_progress, response.completed, response.failed, response.incomplete, response.cancelled — como { event, resource_id, created_at, data }, onde data é o objeto de evento completo. Com um segredo definido, cada entrega carrega X-Webhook-Signature: sha256=<hex>, um HMAC-SHA256 do corpo JSON bruto — verifique-o antes de confiar no payload. A entrega nunca bloqueia a resposta: três tentativas com backoff exponencial e um tempo limite de 10 segundos. O endpoint precisa ser acessível publicamente — endereços privados e localhost são rejeitados. O gateway exige que webhook_secret tenha pelo menos 16 caracteres.
const queued = await mka1.llm.responses.create({
  responsesCreateRequest: {
    model: 'meetkai:functionary-pt',
    input: 'Resuma este relatório de 80 páginas…',
    background: true,
    stream: false,
    webhookUrl: 'https://your-app.example.com/hooks/mka1',
    webhookSecret: process.env.MKA1_WEBHOOK_SECRET,
  },
}) as ResponseObject;
import os

queued = sdk.llm.responses.create(
    model="meetkai:functionary-pt",
    input="Resuma este relatório de 80 páginas…",
    background=True,
    stream=False,
    webhook_url="https://your-app.example.com/hooks/mka1",
    webhook_secret=os.environ["MKA1_WEBHOOK_SECRET"],
)
Para o seu lado receptor:
import crypto from 'node:crypto';

// No seu handler de webhook — verifique X-Webhook-Signature contra o corpo bruto da requisição
function isValidSignature(rawBody: string, signatureHeader: string, secret: string) {
  const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signatureHeader));
}

Conversas e memória

Detalhe de conversa com itens e metadados O MKA1 oferece duas formas complementares de manter o contexto entre turnos: conversas com estado (histórico mantido para uma sessão, no servidor) e a loja de memória de longo prazo (a ferramenta history, persistente entre sessões e com escopo por usuário final).

Conversas com estado

Uma conversa é um contêiner do lado do servidor que o gateway usa para manter o estado entre requisições de Responses, para que você nunca reenvie o histórico completo. Crie uma e depois passe seu ID em cada resposta de acompanhamento.
import { SDK } from '@meetkai/mka1';

const mka1 = new SDK({ bearerAuth: `Bearer ${YOUR_API_KEY}` });

// 1. Crie uma conversa (metadados opcionais para seu próprio roteamento)
const conv = await mka1.llm.conversations.create({
  xOnBehalfOf: '<end-user-id>',
  createConversationRequest: {
    metadata: { session_id: 'web-42', channel: 'support' },
  },
});

// 2. (Opcional) escreva o histórico explicitamente antes de chamar Responses
await mka1.llm.conversations.createItems({
  conversationId: conv.id,
  xOnBehalfOf: '<end-user-id>',
  createItemsRequest: {
    items: [
      { type: 'message', role: 'user', content: 'Resuma o ticket de suporte mais recente.' },
    ],
  },
});

// 3. Continue o fluxo — anexe a conversa para que o modelo tenha histórico
const result = await mka1.llm.responses.create({
  responsesCreateRequest: {
    model: 'meetkai:functionary-pt',
    conversation: conv.id,
    input: 'Transforme esse resumo em uma resposta pronta para o cliente.',
  },
});
# 1. Crie uma conversa (metadados opcionais para seu próprio roteamento)
conv = sdk.llm.conversations.create(
    metadata={"session_id": "web-42", "channel": "support"},
    x_on_behalf_of="<end-user-id>",
)

# 2. (Opcional) escreva o histórico explicitamente antes de chamar Responses
sdk.llm.conversations.create_items(
    conversation_id=conv.id,
    items=[
        {"type": "message", "role": "user", "content": "Resuma o ticket de suporte mais recente."},
    ],
    x_on_behalf_of="<end-user-id>",
)

# 3. Continue o fluxo — anexe a conversa para que o modelo tenha histórico
result = sdk.llm.responses.create(
    model="meetkai:functionary-pt",
    conversation=conv.id,
    input="Transforme esse resumo em uma resposta pronta para o cliente.",
)
Passe conversation em cada requisição; o gateway mantém a thread por você. Use uma conversa quando quiser um contêiner reutilizável e inspecionável para muitos turnos e a capacidade de listar, buscar ou excluir itens depois. Use previous_response_id em vez disso quando só precisar bifurcar a partir de uma única resposta anterior.

Loja de memória de longo prazo

A ferramenta history dá ao modelo memória que persiste entre sessões. Adicione { type: 'history' } a tools e defina store: true; cada par requisição/resposta é indexado em segundo plano e pesquisado semanticamente (embeddings vetoriais) quando o modelo decide que precisa lembrar de algo. A memória é isolada por usuário final via o cabeçalho X-On-Behalf-Of.
// Sessão 1: armazene um fato
await mka1.llm.responses.create({
  xOnBehalfOf: 'user-123',
  responsesCreateRequest: {
    model: 'meetkai:functionary-pt',
    input: 'Lembre-se disto: minha cor favorita é azul.',
    tools: [{ type: 'history' }],
    store: true,
  },
});

// Sessão 2 (minutos ou dias depois — a indexação leva ~1–2 min): recupere-o
const recalled = await mka1.llm.responses.create({
  xOnBehalfOf: 'user-123',
  responsesCreateRequest: {
    model: 'meetkai:functionary-pt',
    input: 'Qual é a minha cor favorita?',
    tools: [{ type: 'history' }],
    store: true,
  },
});
// → "Sua cor favorita é azul."
# Sessão 1: armazene um fato
sdk.llm.responses.create(
    model="meetkai:functionary-pt",
    input="Lembre-se disto: minha cor favorita é azul.",
    tools=[{"type": "history"}],
    store=True,
    x_on_behalf_of="user-123",
)

# Sessão 2 (minutos ou dias depois — a indexação leva ~1–2 min): recupere-o
recalled = sdk.llm.responses.create(
    model="meetkai:functionary-pt",
    input="Qual é a minha cor favorita?",
    tools=[{"type": "history"}],
    store=True,
    x_on_behalf_of="user-123",
)
Regra prática: as conversas mantêm uma sessão coerente; a ferramenta history carrega preferências, decisões e contexto adiante através de muitas sessões para o mesmo usuário.

Arquivos, lojas vetoriais e recuperação (RAG)

Uma loja vetorial com arquivos anexados em indexação O MKA1 divide a recuperação em dois recursos: Files guarda seus documentos enviados, e Vector Stores indexa esses arquivos para que você possa executar busca semântica sobre os trechos resultantes. Esse é o padrão para assistentes baseados em documentos e respostas fundamentadas. A indexação é automática. Você envia, anexa e pesquisa; o MKA1 cuida do fatiamento e dos embeddings. Todos os trechos abaixo usam o SDK MKA1 de TypeScript ou Python. Inicialize o cliente uma vez:
import { SDK } from '@meetkai/mka1';

const mka1 = new SDK({ bearerAuth: 'Bearer <mka1-api-key>' });
from meetkai_mka1 import SDK

sdk = SDK(bearer_auth="Bearer <mka1-api-key>")

1. Envie um arquivo

Envie o documento uma vez. A resposta retorna um objeto de arquivo cujo id se parece com file_1783478060914_iemq10dh5h — passe-o para as lojas vetoriais no próximo passo.
const file = Bun.file('./support-manual.pdf');

const result = await mka1.llm.files.upload({
  xOnBehalfOf: '<end-user-id>',
  requestBody: { file, purpose: 'assistants' },
});
// result.id → p. ex. file_1783478060914_iemq10dh5h
with open("support-manual.pdf", "rb") as fh:
    result = sdk.llm.files.upload(
        file={"file_name": "support-manual.pdf", "content": fh.read()},
        purpose="assistants",
        x_on_behalf_of="<end-user-id>",
    )
# result.id → p. ex. file_1783481291595_r19s7ueog7o

2. Crie uma loja vetorial e anexe arquivos

Crie uma loja vetorial, passando um ou mais IDs de arquivos enviados em fileIds. A loja retorna um ID como vs_1783478061269_mptf5b93t0q. Os arquivos anexados são indexados automaticamente.
const vectorStore = await mka1.llm.vectorStores.create({
  xOnBehalfOf: '<end-user-id>',
  createVectorStoreRequest: {
    name: 'Base de conhecimento de suporte',
    description: 'Manuais de suporte e documentos da central de ajuda indexados',
    fileIds: [result.id],
    expiresAfter: { anchor: 'last_active_at', days: 30 },
  },
});
vector_store = sdk.llm.vector_stores.create(
    name="Base de conhecimento de suporte",
    description="Manuais de suporte e documentos da central de ajuda indexados",
    file_ids=[result.id],
    expires_after={"anchor": "last_active_at", "days": 30},
    x_on_behalf_of="<end-user-id>",
)
Para adicionar mais arquivos depois sem recriar a loja, use createFile:
const second = await mka1.llm.files.upload({
  xOnBehalfOf: '<end-user-id>',
  requestBody: { file: Bun.file('./help-center-faq.pdf'), purpose: 'assistants' },
});

const vsFile = await mka1.llm.vectorStores.createFile({
  vectorStoreId: vectorStore.id,
  xOnBehalfOf: '<end-user-id>',
  createVectorStoreFileRequest: {
    fileId: second.id,
    attributes: { category: 'faq', version: '2.0' },
  },
});
with open("help-center-faq.pdf", "rb") as fh:
    second = sdk.llm.files.upload(
        file={"file_name": "help-center-faq.pdf", "content": fh.read()},
        purpose="assistants",
        x_on_behalf_of="<end-user-id>",
    )

vs_file = sdk.llm.vector_stores.create_file(
    vector_store_id=vector_store.id,
    file_id=second.id,
    attributes={"category": "faq", "version": "2.0"},
    x_on_behalf_of="<end-user-id>",
)
Um arquivo de loja vetorial pode reportar status: "in_progress" enquanto a indexação roda, então espere o processamento terminar antes de confiar nos resultados de busca.

3. Pesquise trechos relevantes na loja

Execute uma busca semântica para recuperar os trechos mais relevantes para a pergunta de um usuário. A resposta retorna correspondências classificadas com file_id, filename, dados de pontuação e o conteúdo do trecho. Alimente esse texto na lógica da sua própria aplicação ou em uma requisição de Responses.
const results = await mka1.llm.vectorStores.search({
  vectorStoreId: vectorStore.id,
  xOnBehalfOf: '<end-user-id>',
  searchVectorStoreRequest: {
    query: 'Como redefino minha senha?',
    maxNumResults: 5,
  },
});
results = sdk.llm.vector_stores.search(
    vector_store_id=vector_store.id,
    query="Como redefino minha senha?",
    max_num_results=5,
    x_on_behalf_of="<end-user-id>",
)

Bônus: extração estruturada

Quando você precisa de JSON tipado de um documento em vez de trechos de texto livre, use o recurso Extract. Para trabalho pontual, chame extract com um JSON Schema inline — passado como string JSON — e o arquivo a ler. Para trabalhos repetidos, salve o esquema uma vez com createSchema (aqui o esquema é um objeto simples) e execute-o contra muitos arquivos com extractWithSchema, referenciando o id do esquema retornado em data.id. Nomeie um modelo explicitamente em cada chamada de extração. Uma resposta bem-sucedida retorna success, um objeto data com os campos extraídos e metadata sobre a execução.
const schema = {
  type: 'object',
  properties: {
    document_title: { type: 'string' },
    reset_link_expiry_minutes: { type: 'number' },
    support_email: { type: 'string' },
  },
  required: ['document_title'],
};

// Extração pontual — aqui o esquema é uma string JSON
const res = await mka1.llm.extract.extract({
  requestBody: {
    model: 'openai:gpt-4.1', // 'auto' atualmente retorna 500 neste endpoint
    prompt: 'Extraia o título do documento, a expiração do link de redefinição e o e-mail de suporte.',
    schema: JSON.stringify(schema),
    file: Bun.file('./support-manual.txt'),
  },
});
// → { success, data: {…}, metadata: {…} }
import json

schema = {
    "type": "object",
    "properties": {
        "document_title": {"type": "string"},
        "reset_link_expiry_minutes": {"type": "number"},
        "support_email": {"type": "string"},
    },
    "required": ["document_title"],
}

# Extração pontual — aqui o esquema é uma string JSON
with open("support-manual.txt", "rb") as fh:
    res = sdk.llm.extract.extract(
        model="openai:gpt-4.1",  # 'auto' atualmente retorna 500 neste endpoint
        prompt="Extraia o título do documento, a expiração do link de redefinição e o e-mail de suporte.",
        schema=json.dumps(schema),
        file={"file_name": "support-manual.txt", "content": fh.read()},
    )
# res.success, res.data, res.metadata
// Modelo reutilizável — aqui o esquema é um objeto; o id chega em data.id
const created = await mka1.llm.extract.createSchema({
  extractionSchema: {
    name: 'support-manual',
    description: 'Extrair dados do manual de suporte',
    schema,
  },
});

const out = await mka1.llm.extract.extractWithSchema({
  schemaId: created.data.id,
  requestBody: {
    model: 'openai:gpt-4.1',
    prompt: 'Extraia os campos.',
    file: Bun.file('./support-manual.txt'),
  },
});
# Modelo reutilizável — aqui o esquema é um dict; o id chega em data.id
created = sdk.llm.extract.create_schema(
    name="support-manual",
    description="Extrair dados do manual de suporte",
    schema=schema,
)

out = sdk.llm.extract.extract_with_schema(
    schema_id=created.data.id,
    model="openai:gpt-4.1",
    prompt="Extraia os campos.",
    file={"file_name": "support-manual.txt", "content": open("support-manual.txt", "rb").read()},
)

Agentes, ferramentas e MCP

Executando um agente salvo a partir do console Um agente salvo é um objeto de agente reutilizável que armazena seu próprio comportamento para que você não reconstrua uma requisição de Responses a cada vez. Cada agente persiste um modelo, instruções e uma configuração de ferramentas (tools, tool_choice, parallel_tool_calls, max_tool_calls, text, reasoning). Quando você o executa, o serviço combina sua entrada por execução com a configuração salva e a encaminha para a API de Responses através do mkllm-gateway. Cada execução persiste a entrada mais o resultado de Responses do upstream, então você também ganha histórico de execuções de graça. Os agentes recebem um id estável como agt_....

Crie um agente

Crie um agente uma vez com os SDKs MKA1 de Python, TypeScript ou C#, incluindo uma ferramenta integrada web_search para que as execuções possam trazer informação externa atual:
import { SDK } from '@meetkai/mka1';

const mka1 = new SDK({ bearerAuth: 'Bearer YOUR_API_KEY' });

const agent = await mka1.agents.createAgent({
  createAgentRequest: {
    name: 'release-research-agent',
    description: 'Busca informações atuais de versões antes de responder.',
    model: 'meetkai:functionary-pt',
    instructions: 'Use a busca na web quando a pergunta depender de informação externa atual.',
    tools: [{ type: 'web_search', searchContextSize: 'medium' }],
    metadata: { team: 'docs' },
  },
});
console.log(agent.id);
from meetkai_mka1 import SDK

sdk = SDK(bearer_auth="Bearer YOUR_API_KEY")

agent = sdk.agents.create_agent(
    name="release-research-agent",
    description="Busca informações atuais de versões antes de responder.",
    model="meetkai:functionary-pt",
    instructions="Use a busca na web quando a pergunta depender de informação externa atual.",
    tools=[{"type": "web_search", "search_context_size": "medium"}],
    metadata={"team": "docs"},
)

print(agent.id)
O array tools completo (como enviado via HTTPS) configura a ferramenta integrada:
"tools": [
  { "type": "web_search", "search_context_size": "medium" }
],
"tool_choice": "auto",
"parallel_tool_calls": true

Execute um agente

Execute enviando apenas a entrada por execução. A execução persiste status, o gateway_response armazenado e gateway_response_id da chamada upstream. Se a execução usou web_search, o gateway_response persistido inclui as entradas de chamadas de ferramentas.
const run = await mka1.agentRuns.createAgentRun({
  agentId: agent.id,
  createAgentRunRequest: {
    input: 'Qual é a versão estável atual do Bun? Use a busca na web antes de responder.',
    metadata: { request_source: 'docs' },
  },
});

console.log(run.gatewayResponseId);
console.log(run.status);
run = sdk.agent_runs.create_agent_run(
    agent_id="agt_123",
    input="Qual é a versão estável atual do Bun? Use a busca na web antes de responder.",
    metadata={"request_source": "docs"},
)

print(run.gateway_response_id)
print(run.status)
Use sdk.agents.list_agents(...) / sdk.agent_runs.list_agent_runs(agent_id=...) para inspecionar agentes salvos e execuções anteriores.
const agents = await mka1.agents.listAgents({});
const runs = await mka1.agentRuns.listAgentRuns({ agentId: agent.id });
agents = sdk.agents.list_agents()
runs = sdk.agent_runs.list_agent_runs(agent_id="agt_123")

Histórico de versões e reversão

Cada alteração confirmada em um agente salvo — criar, atualizar, reverter — acrescenta uma versão imutável, então o histórico de configuração de um agente é sempre inspecionável. Reverter não reescreve o histórico: acrescenta uma nova versão restaurada a partir da versão alvo.
// Atualize o agente — isto confirma a versão 2
await mka1.agents.updateAgent({
  agentId: agent.id,
  updateAgentRequest: { instructions: 'Responda com detalhes exaustivos.' },
});

// Inspecione o histórico
const versions = await mka1.agentVersions.listAgentVersions({ agentId: agent.id });
// versions.data → [ { version: 2, isCurrent: true, … }, { version: 1, … } ]

// Busque uma versão completa
const v2 = await mka1.agentVersions.getAgentVersion({ agentId: agent.id, version: 2 });

// Reverta para a v1 — acrescenta a v3 com restoredFromVersion: 1
await mka1.agentVersions.rollbackAgentVersion({ agentId: agent.id, version: 1 });
sdk.agents.update_agent(agent_id=agent.id, instructions="Responda com detalhes exaustivos.")

versions = sdk.agent_versions.list_agent_versions(agent_id=agent.id)
# versions.data → [AgentVersion(version=2, is_current=True, …), AgentVersion(version=1, …)]

v2 = sdk.agent_versions.get_agent_version(agent_id=agent.id, version=2)

sdk.agent_versions.rollback_agent_version(agent_id=agent.id, version=1)
# o histórico agora é v3 (atual, restored_from_version=1), v2, v1

Anexe um servidor de ferramentas MCP

Além das ferramentas integradas, você pode deixar o modelo chamar ferramentas de um servidor MCP externo adicionando uma entrada mcp a tools. Defina require_approval como "never" para executar imediatamente, ou "always" para pausar e pedir aprovação do usuário final. Limite as ferramentas invocáveis com allowed_tools; passe credenciais upstream em headers (elas são mascaradas nas respostas armazenadas).
import type { ResponseObject } from '@meetkai/mka1/models/components';

const response = await mka1.llm.responses.create({
  responsesCreateRequest: {
    model: 'meetkai:functionary-pt',
    instructions: 'Use as ferramentas do Linear quando o usuário perguntar sobre tarefas, bugs ou projetos.',
    input: 'Liste minha issue mais recente do Linear atribuída a mim.',
    tools: [
      {
        type: 'mcp',
        serverLabel: 'Linear MCP',
        serverUrl: 'https://mcp.linear.app/mcp',
        allowedTools: ['issues.list'],
        headers: { Authorization: `Bearer ${process.env.LINEAR_API_KEY}` },
        requireApproval: 'never',
      },
    ],
  },
}) as ResponseObject;

console.log(response.outputText);
import os

response = sdk.llm.responses.create(
    model="meetkai:functionary-pt",
    instructions="Use as ferramentas do Linear quando o usuário perguntar sobre tarefas, bugs ou projetos.",
    input="Liste minha issue mais recente do Linear atribuída a mim.",
    tools=[
        {
            "type": "mcp",
            "server_label": "Linear MCP",
            "server_url": "https://mcp.linear.app/mcp",
            "allowed_tools": ["issues.list"],
            "headers": {"Authorization": f"Bearer {os.environ['LINEAR_API_KEY']}"},
            "require_approval": "never",
        },
    ],
)

print(response.output_text)
O modelo chama a ferramenta MCP permitida e retorna a mensagem final em uma única requisição. Com require_approval: "always", crie a resposta em modo de segundo plano, faça polling e trate o item mcp_approval_request devolvendo um mcp_approval_response.

Prompts, habilidades e guardrails

Um modelo de prompt versionado no repositório de prompts O MKA1 separa o quê de uma chamada LLM (seus prompts), as capacidades que você agrupa para ela (habilidades) e a governança que mantém o uso seguro e responsável (guardrails, limite de taxa e auditoria).

Repositório de prompts

A API de Prompts armazena, versiona e renderiza modelos de prompt de forma centralizada. Cada alteração de modelo cria uma versão imutável, então você tem um histórico completo de mudanças e pode reverter para qualquer versão anterior a qualquer momento. Uma reversão não é destrutiva e apenas troca a versão ativa. Os modelos usam marcadores {{variable}} que são renderizados no lado do servidor quando você recupera um prompt, permitindo reutilizar um modelo em vários contextos. Os prompts são isolados por chave de API.
import { SDK } from '@meetkai/mka1';

const mka1 = new SDK({ bearerAuth: `Bearer ${YOUR_API_KEY}` });

const prompt = await mka1.llm.prompts.create({
  createPromptRequest: {
    name: 'greeting',
    template: 'Olá, {{name}}! Bem-vindo à {{company}}.',
  },
});

const rendered = await mka1.llm.prompts.get({
  id: prompt.id,
  variables: JSON.stringify({ name: 'Alice', company: 'Acme' }),
});
console.log(rendered.renderedTemplate); // "Olá, Alice! Bem-vindo à Acme."
import json

prompt = sdk.llm.prompts.create(
    name="greeting",
    template="Olá, {{name}}! Bem-vindo à {{company}}.",
)

rendered = sdk.llm.prompts.get(
    id=prompt.id,
    variables=json.dumps({"name": "Alice", "company": "Acme"}),
)
print(rendered.rendered_template)  # "Olá, Alice! Bem-vindo à Acme."

Habilidades

Habilidades são pacotes de capacidades reutilizáveis e versionados que você envia ao gateway. Cada habilidade empacota o comportamento de ferramentas atrás de um manifesto SKILL.md. O nome e a descrição da habilidade são lidos diretamente desse manifesto. Você pode enviar um único conjunto de arquivos ou um pacote completo, gerenciar versões (cada habilidade rastreia uma versão padrão e a mais recente) e revisar cada arquivo antes de criá-la. Gerencie as habilidades no painel em Skills, ou via a API de Skills.

Guardrails, limite de taxa e auditoria de uso

Esses três recursos de governança mantêm o tráfego delegado e multiusuário controlado e responsável:
  • Limite de taxa - Cada chave de API pode carregar uma cota sobre uma janela configurável — por minuto, hora ou dia. Quando uma chave excede seu limite, o gateway retorna 429 Too Many Requests antes de a requisição chegar ao modelo, então nenhum token é consumido e nenhum uso é cobrado. Trate os 429 com novas tentativas de backoff exponencial.
  • Auditoria de uso - Revise o uso de tokens, requisições e armazenamento por org e equipe em Admin → Usage, filtrável por usuário (membros da org). Para relatórios por usuário final, consulte a API de uso com seu filtro external_user_ids — a identidade X-On-Behalf-Of. Cada resposta também retorna um X-Request-ID que você pode armazenar como chave de correlação.
  • Guardrails - As decisões de política são registradas no mesmo fluxo de auditoria: resultados como policy_violation ou throttled e valores de policy_action de warn, block ou escalate fluem para a página de Guardrails, dando a você um caminho consistente de um relatório de uso até a ação exata que foi permitida, avisada, bloqueada ou escalada.
Fontes: repositórios de prompts, limite de taxa, auditoria de uso e habilidades.

Fala e voz

Detalhe de geração de texto para fala com saída de áudio O MKA1 expõe a fala baseada em arquivos através do recurso llm.speech do SDK. Use speak para texto-para-fala e transcribe para fala-para-texto. Para conversas bidirecionais em tempo real, use o modo de voz avançado. O modo de voz avançado é coberto separadamente.

Texto para fala

speak retorna um arquivo WAV completo. O corpo da resposta é áudio binário, e os cabeçalhos da resposta incluem X-Language-Code.
import { SDK } from '@meetkai/mka1';
import { writeFileSync } from 'node:fs';

const mka1 = new SDK({ bearerAuth: 'Bearer <mka1-api-key>' });

const { headers, result } = await mka1.llm.speech.speak({
  textToSpeechRequest: {
    text: 'Welcome to the MKA1 API speech guide.',
    language: 'en',
  },
});
// headers['x-language-code'] → ['en']

const chunks = [];
for await (const chunk of result) chunks.push(chunk);
writeFileSync('speech.wav', Buffer.concat(chunks));
res = sdk.llm.speech.speak(
    text="Welcome to the MKA1 API speech guide.",
    language="en",
)
# res.headers["x-language-code"] → ["en"]; res.result transmite os bytes WAV

with open("speech.wav", "wb") as fh:
    fh.write(res.result.read())
Para reprodução de baixa latência que começa antes de o arquivo completo estar pronto, use speakStreaming e escolha mp3 (menor) ou pcm (sem compressão):
// Variante de baixa latência
const streamed = await mka1.llm.speech.speakStreaming({
  textToSpeechStreamingRequest: {
    text: 'Start speaking this response as soon as audio is ready.',
    language: 'en',
    format: 'mp3',
  },
});
# Variante de baixa latência — note format_ com underscore no final
streamed = sdk.llm.speech.speak_streaming(
    text="Start speaking this response as soon as audio is ready.",
    language="en",
    format_="mp3",
)

Fala para texto

transcribe aceita um arquivo de áudio (FLAC, MP3, MP4, M4A, OGG, WAV, WebM, PCM e mais) e retorna a transcrição junto com o idioma detectado e a confiança:
import { openAsBlob } from 'node:fs';

const result = await mka1.llm.speech.transcribe({
  language: 'en',
  prompt: 'This is a technical podcast about machine learning.',
  temperature: 0.2,
  requestBody: { file: await openAsBlob('episode.wav') },
});

console.log(result.text);       // transcrição
console.log(result.confidence); // confiança da detecção
with open("episode.wav", "rb") as fh:
    result = sdk.llm.speech.transcribe(
        file={"file_name": "episode.wav", "content": fh.read()},
        language="en",
        prompt="This is a technical podcast about machine learning.",
        temperature=0.2,
    )

print(result.text)        # transcrição
print(result.confidence)  # confiança da detecção
Para separação de múltiplos falantes, defina includeSpeakerData: true (requer áudio WAV ou PCM). A resposta então inclui um array speakers com segmentos rotulados e tempos offset_ms / duration_ms. Arquivos fonte: fala, saída multimodal.

Avaliar e observar

Quando algo funciona, o MKA1 ajuda você a medi-lo e observá-lo em produção. Uma suíte de avaliação com conjunto de dados, avaliador e versões
  • Evals - Monte uma suíte de avaliação a partir de conjuntos de dados, prompts e avaliadores, e depois lance execuções duráveis contra um ou mais modelos. Acompanhe a precisão e as pontuações por amostra, e compare modelos em um placar. Use para escolher um modelo e para pegar regressões antes que sejam lançadas.
  • Sessions - Cada execução de agente é registrada. Reproduza a transcrição (mensagens, raciocínio, chamadas de ferramentas) e percorra os eventos brutos para depurar exatamente o que um agente fez.
  • Uso e auditoria - Revise o uso de tokens, requisições e armazenamento por org e equipe em Admin → Usage, e filtre por usuário final quando enviar X-On-Behalf-Of. Cada resposta também retorna um X-Request-ID que você pode armazenar como chave de correlação.

Auditoria

A visão de Audit do tráfego do gateway em Admin → Audit Audit (Admin → Audit) é a superfície de revisão do tráfego que passou pelo gateway. Administradores do cluster veem requisições de todas as organizações e equipes; administradores de organização veem a atividade da sua própria org. Pesquise por rota, caminho ou usuário; filtre por serviço, método, status, modelo ou estado de revisão; ou cole um X-Request-ID — retornado em cada resposta da API — para pular direto para a requisição exata. Marque entradas para revisão, agrupe requisições relacionadas em casos e exporte dados de resposta para análise offline.

Alertas

Endpoints de webhook de alertas em Admin → Alerts Os alertas transformam falhas em webhooks. Em Admin → Alerts, registre uma URL de endpoint e escolha seu escopo: o cluster inteiro (administradores do cluster), sua organização (proprietários e administradores de org) ou uma única equipe — administradores de org podem mirar qualquer equipe, e membros de equipe podem gerenciar webhooks da sua própria equipe ativa. Inscreva o endpoint em um ou ambos os tipos de evento — response.failed (uma requisição de resposta falhou no provedor do modelo) e gateway.request.failed (qualquer requisição do gateway retornou um 5xx) — ou deixe a inscrição vazia para receber todos. Filtros opcionais restringem a entrega a chaves de API, códigos de erro ou modelos específicos. Cada endpoint tem uma página de detalhes mostrando sua configuração, seu segredo de assinatura (revele, copie ou rotacione) e as entregas recentes com payloads e status succeeded / failed / pending. De lá você pode reenviar uma entrega, disparar um alerta de teste durante a integração, e editar, desabilitar ou excluir o endpoint — editar nunca muda o segredo de assinatura.

Preços, orçamentos e uso

Cada requisição flui por um pipeline de faturamento: o uso registra os volumes, o livro de preços de modelos os converte em custos e os orçamentos aplicam limites sobre o resultado. Esta seção cobre os três.

Preços

Formulário de adicionar preço de modelo em Admin → Pricing Cada requisição é medida e precificada contra o livro de preços de modelos do seu cluster. Administradores do cluster mantêm o livro de preços em Admin → Pricing:
  • Moeda do cluster - A moeda em que todo preço e orçamento é denominado.
  • Preços de modelos - A tabela padrão do cluster, um preço por modelo. As dimensões de tarifa seguem a modalidade do modelo: tokens de entrada, saída, entrada em cache e raciocínio para LLMs; áudio e caracteres para fala; tarifas por imagem com níveis opcionais por tamanho; busca na web.
  • Substituições por org - Preços por organização para quando uma org fatura diferente do padrão do cluster.
  • Tarifas efetivas - Uma visão de resolução mostrando qual preço — padrão do cluster, substituição da org ou sem preço — cada modelo resolve para uma dada organização. Modelos sem preço faturam a 0.
Os preços são datados: salvar adiciona uma nova versão e nunca reescreve o custo passado. O gasto então aparece em dois lugares:
  • Admin → Usage - Gasto total precificado a partir do livro de preços, detalhado por organização, equipe, chave de API e modelo — junto com os volumes subjacentes (veja Uso abaixo).
  • A API - Consulte o gasto em qualquer intervalo de tempo, agrupado por modelo, chave de API, equipe, organização ou usuário final (a identidade X-On-Behalf-Of). Este é o alimentador para sistemas de faturamento; os Orçamentos (abaixo) aplicam limites contra o mesmo gasto.
const now = Math.floor(Date.now() / 1000);

const spend = await mka1.usage.costs({
  startTime: now - 7 * 24 * 60 * 60, // últimos 7 dias (segundos unix)
  endTime: now,
  groupBy: 'model,api_key_id', // dimensões separadas por vírgula
});
// spend.data → [{ model, apiKeyId, teamId, externalUserId, orgId, cost }, …]
import time

now = int(time.time())
spend = sdk.usage.costs(
    start_time=now - 7 * 24 * 3600,  # últimos 7 dias (segundos unix)
    end_time=now,
    group_by="model,api_key_id",  # dimensões separadas por vírgula
)
# spend.data → linhas com model, api_key_id, team_id, external_user_id, org_id, cost

Orçamentos

Formulário de novo orçamento de organização em Admin → Budgets Os orçamentos limitam o gasto total por período em uma organização ou uma chave de API. Crie e gerencie-os em Admin → Budgets — administradores de organização gerenciam os orçamentos da sua org, enquanto orçamentos de chaves de API hoje são geridos pelo administrador do cluster. Um orçamento tem três partes:
  • Período e limite - Diário, semanal ou mensal, com um limite na moeda do cluster. As janelas de gasto reiniciam nos limites do calendário UTC.
  • Limiares - Porcentagens únicas do limite, cada uma pareada com uma ação: alert (notificar) ou block (rejeitar novas requisições). Um orçamento que passou de um limiar de bloqueio mostra Blocked nas colunas ao vivo Spend e Status.
  • Webhook de alerta (opcional) - Uma URL mais um segredo de assinatura HMAC que recebe as notificações de limiar.
Cada linha de orçamento mostra o gasto ao vivo contra seu limite; abra o histórico de um orçamento para revisar os eventos de limiar do período, e edite ou exclua orçamentos conforme as necessidades mudam. Os orçamentos têm duas propriedades: orçamentos de cluster são tetos do operador (somente leitura para administradores de org), enquanto orçamentos de org são autoimpostos. A aplicação é de melhor esforço e fail-open, então dimensione os limites com margem. As mesmas operações estão disponíveis pela API — conceda à chave os scopes de Orçamentos exclusivos de administrador (read:budgets / write:budgets) no assistente de chaves do Passo 4.
// Orçamento mensal próprio em uma chave de API: avisar aos 80%, bloquear aos 100%
await mka1.budgets.setApiKey({
  apiKeyId: 'ak_…',
  requestBody: {
    period: 'monthly',
    limit: 250, // na moeda do seu cluster — veja budgets.getCurrency()
    thresholds: [
      { pct: 80, action: 'alert' },
      { pct: 100, action: 'block' },
    ],
    webhookUrl: 'https://your-app.example.com/hooks/budget',
    webhookSecret: process.env.MKA1_WEBHOOK_SECRET,
  },
});

const budgets = await mka1.budgets.getApiKey({ apiKeyId: 'ak_…' });
const events = await mka1.budgets.apiKeyEvents({ apiKeyId: 'ak_…' });
await mka1.budgets.deleteApiKey({ apiKeyId: 'ak_…', owner: 'org' });

// Variantes no nível da org: budgets.setOrg / getOrg / deleteOrg / orgEvents ({ orgId, … })
sdk.budgets.set_api_key(
    api_key_id="ak_…",
    period="monthly",
    limit=250,
    thresholds=[
        {"pct": 80, "action": "alert"},
        {"pct": 100, "action": "block"},
    ],
)

budgets = sdk.budgets.get_api_key(api_key_id="ak_…")
events = sdk.budgets.api_key_events(api_key_id="ak_…")
sdk.budgets.delete_api_key(api_key_id="ak_…", owner="org")

# Variantes no nível da org: set_org / get_org / delete_org / org_events (org_id=…)

Uso

O painel de Usage com tokens ao longo do tempo e detalhamentos por modelo em Admin → Usage O uso é o livro de volumes por trás dos preços e orçamentos — os tokens, contagens de requisições e armazenamento de cada requisição são medidos por organização, equipe, chave de API e usuário final. Ele vive em dois lugares:
  • No console - Admin → Usage mostra um gráfico de tokens ao longo do tempo (24h / 7d / 30d), detalhamentos por categoria (Responses, Completions, Embeddings, Classify, Extract) com tokens de entrada/saída e contagens de requisições por modelo, linhas por usuário final, armazenamento de arquivos e vetores, e operações de sandbox — tudo exportável como CSV. A seção de gasto precifica esses volumes a partir do livro de preços de modelos (veja Preços acima).
  • Pela API - Endpoints por categoria (llm.usage.responses, completions, conversations, embeddings, extract, classify, vectorStores, files) retornam séries agrupadas no tempo. Escolha um bucket_width, filtre por models, user_ids ou external_user_ids (a identidade X-On-Behalf-Of) e agrupe por model, api_key_id, user_id, org_id ou background para relatórios por dimensão.
const now = Math.floor(Date.now() / 1000);

const usage = await mka1.llm.usage.responses({
  startTime: now - 7 * 24 * 60 * 60, // últimos 7 dias (segundos unix)
  endTime: now,
  bucketWidth: '1d',
  groupBy: 'model',
});
// usage.data → um bucket por dia, cada um com resultados por modelo
// (tokens de entrada/saída, contagens de requisições)
import time

now = int(time.time())
usage = sdk.llm.usage.responses(
    start_time=now - 7 * 24 * 3600,  # últimos 7 dias (segundos unix)
    end_time=now,
    bucket_width="1d",
    group_by="model",
)
# usage.data → um bucket por dia, cada um com resultados por modelo

Serving

O Serving transforma os aceleradores do seu cluster — GPU, NPU ou TPU — em endpoints de inferência com autoescalonamento para os modelos que você escolher. Ele vive na sua própria seção Serving da barra lateral (administradores de organização e de cluster), e sua organização precisa ser provisionada para serving pelo operador do cluster antes do primeiro uso. Seis blocos de construção:
  • Deployments - Um modelo servido atrás de um endpoint de inferência em aceleradores dedicados, apoiado por vLLM ou SGLang. Mudanças de configuração geram uma nova revisão — reverta para qualquer revisão anterior a qualquer momento — enquanto mudanças de escalonamento se aplicam no lugar. A URL do endpoint é atribuída quando a implantação está pronta, e a autenticação do endpoint exige que os chamadores apresentem uma chave de API válida. Cada implantação expõe status, réplicas, revisões, logs e métricas.
  • Models - Registre um modelo servível por nome e origem, opcionalmente fixando um branch, tag ou revisão de commit para implantações reproduzíveis.
  • Images - Construa imagens de contêiner personalizadas (imagem OCI base, pacotes apt, comandos de build) para engines de serving e trabalhos de fine-tuning; as implantações usam por padrão a imagem padrão do engine.
  • Fine-tune jobs - Treine nos aceleradores do cluster: um modelo base, um conjunto de dados, uma estratégia (LoRA por padrão, ou fine-tuning completo) e hiperparâmetros livres. Acompanhe logs e a linha do tempo de eventos, colete checkpoints e cancele a qualquer momento.
  • Accelerators - Os tipos de aceleradores disponíveis para sua organização (p. ex. A100, H100) e seus limites por tipo.
  • Volumes & secrets - Volumes persistentes (de tamanho fixo, ou elásticos que crescem sob demanda) e segredos como um hf-token, injetados nas implantações como variáveis de ambiente.
O autoescalonamento é por implantação: réplicas mínimas e máximas, réplicas de reserva mantidas prontas para absorver picos, um teto de requisições concorrentes roteadas a uma réplica antes de escalar para fora, e uma janela de ociosidade (2–1200 segundos) antes de reduzir a escala.
// 1. Registre o modelo a servir (fixe uma revisão para implantações reproduzíveis)
await mka1.serving.models.register({
  modelRegister: { name: 'qwen-7b', source: 'Qwen/Qwen2.5-7B-Instruct' },
});

// 2. Implante-o atrás de um endpoint com autoescalonamento
const deployment = await mka1.serving.deployments.create({
  deploymentCreate: {
    name: 'qwen-7b-prod',
    model: 'qwen-7b',
    engine: 'vllm',
    accelerator: { type: 'H100', count: 1, fallback: ['A100'] },
    scaling: { minContainers: 1, maxContainers: 4, maxConcurrentInputs: 32 },
    engineArgs: ['--max-model-len', '8192'],
    endpointAuth: true,
  },
});
// a URL do endpoint aparece na implantação quando ela está pronta

// 3. Opere-o
await mka1.serving.deployments.updateScaling({
  deploymentId: deployment.id,
  scaling: { minContainers: 2, maxContainers: 8 }, // aplica-se no lugar — sem nova revisão
});

const logs = await mka1.serving.deployments.getLogs({ deploymentId: deployment.id, tail: 100 });

await mka1.serving.deployments.rollback({
  deploymentId: deployment.id,
  deploymentRollbackRequest: { revision: 1 }, // mudanças de configuração geram revisões
});
# 1. Registre o modelo a servir (fixe uma revisão para implantações reproduzíveis)
sdk.serving.models.register(name="qwen-7b", source="Qwen/Qwen2.5-7B-Instruct")

# 2. Implante-o atrás de um endpoint com autoescalonamento
deployment = sdk.serving.deployments.create(
    name="qwen-7b-prod",
    model="qwen-7b",
    engine="vllm",
    accelerator={"type": "H100", "count": 1, "fallback": ["A100"]},
    scaling={"min_containers": 1, "max_containers": 4, "max_concurrent_inputs": 32},
    engine_args=["--max-model-len", "8192"],
    endpoint_auth=True,
)
# a URL do endpoint aparece na implantação quando ela está pronta

# 3. Opere-o
sdk.serving.deployments.update_scaling(
    deployment_id=deployment.id,
    min_containers=2,
    max_containers=8,  # aplica-se no lugar — sem nova revisão
)

logs = sdk.serving.deployments.get_logs(deployment_id=deployment.id, tail=100)

sdk.serving.deployments.rollback(deployment_id=deployment.id, revision=1)

Juntando tudo: construa um agente de ponta a ponta

Os blocos de construção se compõem. Este é o fluxo principal de ponta a ponta: indexe conhecimento, conecte ferramentas, empacote uma habilidade, monte um agente, execute-o e rastreie o resultado. Formulário de criação de agente com ferramentas integradas
  1. Indexe conhecimento. Envie seus documentos como Files e anexe-os a um Vector Store para que o agente possa fundamentar respostas no seu conteúdo (veja Arquivos, lojas vetoriais e recuperação).
  2. Conecte ferramentas. Registre um servidor MCP (ou use ferramentas integradas como web_search) para que o agente possa agir e buscar dados ao vivo (veja Agentes, ferramentas e MCP).
  3. Empacote uma habilidade. Agrupe comportamento reutilizável atrás de um SKILL.md e envie-o em Skills, depois anexe-o.
  4. Monte o agente. Crie um agente salvo com um modelo, instruções e esse conjunto de ferramentas. Você configura o agente uma vez, então não reconstrói a requisição a cada chamada.
  5. Execute-o. Execute o agente com entrada nova a partir do console ou de POST /api/v1/agents/{id}/runs. Cada execução persiste sua entrada e a resposta do gateway.
  6. Rastreie a execução. Abra Sessions para reproduzir a transcrição e confirmar que o agente chamou as ferramentas certas.

Referência e suporte

Mantenha isto por perto enquanto constrói:
Recapitulação rápida
  1. Aceite o convite do cluster → você é proprietário de uma nova organização.
  2. Crie uma equipe e convide colegas.
  3. Gere uma chave de API nessa equipe (copie o segredo uma vez).
  4. Instale um SDK e autentique-se com Authorization: Bearer.
  5. Chame responses.create — depois componha conversas, memória, RAG, agentes, ferramentas e fala na sua aplicação.
Bem-vindo a bordo. Agora vá construir algo.