Execute este caderno no Google Colab
Cada passo abaixo em um caderno executável, com a visão geral tocando embutida. Nada para instalar.
Como funciona
Cinco endpoints, cada um fazendo uma tarefa:
A recuperação aqui é deliberadamente simples: vetores em uma lista Python, similaridade de cosseno em um loop. Essa é a quantidade certa de maquinário para algumas dezenas de fontes e mantém as partes móveis visíveis. Quando você superar isso, Construindo um bot RAG privado cobre o mesmo pipeline com um banco de dados vetorial de verdade e uma etapa de re-ranking.
Configuração
Uma dependência e uma chave da página de configurações da API.notebook.py e comece com as importações e a configuração. As duas listas ao final são todo o estado do caderno: sources registra o que você adicionou, e chunks guarda os pedaços pesquisáveis.
HOSTS mapeia o nome de um apresentador a uma voz. Ambas as vozes vêm de tts-xai-v1, e isso importa: as vozes pertencem aos modelos, e enviar uma voz de uma família para um modelo de outra é o erro inicial mais comum com o endpoint de fala.
Escolhendo um modelo que não vai envelhecer
Fixar um modelo de chat em código dentro de um projeto garante que o projeto envelheça. A Venice publica qual modelo ocupa cada papel no momento em/models/traits, então você pode pedir o padrão atual em vez de nomear um.
most_intelligent te dá um modelo mais forte para a sumarização pesada em raciocínio, e default_reasoning te dá um que pensa em aberto. Veja Modelos para a lista completa.
Adicionando fontes
Uma fonte é uma URL ou um arquivo em disco, e a Venice tem um endpoint para cada um. Ambos retornam texto simples, e esse é o ponto: o resto do caderno não se importa de onde uma fonte veio./augment/scrape retorna Markdown em vez de HTML bruto, então não há boilerplate para limpar. /augment/text-parser aceita PDF, Word, Excel e texto simples de até 25 MB, e reporta uma contagem de tokens junto com o texto. Processamento de documentos cobre todas as opções.
Chunking e embeddings
Fazer o embedding de um documento inteiro produz um vetor que é uma média de tudo o que ele diz, o que é bruto demais para recuperar uma afirmação específica. Dividi-lo produz vetores em que cada um significa algo. Divida nos limites de parágrafo em vez de por uma contagem fixa de caracteres. Um chunk que termina no meio de uma frase é recuperado mal, porque o embedding é de um fragmento.embed faz batching porque o endpoint aceita uma lista, e uma requisição para sessenta e quatro chunks é muito mais barata em tempo de execução do que sessenta e quatro requisições. text-embedding-bge-m3 retorna 1024 dimensões e lida bem com fontes multilíngues.
Adicionar uma fonte agora é ler, dividir, gerar embeddings e registrar. A magnitude de cada vetor é armazenada junto com ele, porque ela nunca muda e recomputá-la dentro do loop de similaridade é trabalho desperdiçado.
number é o que possibilita a citação depois. Cada chunk lembra de qual fonte veio, para que uma resposta possa apontar de volta para ela.
Recuperando os trechos certos
Similaridade de cosseno entre o vetor da pergunta e cada vetor de chunk, ordenados, top k. Para alguns milhares de chunks isso roda mais rápido do que a chamada de rede que produziu o vetor da pergunta.Respondendo com citações
A diferença entre uma resposta fundamentada e um palpite confiante está inteiramente no prompt. Duas instruções fazem o trabalho: responda apenas a partir das notas e diga quando as notas não forem suficientes. Sem a segunda, um modelo vai preencher a lacuna silenciosamente com base na memória, que é justamente o modo de falha que você está tentando eliminar por design. Numerar as notas no prompt dá ao modelo um vocabulário de citação. Ele escreve[2], e você pode resolver isso de volta para uma fonte.
Escrevendo o roteiro da visão geral
Aqui é onde o caderno deixa de ser uma caixa de busca. Um resumo é algo que você lê; uma visão geral é algo que você escuta, e as duas pedem uma prosa diferente. Diálogo funciona melhor em áudio porque o revezamento faz o ritmo por você, e uma pergunta de um apresentador é uma forma natural de introduzir a próxima ideia. Três restrições importam, e todas as três vêm do áudio, não do texto:- Sem markdown, sem URLs. Um modelo de fala lê
https://docs.venice.aium caractere de cada vez. - Escreva abreviações por extenso. T E E na primeira vez, não tee.
- Varie o comprimento dos turnos. Turnos de tamanho uniforme soam como duas pessoas lendo uma lista uma para a outra.
enum em speaker significa que todo turno mapeia para uma voz que você tem.
spread amostra chunks por toda a coleção em vez de recuperar por similaridade. Pegar cada enésimo chunk é rudimentar e funciona bem: ele chega ao final de documentos longos, o que pegar os doze primeiros nunca faria.
Trate a contagem de turnos como uma dica em vez de uma instrução. Pedir dezesseis já produziu de dezesseis a vinte e oito aqui, dependendo do quanto as fontes têm a dizer. Se você precisa de um teto rígido, trunque turns antes de renderizar em vez de discutir com o prompt.
Renderizando duas vozes em uma única faixa
Cada turno vira uma requisição de fala, com a voz escolhida por quem está falando.pool.map preserva a ordem de entrada, então os turnos voltam na ordem em que foram escritos, não importa qual termine primeiro. Quatro workers é um teto deliberado em vez de um máximo: mais concorrência começará a retornar 429s em tiers mais baixos, e o trabalho já é dominado pelo turno individual mais longo.
Executando
Personalizando
As fontes são todo o jogo. Tudo a jusante é limitado pelo que você coloca. Páginas raspadas trazem sua navegação e rodapés junto, o que é inofensivo para responder mas aparece numa visão geral como um apresentador discutindo com seriedade um índice de documentação. Se isso acontecer, descarte chunks abaixo de um limite de comprimento ou filtre elementos óbvios de layout antes de gerar embeddings. Troque as vozes.HOSTS são duas entradas em um dicionário. tts-xai-v1 traz vinte e seis vozes, e outras famílias têm as suas; GET /models?type=tts lista voices por modelo. Duas vozes que contrastam claramente são mais fáceis de acompanhar do que duas que são meramente diferentes.
Clone a sua própria. Clonagem de voz transforma uma amostra curta em um handle de voz que você pode encaixar direto em HOSTS.
Adicione um terceiro participante. Nada no pipeline pressupõe dois falantes exceto o enum do schema. Adicionar um entrevistador que só faz perguntas muda bastante o clima.
Guarde o roteiro. Escrever turns num arquivo JSON ao lado do áudio custa duas linhas e evita uma nova renderização toda vez que você quiser ajustar uma frase.
Próximos passos
Bot RAG privado
O mesmo pipeline de recuperação com um banco vetorial de verdade e re-ranking.
Respostas citadas com busca na web
Encontre as fontes automaticamente em vez de nomeá-las você mesmo.
Texto para fala
Referência para o endpoint de fala, suas vozes e streaming.
Processamento de documentos
Tudo que o parser de texto aceita, e o que ele retorna.