3 pontos por GN⁺ 2024-09-22 | 1 comentários | Compartilhar no WhatsApp
  • RAG usado em IA baseada em conhecimento corporativo pode perder contexto, como nome da empresa ou período, ao dividir documentos em pequenos chunks, deixando passar informações relevantes
  • O Contextual Retrieval da Anthropic adiciona uma breve descrição baseada no documento inteiro antes de cada chunk e então cria embeddings e índice BM25 para reduzir falhas de busca
  • Nos experimentos, Contextual Embeddings reduziu a taxa de falha na recuperação dos top-20 chunks de 5,7% para 3,7%, ou 35%, e a combinação de Contextual Embeddings com Contextual BM25 reduziu para 2,9%, ou 49%
  • Ao adicionar reranking, os top-150 candidatos são pontuados novamente e apenas os top-20 são enviados ao modelo, reduzindo a taxa de falha de busca de 5,7% para 1,9%, ou 67%
  • Se a base de conhecimento tiver 200.000 tokens ou menos, também é possível colocar tudo no prompt, mas em bases maiores é preciso avaliar por caso de uso a combinação de Contextual Retrieval com reranking

O contexto do documento que o RAG perde

  • Para que um modelo de IA seja útil em um trabalho específico, ele precisa acessar conhecimento de contexto
    • Um chatbot de atendimento ao cliente precisa do conhecimento do negócio em questão
    • Um bot de análise jurídica precisa de conhecimento sobre precedentes
  • Desenvolvedores normalmente reforçam o conhecimento do modelo com Retrieval-Augmented Generation (RAG)
    • Buscam informações relevantes na base de conhecimento
    • Anexam as informações recuperadas ao prompt do usuário para melhorar a resposta do modelo
  • O RAG tradicional pode deixar de encontrar informações relevantes porque remove o contexto no processo de dividir documentos em chunks
  • Contextual Retrieval é uma forma de melhorar a etapa de busca do RAG, e duas sub técnicas podem ser usadas juntas
    • Contextual Embeddings: gera embeddings com chunks enriquecidos com contexto
    • Contextual BM25: cria um índice BM25 com chunks enriquecidos com contexto
    • Essa combinação reduz o número de falhas de recuperação em 49%, e em conjunto com reranking pode reduzir em até 67%
  • Há um cookbook disponível para implantar Contextual Retrieval com Claude

Prompts longos também são viáveis em bases pequenas

  • Se a base de conhecimento tiver 200.000 tokens ou menos, menor que cerca de 500 páginas, é possível colocar a base inteira no prompt sem usar RAG
  • O prompt caching do Claude torna essa abordagem mais rápida e econômica
    • É possível armazenar em cache prompts usados com frequência entre chamadas de API
    • A latência pode ser reduzida em mais de 2x
    • O custo pode cair em até 90%
    • O funcionamento pode ser visto no prompt caching cookbook
  • Quando a base de conhecimento cresce, é preciso um método de recuperação mais escalável, e aí entra o Contextual Retrieval

O papel do RAG tradicional e do BM25

  • Quando uma base de conhecimento grande não cabe na janela de contexto, a solução comum é o RAG
  • O fluxo de pré-processamento do RAG é o seguinte
    • O corpus de documentos é dividido em pequenos chunks de texto, normalmente com algumas centenas de tokens ou menos
    • Um modelo de embeddings converte os chunks em embeddings vetoriais que carregam significado
    • Os embeddings são armazenados em um banco vetorial que permite busca por similaridade semântica
  • Em tempo de execução, os chunks semanticamente mais parecidos com a consulta do usuário são encontrados no banco vetorial, e os chunks relevantes são adicionados ao prompt do modelo gerador
  • Modelos de embeddings capturam bem relações semânticas, mas podem deixar passar correspondências exatas de string
  • BM25 (Best Matching 25) é uma função de ranqueamento baseada em correspondência lexical, especialmente eficaz para consultas com identificadores únicos ou termos técnicos
    • BM25 se baseia no conceito de TF-IDF
    • TF-IDF mede o quanto uma palavra específica é importante para um documento dentro de uma coleção
    • BM25 considera o comprimento do documento e aplica uma função de saturação à frequência dos termos para evitar que palavras comuns dominem os resultados
  • Por exemplo, ao buscar "Error code TS-999" em uma base de suporte técnico, um modelo de embeddings pode encontrar documentos sobre códigos de erro em geral, mas deixar passar a correspondência exata de "TS-999"
  • O BM25 encontra diretamente essa string e identifica o documento relevante

RAG usando embeddings e BM25 juntos

  • O RAG pode combinar embeddings e BM25 para recuperar chunks com mais precisão
    • Divide a base de conhecimento em pequenos chunks
    • Gera codificação TF-IDF e embeddings semânticos para cada chunk
    • Usa BM25 para encontrar os principais chunks com base em correspondência exata
    • Usa embeddings para encontrar os principais chunks com base em similaridade semântica
    • Combina os resultados com técnicas de rank fusion e remove duplicatas
    • Coloca os top K chunks no prompt para gerar a resposta
  • Essa abordagem equilibra correspondência exata de termos com entendimento semântico mais amplo
  • Ela também escala de forma econômica para bases de conhecimento enormes, que não caberiam em um único prompt
  • Mas sistemas RAG tradicionais têm a limitação de destruir o contexto ao dividir documentos em chunks
  • Um exemplo típico é uma base de conhecimento formada por filings da SEC com a pergunta "What was the revenue growth for ACME Corp in Q2 2023?"
    • O chunk relevante pode conter apenas "The company's revenue grew by 3% over the previous quarter."
    • Só com esse chunk, não dá para saber de qual empresa ou de qual período se trata
    • Isso dificulta usar a informação correta tanto na busca quanto na etapa de uso

Como funciona o Contextual Retrieval

  • Contextual Retrieval adiciona na frente de cada chunk um contexto descritivo por chunk antes de gerar embeddings e criar o índice BM25
    • Quando aplicado aos embeddings, vira Contextual Embeddings
    • Quando aplicado ao índice BM25, vira Contextual BM25
  • No exemplo do filing da SEC, o chunk original é o seguinte
The company's revenue grew by 3% over the previous quarter.
  • O chunk contextualizado fica assim
This chunk is from an SEC filing on ACME corp's performance in Q2 2023; the previous quarter's revenue was $314 million. The company's revenue grew by 3% over the previous quarter.

Gerando contexto para chunks com Claude

  • Não é realista que pessoas anotem manualmente milhares ou milhões de chunks
  • A Anthropic escreveu um prompt para que o Claude gere um contexto curto e específico por chunk com base no contexto do documento inteiro
  • O prompt usado com Claude 3 Haiku é o seguinte
<document>
{{WHOLE_DOCUMENT}}
</document>
Here is the chunk we want to situate within the whole document
<chunk>
{{CHUNK_CONTENT}}
</chunk>
Please give a short succinct context to situate this chunk within the overall document for the purposes of improving search retrieval of the chunk. Answer only with the succinct context and nothing else.
  • O texto de contexto gerado costuma ter 50 a 100 tokens e é colocado antes do chunk para então ser usado na geração dos embeddings e do índice BM25
  • Com prompt caching, não é preciso reenviar o documento de referência a cada chunk
    • O documento é colocado em cache uma vez e depois o conteúdo já armazenado é referenciado
    • Assumindo chunks de 800 tokens, documentos de 8k tokens, instrução de contexto de 50 tokens e contexto gerado de 100 tokens por chunk, o custo único para gerar chunks contextualizados é de US$ 1,02 por 1 milhão de tokens de documentos

Método experimental e desempenho de busca

  • Os experimentos foram realizados em vários domínios de conhecimento, modelos de embeddings, estratégias de recuperação e métricas de avaliação
    • Base de código
    • Romance
    • Artigos do ArXiv
    • Artigos científicos
  • Exemplos de perguntas e respostas de cada domínio estão no Appendix II
  • O gráfico mostra o desempenho médio em todos os domínios, usando a configuração de embeddings de melhor resultado, Gemini Text 004, e recuperação de top-20 chunks
  • A métrica de avaliação é 1 - recall@20
    • Ela mede a proporção de vezes em que o documento relevante não foi recuperado entre os 20 principais chunks
  • Em todos os resultados, todas as combinações embedding-source avaliadas melhoraram com a contextualização
  • Os ganhos de desempenho foram os seguintes
    • Contextual Embeddings: taxa de falha de recuperação dos top-20 chunks caiu de 5,7% → 3,7%, ou 35%
    • Contextual Embeddings + Contextual BM25: taxa de falha caiu de 5,7% → 2,9%, ou 49%

Pontos a considerar na implementação

  • Limites dos chunks podem afetar o desempenho da recuperação
    • Tamanho do chunk
    • Fronteiras do chunk
    • Sobreposição entre chunks
  • Contextual Retrieval melhorou o desempenho em todos os modelos de embeddings testados, mas o tamanho do ganho pode variar por modelo
    • Os embeddings do Gemini e da Voyage foram especialmente eficazes
  • O prompt genérico fornecido funciona bem, mas um prompt de contextualização personalizado para o domínio ou caso de uso pode gerar resultados melhores
    • Exemplo: incluir um glossário de termos-chave definidos apenas em outros documentos da base de conhecimento
  • Colocar mais chunks na janela de contexto aumenta a chance de incluir informação relevante
    • Mas, quanto mais informação, maior a chance de o modelo se dispersar, então há um limite
    • Nos testes com 5, 10 e 20 chunks, 20 teve o melhor desempenho
    • Em casos de uso reais, é necessário experimentar
  • Na geração da resposta, pode haver ganho ao enviar os chunks contextualizados e distinguir o que é contexto e o que é chunk original
  • Sempre execute avaliações

Melhorando ainda mais com reranking

  • Reranking é uma técnica de filtragem que, em bases de conhecimento grandes, envia ao modelo apenas os chunks mais relevantes entre os candidatos recuperados inicialmente
  • Essa etapa pode afetar qualidade da resposta, custo e latência ao reduzir a quantidade de informação processada pelo modelo
  • O procedimento é o seguinte
    • Uma recuperação inicial busca os chunks potencialmente relevantes do topo
    • Nos experimentos, foi usado top 150
    • Os top N chunks e a consulta do usuário são enviados a um modelo de reranking
    • O modelo de reranking atribui a cada chunk uma pontuação de relevância e importância
    • Os top K chunks são selecionados
    • Nos experimentos, foi usado top 20
    • Os chunks selecionados são inseridos no contexto do modelo para gerar o resultado final
  • Os experimentos foram feitos com o Cohere reranker
  • Também existe o Voyage reranker, mas não houve tempo para testá-lo
  • Ao adicionar uma etapa de reranking em diferentes domínios, a recuperação fica ainda mais otimizada
  • Reranked Contextual Embedding + Contextual BM25 reduziu a taxa de falha na recuperação dos top-20 chunks de 5,7% → 1,9%, ou 67%

Equilíbrio entre custo e latência

  • O reranking adiciona uma etapa extra em tempo de execução, então inevitavelmente acrescenta alguma latência
  • Mesmo que o modelo de reranking pontue todos os chunks em paralelo, ainda é preciso considerar o impacto em latência e custo
  • Reranquear mais chunks pode melhorar o desempenho, mas aumenta custo e latência
  • Reranquear menos chunks reduz custo e latência, mas pode diminuir o ganho de desempenho
  • O equilíbrio adequado deve ser encontrado experimentando várias configurações no caso de uso específico

Resultado ao combinar as técnicas

  • Foram comparadas combinações de tipo de dataset, modelo de embeddings, uso ou não de BM25, uso ou não de Contextual Retrieval, uso ou não de reranking e quantidade de recuperação top-K
  • O resumo dos resultados é o seguinte
    • Embeddings + BM25 é melhor do que embeddings sozinhos
    • Entre os embeddings testados, Voyage e Gemini foram os melhores
    • Enviar top-20 chunks ao modelo é mais eficaz do que top-10 ou top-5
    • Adicionar contexto aos chunks melhora bastante a precisão da recuperação
    • Reranking é melhor do que não usar reranking
    • Para maximizar o ganho de desempenho, é possível combinar Contextual Embeddings baseados em Voyage ou Gemini, Contextual BM25, etapa de reranking e adição de 20 chunks ao prompt
  • Desenvolvedores podem experimentar essa abordagem com o Contextual Retrieval cookbook

1 comentários

 
GN⁺ 2024-09-22
Opiniões no Hacker News
  • Estou criando um RAG empresarial para órgãos governamentais. Ao fazer testes A/B experimentais com métricas RAGAS, considerando perguntas de avaliação sintéticas, não houve grande mudança ao adicionar um reranking baseado em LLM depois de uma busca híbrida (busca semântica + vetores), e o HyDE reduziu bastante a qualidade das respostas e da busca.
    Ainda precisamos fazer mais avaliações RAGAS com perguntas de especialistas e perguntas reais de usuários.
    Então, em RAG operacional/enterprise, dizer que busca híbrida costuma ser boa não é exatamente novidade, mas um método não vence sempre. No nosso caso, como segundo método ao lado da similaridade vetorial, bastou a busca semântica do Azure AI Search. Em outros lugares, BM25 ou um pequeno modelo de linguagem ajustado para pós-processamento de consultas pode funcionar melhor; no fim, é preciso continuar testando caso a caso.
    Em seguida, pretendemos tentar RAPTOR, SelfRAG, RAG agêntico, melhoria de consultas (expansão e subconsultas) e GraphRAG.
    A lição até agora é que é preciso ter uma linha de base e grupos experimentais e tentar refutar a hipótese nula com métricas como RAGAS; e as perguntas/respostas de avaliação devem usar três tipos: Q&A escrito por especialistas, perguntas reais de usuários obtidas de logs e Q&A sintético gerado a partir dos documentos originais.

    • Você poderia explicar as siglas que usou no comentário, ou fornecer links com explicações?
    • Tenho curiosidade sobre como você vê o HippoRAG. Já tentou ou planeja tentar no futuro?
  • O que mais gosto nesse método é que ele aproveita bem o prompt caching.
    Prompts em cache costumam custar cerca de 1/10 do custo normal, então um truque como processar todos os chunks junto com o documento original inteiro antes não fazia sentido financeiramente, mas agora se tornou possível.
    Acho que a redução de custo via cache vai abrir espaço para mais técnicas boas desse tipo.
    Nota sobre busca contextual: https://simonwillison.net/2024/Sep/20/introducing-contextual... e nota sobre prompt caching: https://simonwillison.net/2024/Aug/14/prompt-caching-with-cl...

    • Acompanho seu blog e leio quase todos os textos sobre LLMs. Fico curioso para saber qual é o seu custo mensal para explorar vários LLMs e recursos.
      Acho que seria um contexto útil para ter uma noção de quanto é preciso gastar para acompanhar os modelos e recursos mais recentes.
    • Há muita coisa que pode ser pré-computada para embeddings. Não é preciso colocar em cache; basta fazer pré-computação, e aí muitas técnicas comuns em ETL podem entrar.
      Do ponto de vista de alguém com background em busca tradicional, limitar RAG a modelos de embedding prontos e busca vetorial parece uma estratégia bastante ingênua. Busca vetorial, por si só, não é tão boa; para melhorar o contexto fornecido ao LLM, são necessárias estratégias adicionais de recuperação de informação. O que está sendo feito aqui é, na prática, isso.
      A Microsoft publicou anteriormente um artigo sobre Graph RAG, que combina RAG e busca vetorial com base em um grafo de conceitos criado por extração de entidades nos dados indexados. Isso permite trazer informações contextualmente relacionadas aos chunks correspondentes.
      Tenho a impressão de que dá para ir bem longe até mesmo sem busca vetorial. O custo também fica muito mais baixo. Basta usar um mecanismo de busca tradicional e consultas bem ajustadas. Claro que o ponto central é o ajuste das consultas, e isso pode não servir bem para casos genéricos, mas pode funcionar em casos mais especializados.
    • Custo é um aspecto, mas e o tempo de ingestão? Esse método não acrescenta um tempo de processamento considerável ao pipeline?
  • Para acrescentar contexto, essa abordagem não é tão nova assim. Uma das formas comuns de melhorar resultados de RAG é “expandir” os chunks de base com um LLM para aumentar a superfície semântica que pode ser correspondida.
    Também é possível melhorar mais rodando expansão de consultas com HyDE[1], mas como nem sempre melhora, eu uso isso como caminho alternativo.
    Não sei bem o que a Anthropic trouxe de novo aqui. Mesmo olhando o código do cookbook, ele apenas mostra o processo de criar esse contexto; a API não mudou de fato em relação à “busca contextual”.
    O que mudou foi o prompt caching, introduzido há cerca de um mês, que permite fornecer o documento longo inteiro como contexto e anexar um contexto melhor a chunks individuais por um custo muito baixo. O caching é um ótimo recurso para disponibilizar a desenvolvedores, e reconheço seu valor.
    Fora isso, porém, parece ser apenas um cookbook mostrando um workflow específico de RAG.
    Além disso, a Cohere é uma das APIs de que mais gostei entre as que usei. Não tenho afiliação, e a Cohere RAG API foi muito boa, ao contrário de outros provedores. Recomendo fortemente.
    1: https://arxiv.org/abs/2212.10496

    • A inovação parece estar em usar caching para tornar o custo dessa abordagem viável. A implementação é algo como pedir ao LLM, toda vez que cria um chunk, que gere chunks atômicos a partir do contexto completo.
      Se seus dados tiverem dezenas de milhares de chunks, é preciso fazer isso para todos eles, então sai caro. Fazer cache dos documentos reduz esse custo.
    • Tentei fazer isso com Prompt Caching cerca de um mês atrás, mas parei ao ver que a vida útil máxima de um prompt em cache era de 5 minutos.
      Isso não se encaixa bem nos meus requisitos de RAG, e imagino que com a maioria seja igual. Afinal, uma consulta pode ser executada no mês seguinte ou daqui a 1 ano. Não parece que essa política tenha mudado, então acho um pouco inesperado falar de Prompt Caching em relação a RAG.
  • Nós também fazemos algo parecido. Primeiro quebramos o documento em chunks com base nos títulos h1, h2 e h3, e anexamos os cabeçalhos como contexto no início do chunk
    Como exemplo hipotético, se o chunk original fosse “A dose usual para adultos é de 1 a 2 comprimidos ou cápsulas de 200 mg, 3 vezes ao dia”, agora ficaria algo como # Fever, ## Treatment, uma linha divisória e, depois, o mesmo conteúdo
    Parece funcionar bem, e também não precisa de LLM ao indexar os documentos

    • Sempre me perguntei como um LLM sabe que um texto longo ou uma transcrição de áudio foi escrito por Alan Watts. Esse tipo de anotação de metadados deve ter sido comum ao preparar dados de treinamento para modelos como o Llama
      Talvez essa seja a origem da controvérsia de que “o ChatGPT ficou mais lento em dezembro”. Esses metadados de “data” podem ter sinalizado ao ChatGPT para ser menos útil
    • Estou trabalhando em perguntas e respostas com base em documentos longos, de mais de 100 páginas, ou conjuntos de documentos, e adotei uma abordagem parecida
      Primeiro resumo cada página, dou um título e extraio a lista de subseções. Depois junto todos os resumos e peço ao modelo para criar um índice hierárquico. O modelo organiza todo o conjunto em uma árvore e, no momento da consulta, combina o caminho dentro da árvore como contexto adicional
    • Fico curioso se vocês testaram vários formatos para inserir os cabeçalhos incluídos. Pergunto porque também faço algo parecido
  • Não gosto muito dessa técnica. Concordo que o cenário apresentado é um problema comum, mas a solução proposta parece desajeitada
    Embeddings vetoriais têm uma característica meio de compressão bag-of-words e podem acabar sendo indexados em excesso pelo primeiro bloco de texto após a quebra de linha. Como resultado, certos índices do vetor ficam muito mais próximos de 0 do que antes. Depois da quantização, acabam virando 0, e você pode perder muita precisão no vetor denso. A busca por IDF compensa até certo ponto, mas não o suficiente
    Se você “impulsionar semanticamente” o embedding para movê-lo para mais perto do título, resumo, abstract etc. do documento, pode obter o ganho de recall desse prefixo de “contexto” sem contaminar o vetor base. Na implementação, é uma soma ponderada. Na etapa de augmentação, ao colocar algo na janela de contexto, se o documento corresponder, também dá para injetar o chunk de resumo junto. Pessoalmente, acho uma solução muito mais limpa
    Descrição de “semantic boost” da API da Trieve[1]:
    semantic_boost: útil para mover o vetor de embedding de um chunk na direção de uma frase de distância. Por exemplo, um chunk cujo chunk_html é iphone pode ser empurrado 25% mais perto do termo “flagship” usando flagship como distance_phrase e 0.25 como distance_factor. Conceitualmente, você traça uma linha de distância euclidiana/L2 entre o vetor do innerText de chunk_html e o vetor de distance_phrase, e move o vetor de chunk_html ao longo dessa linha para mais perto ou mais longe em distance_factorL2Distance
    [1]:https://docs.trieve.ai/api-reference/chunk/create-or-upsert-...

    • Pergunta meio do nada, mas bancos de dados vetoriais são compatíveis entre modelos? Pelo que sei, embeddings são específicos de cada modelo, então imagino que não
      Se for assim, isso não significa que um banco de dados vetorial fica preso a um único LLM, até mesmo a uma única versão como o Claude-3.5 Sonnet, sem poder migrar nem para o 3.5 Haiku ou Opus, e que seria necessário reindexar para ir para ChatGPT ou Llama?
  • A técnica que considero mais útil é implementar uma estratégia de lista encadeada, na qual o chunk tem vários ponteiros para itens que se referem a ele. Faço isso manualmente, mas isso aumenta muito a diversidade de formas pelas quais um determinado nó pode ser referenciado
    Vendo de outro jeito, é como comentários. Todos os comentários abaixo deste post podem ser vistos como ponteiros para o post original. Alguns comentários têm uma distância semântica próxima do original, outros ficam mais distantes por causa da percepção do autor. Mas, ao atribuir um parent_id a cada comentário, aumentam os caminhos de acesso ao post original
    Um exemplo dessa técnica pode ser visto aqui [1]. Em vez de tentar adivinhar que consulta o usuário final fará, basta deixar o usuário falar e indexar isso como um ponteiro. Há um número finito de opções para representar um objeto, mas algumas expressões ficam muito, muito, muito distantes do significado do objeto central
    [1] - https://x.com/yourcommonbase/status/1833262865194557505

  • A ideia de que, em datasets pequenos, basta colocar 200 mil tokens para obter a melhor resposta não bate com a minha experiência
    Vejo com frequência que, quanto maior o prompt, menor a consistência da saída e pior a obediência às instruções. Parece que isso acontece até em faixas bem abaixo de 25k tokens. Fico curioso se outras pessoas também passam por isso e se há algum método conhecido para evitar esse problema

  • Interessante. O problema que eu enfrento é usar RAG para buscar regras aplicáveis, não chunks de conhecimento. Só as regras que podem ser aplicadas ao contexto devem ser injetadas no contexto
    Ainda não fiz experimentos, mas acho que pode funcionar treinar um pequeno classificador para determinar se uma determinada regra pode ser aplicada. O LLM principal ficaria com o papel de decidir se aquela regra de fato se aplica no contexto atual
    Por exemplo, suponha que você esteja jogando um jogo de dungeon multiusuário com um LLM. Digamos que, no passado, o personagem tenha se comportado mal em relação a táxis, e o jogo tenha criado uma regra: “sempre que tentar pegar um táxi, será expulso. ‘Sabemos quem você é e não o aceitaremos como cliente até que peça desculpas formalmente ao diretor da empresa de táxis’”. Se pedir desculpas, a regra é removida. O diretor da empresa de táxis poderia ser outro jogador, ou a pessoa que inicialmente acionou a regra a ser aplicada pela sua frota de táxis NPC
    Fico curioso para saber o quanto isso escala em termos do número de regras ativas e até que ponto o RAG tradicional poderia ser aplicado. Determinar se uma regra se aplica parece um problema mais abstrato e difícil do que determinar se um chunk de conhecimento é relevante
    O ponto central que torna isso especialmente mais difícil é um loop de dependência que não existe na recuperação de conhecimento. Para identificar se uma regra se aplica, é preciso primeiro recuperar essa regra. Como esse problema poderia ser resolvido?

    • Se o contexto dentro do jogo estiver descrito adequadamente na consulta, acho que a busca vetorial tradicional usada em RAG também serviria neste caso
      Um exemplo de consulta, escrito com a ajuda do LLama 3.1 8B, poderia ser detalhado o suficiente: um exército de elfos sombrios se aproxima, Grimgold Ironfist está em uma situação desesperadora e, embora tenha sido no passado um orgulhoso integrante da milícia anã, agora está com 35% de vida; no inventário tem uma picareta velha, um balde de água, pão velho e 17 moedas de ouro; e, apesar de seu “passado problemático” com a guilda dos táxis, tenta chamar um táxi na estrada
      Um exemplo de regra a ser recuperada do armazenamento vetorial seria encontrado por proximidade vetorial por causa das menções ao nome/atributos do personagem e a táxi e Taxi Guild
      Seria uma regra como: “A Taxi Guild impôs uma penalidade rigorosa a Grimgold. Sempre que ele tentar chamar um táxi, será imediatamente expulso do veículo. O decreto da Guild diz: ‘Grimgold Ironfist, o anão barbudo de má reputação, não poderá embarcar em nenhum táxi operado por membros até que peça desculpas formalmente a Thorgrim Stonebeard, diretor da Golden Horse Cab Company. O descumprimento resultará em banimento permanente de nossos serviços’”
  • Dizem “se a base de conhecimento tiver menos de 200.000 tokens (cerca de 500 páginas)”, mas eu queria que a Anthropic simplesmente publicasse o tokenizador. Para não termos que ficar adivinhando

    • Como as respostas são transmitidas em streaming por token, será que não dá para fazer engenharia reversa?
  • Estou esperando o dia em que toda a indústria de IA vai dar uma volta completa e acabar voltando para TF-IDF

    • Sim, também achei meio engraçado. Imagino que produtos como elasticsearch já deem suporte por padrão a algoritmos clássicos de correspondência de texto, de qualquer forma