Saltar para o conteúdo
megapromotingVamos falar
Produtos Kallina

Agentes de voz com IA Plataforma

Uma boa conversa continua com uma ação.

Construímos agentes que recebem e iniciam chamadas, usam as informações da empresa e trabalham com os seus sistemas. Da primeira pergunta até um pedido completo, uma confirmação ou a transferência para um colega.

EscutarVerificaAtuaVOZ + CONTEXTO + AÇÃO
Como funciona a Kallina

Kallina

Da informação ao trabalho feito.

01

Escutar

Compreende o pedido no contexto da conversa e das regras da empresa.

02

Verifica

Consulte a base de conhecimentos e as integrações autorizadas antes de responder.

03

Atua

Preencha os dados, execute a ação permitida ou transfira a conversa para um humano.

Onde se torna útil.

Receção e suporte

Perguntas frequentes, recolha de pedidos e retorno às pessoas que pediram para ser contactadas.

Encomendas e entregas

Confirmações e coordenação, com as informações do sistema de encomendas ligado.

Qualificação e marcações

Recolha os detalhes necessários. O acesso ao calendário e a reserva são definidos para cada integração.

Os cenários, o número de telefone, os idiomas e as ações são configurados para cada implementação. A equipa mantém a possibilidade de assumir a conversa.

Kallina em detalhe

O que você pode fazer com este projeto.

Kallina é a plataforma em que construímos agentes que falam ao telefone e na página web. Um agente tem um papel escrito, uma base de conhecimentos aprovada, um conjunto de ferramentas que pode chamar e um limite para além do qual passa a conversa a um humano. A conversa não termina no transcript: a chamada tem duração, custo por fornecedor, gravação e análise, tudo ligado à conta da empresa.

O motor vocal não é único. Na configuração do agente você escolhe entre ElevenLabs Conversational AI, OpenAI Realtime, Gemini Live ou “auto”, caso em que Kallina escolhe o fornecedor em função da língua, carga e disponibilidade. Além disso, você escolhe separadamente o cérebro textual — o catálogo no código tem 78 entradas da OpenAI, Google, Anthropic, xAI e ElevenLabs, cada uma com a latência e o custo por minuto apresentados na interface, para que a escolha seja informada, não por ouvir dizer.

A telefonia é nossa, não alugada ao fornecedor de voz. As chamadas passam por um Asterisk próprio, com roteamento por horário de funcionamento e fuso horário, horário noturno (por exemplo 22:00 → 06:00) e correspondência por prioridade: o cabeçalho SIP Diversion, depois o número Kallina, depois a regra de reserva. Para OpenAI Realtime existe uma ponte AudioSocket que converte o codec nos dois sentidos, g711_ulaw ↔ PCM16.

01

Três fornecedores de voz mais uma posição „auto”

Em `AGENT_PROVIDERS` há quatro opções: `elevenlabs` (ConvAI), `openai-realtime`, `gemini-live` e `auto`. Para text-to-speech em outras línguas que não o inglês, o valor predefinido é `eleven_flash_v2_5` — 32 línguas, aproximadamente 75 ms de latência; a alternativa de melhor qualidade, `eleven_turbo_v2_5`, custa aproximadamente 250 ms. A escolha não está escondida no código, é um campo na configuração do agente.

02

Catálogo de modelos com latência e custo exibidos

78 modelos em `LLM_MODELS`, agrupados por fornecedor na interface juntamente com a latência medida e o custo por minuto — de `gpt-5-nano` com cerca de 806 ms e cerca de 0,0004 $/min, até `claude-sonnet-4-6` com cerca de 1,55 s e cerca de 0,0225 $/min. Um cliente que pergunta „por que responde devagar” recebe uma resposta com números, não uma opinião.

03

Telefonia própria em Asterisk

O reencaminhamento das chamadas é configurado por horário de trabalho e fuso horário, com suporte para horários noturnos e correspondência por prioridade (cabeçalho SIP Diversion → número Kallina → regra de reserva). A ponte `openai-realtime-bridge` faz a conversão AudioSocket entre g711_ulaw e PCM16 para o fluxo de áudio bidirecional.

04

Embed vocal numa única linha, sem id de agente na página

`<script src="https://app.kallina.info/embed.js" data-widget="WIDGET_ID"></script>`. A página nunca descobre que agente responde e não guarda nenhuma chave de fornecedor: pede a Kallina uma sessão, e a Kallina devolve um URL assinado de curta duração. Existe também o modo `data-mode="inline"`, em que o embed não desenha absolutamente nada e a página faz sozinha a sua interface sobre a API `start()` / `stop()` / `toggle()` / `on(event, fn)`.

05

Campanhas de chamadas de saída

Chamadas em lotes com 1–10 chamadas simultâneas, importação de contactos a partir de CSV, lógica de nova tentativa, acompanhamento em tempo real com pausa, retoma e paragem, mais follow-up por SMS.

06

Idiomas

A configuração do agente suporta 32 línguas (`LANGUAGES`), o mapa completo de línguas da plataforma tem 41 entradas, e o painel de administração está traduzido em 20 (`src/i18n/locales`). O romeno é a língua predefinida em `DEFAULT_VALUES`.

Dados e funcionamento

O que entra no sistema. O que deve ser verificado.

Onde os dados ficam
PostgreSQL via Supabase, com Row Level Security e pg_cron; 559 migrações versionadas. A lógica de servidor são funções edge Deno — 472 no repositório na data da verificação.
O que nunca chega à página do cliente
A chave do fornecedor de voz e o identificador do agente. O embed pede `POST /functions/v1/widget-voice-session` com `widget_id` — a chave pública de `chat_widget_configs.widget_id`, não o id interno da linha — e o servidor pede ele próprio à ElevenLabs um URL assinado, através de `convai/conversation/get_signed_url`, e devolve-o. A versão antiga, que colocava `agentId` diretamente no HTML, contornava completamente a Kallina.
Base de conhecimento
Documentos carregados na plataforma, sincronizados com o RAG da ElevenLabs. Sobre eles são colocadas barreiras de conversa, esquemas de recolha de dados e critérios de avaliação do sucesso da chamada, definidos por agente.
Consumo medido antes, não depois
A tabela `usage_events` guarda o consumo repartido por fornecedor e por agente. Antes de qualquer ação que custa, a função `check-can-use` verifica o crédito — o gate está antes da chamada, não a fatura no fim do mês.

Da exploração à implementação

Como preparamos um projeto com Kallina.

01

Escolhemos um único percurso e escrevemos os seus limites

Um cenário com entrada clara e saída clara — chamada recebida na receção, confirmação de encomenda, campanha de chamadas. Escrevemos explicitamente o que o agente não tem permissão para fazer e por que via entrega a conversa a uma pessoa.

02

Ligamos o número e verificamos nos dois sentidos

O número entra no trunk SIP do nosso Asterisk. As chamadas recebidas e as efectuadas são testadas separadamente, porque podem falhar separadamente: uma restrição do operador nas chamadas efectuadas deixa as entradas a funcionar perfeitamente.

03

Verificamos o percurso sem gastar minutos

`scripts/verify-voice-path.mjs` percorre exactamente o caminho de um browser — a linha na configuração, `get-widget-config`, depois `widget-voice-session` — e pára no URL assinado, sem abrir o websocket. Corre num único widget ou em todos os que tenham voz activa, com 1–3 em paralelo, e devolve código de saída, por isso pode entrar directamente num cron.

Perguntas que vale a pena esclarecer.

Que motor de voz usa, concretamente?

Escolhe entre ElevenLabs Conversational AI, OpenAI Realtime e Gemini Live, ou deixa «auto» e o Kallina decide com base no idioma e na disponibilidade. Para a síntese de voz noutras línguas além do inglês, o modelo por defeito é `eleven_flash_v2_5` — 32 línguas, cerca de 75 ms; se quiseres maior qualidade e aceitares maior atraso, `eleven_turbo_v2_5` anda em torno de 250 ms. As vozes do OpenAI Realtime são dez, e o motor deles vai até `gpt-realtime-2.1`.

Como se instala num site?

Uma linha: `<script src="https://app.kallina.info/embed.js" data-widget="WIDGET_ID"></script>`, carregada como script normal, não como módulo. O ficheiro é servido hoje e tem 13.762 bytes. Se quiseres a tua interface, `data-mode="inline"` não desenha nada e deixa-te `start()`, `stop()`, `toggle()` e os eventos `state`, `message`, `error`. Atenção ao host: o ficheiro está em `app.kallina.info`, não em `kallina.info` — são duas aplicações em dois servidores diferentes.

Consomem-se minutos se o visitante recusar o microfone?

Não. A ordem em `embed.js` é: carrega o SDK, pede o microfone com `getUserMedia({audio:true})` e só depois chama `widget-voice-session`. Se a pessoa recusar o microfone, o pedido de sessão nem chega a ser feito, portanto não é emitido qualquer URL assinado e não se consome nada.

Pode ligar ele primeiro, e não apenas responder?

Sim — chamadas em lote, 1–10 em simultâneo, contactos de CSV, novas tentativas e follow-up por SMS. Mas as chamadas efectuadas dependem do operador telefónico, não só de nós: no nosso registo de problemas está documentado um caso em que a central do operador começou a devolver `403 Forbidden` em todas as saídas, com a nossa configuração inalterada e com as chamadas recebidas a funcionar normalmente. Por isso testamos as saídas separadamente antes de prometer uma campanha.

Em quantas línguas fala e em quantas se administra?

A configuração do agente aceita 32 línguas, o mapa interno de línguas tem 41 entradas, e o painel de administração está traduzido em 20. O romeno é a língua por defeito dos novos agentes.

Publica-se automaticamente a cada alteração de código?

Não, e é bom saber antes de planear um lançamento. O workflow do GitHub no repo aponta para um projecto Supabase Cloud que foi apagado, por isso «push para main = publicação» já não é verdade desde a migração para a infraestrutura própria. A publicação real é feita por SSH, com cópia e reinício. Consequência prática: uma alteração urgente precisa de uma pessoa, não apenas de um commit.

O que acontece se o agente não souber a resposta?

A passagem para um humano faz parte do cenário, não é uma excepção. Cada agente tem limites escritos e um caminho de transferência configurado na telefonia; e na conversa existem guardrails e critérios de avaliação do sucesso, precisamente para que um caso fora do papel seja interrompido, não improvisado.

Exemplo ilustrativo

Uma chamada recebida à noite, que chega onde deve

Um cenário de utilização, sem dados de cliente nem resultados comerciais atribuídos.

Situação inicial

Alguém liga para o número da empresa às 23:40, fora do horário de atendimento na receção.

Como funciona

O Asterisk aplica a regra de horário noturno (por exemplo 22:00 → 06:00) e faz a correspondência por prioridade: o cabeçalho SIP Diversion, depois o número Kallina, depois a regra de reserva. O agente noturno responde no fornecedor escolhido na configuração, clarifica o pedido e chama as ferramentas que tem permissão para usar.

Rezultatul

A chamada fica no histórico com transcrição, gravação áudio, duração e custo discriminado por fornecedor. O que ultrapassa o papel do agente é interrompido e transferido, em vez de ser improvisado.

O que é necessário:O número ligado no trunk SIP do nosso Asterisk, chamadas efetuadas permitidas pelo operador, se desejado, e devolução da chamada, mais um agente com prompt, base de conhecimentos aprovada e limites escritos.

Possibilidades de colaboração

Kallina, no contexto da sua organização.

Informação e receção de pedidos

Assistência vocal com base em informações aprovadas, com passagem para um operador e regras claras sobre a gravação e o armazenamento das conversas.

Empresas privadas

Definimos um piloto em torno de um processo real: utilizadores, dados, integrações, custos e critérios de aceitação. A expansão segue após a avaliação do resultado.

Instituições e empresas públicas

Estabelecemos os requisitos de acessibilidade, alojamento, proteção de dados e interoperabilidade. Qualquer ligação a serviços AGE ou STISC requer a validação da elegibilidade, do acesso e das aprovações.

Estes são cenários de adaptação, não declarações sobre contratos ou parcerias existentes. As funções propostas confirmam-se no âmbito de trabalho do projeto.

Fale sobre um piloto

Parte de um ecossistema.

O que gostaria que funcionasse melhor?

Conte-nos o seu processo. Em conjunto decidimos o que vale a pena construir, o que podemos ligar e como verificamos o resultado.

Vamos falar