Reformulação de consultas e HyDE
Melhore a abrangência da recuperação.
Reformulação de consultas e HyDE é uma aula grátis de AI Prompt Engineering no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de AI Prompt Engineering, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de AI Prompt Engineering inclui 4 aulas no total.
A consulta é o elo fraco
A qualidade da recuperação é limitada pela consulta. As consultas brutas dos usuários costumam ser curtas, ambíguas, cheias de pronomes ou formuladas de maneira diferente dos documentos. A transformação da consulta reformula a consulta antes da recuperação para aumentar a cobertura e a precisão.
Essa é uma das melhorias mais baratas e de maior impacto sobre a RAG ingênua: corrija a consulta e todas as etapas posteriores se beneficiarão.
def transform_query(raw, history):
# Resolve references, expand, decompose, or hypothesize
# BEFORE embedding and retrieving.
return rewrite(raw, history)Reescrita da consulta
A transformação mais simples: um LLM reescreve a consulta do usuário em uma forma mais clara, autocontida e adequada à recuperação. Ele corrige erros de digitação, expande abreviações e remove o ruído conversacional.
Isso é especialmente importante em conversas com várias rodadas, nas quais a mensagem mais recente é ininteligível sem contexto (E quanto à segunda?).
def rewrite_query(raw):
prompt = (
'Rewrite the user question into a clear, standalone search '
'query optimized for document retrieval. Keep key entities.\n'
'Question: ' + raw
)
return llm(prompt, temperature=0).strip()Condensação de conversas
Na RAG de conversas, condense o diálogo e a nova fala em uma única pergunta autônoma. Sem isso, pronomes e elipses tornam a representação vetorial sem sentido e a recuperação entra em colapso.
Envie as falas anteriores para que o reescritor possa transformar referências como isso, aquilo e o anterior em entidades explícitas que o recuperador consiga encontrar.
def condense(history, follow_up):
prompt = (
'Given the conversation, rewrite the follow-up as a standalone '
'question with all references resolved.\nConversation:\n' +
render(history) + '\nFollow-up: ' + follow_up
)
return llm(prompt, temperature=0).strip()Expansão da consulta
A expansão gera sinônimos, termos relacionados ou formulações alternativas para ampliar a cobertura lexical e semântica. Ela combate a incompatibilidade de vocabulário: o documento diz “invalidar”, enquanto o usuário diz “revogar”.
Expanda para a recuperação e depois recupere usando a união; não mostre a forma expandida ao usuário. Tenha cuidado com a expansão excessiva, que pode trazer resultados fora do tópico.
def expand(query, n=3):
prompt = (
'List ' + str(n) + ' alternative phrasings of this query using '
'synonyms and domain terms, one per line.\n' + query
)
variants = parse_lines(llm(prompt, temperature=0.5))
return [query] + variantsRecuperação com múltiplas consultas
Gere várias reformulações diversificadas, recupere resultados para cada uma e combine as listas de resultados (fusão recíproca de posições). Formulações diferentes revelam trechos relevantes diferentes; a fusão combina seus pontos fortes e estabiliza a cobertura.
Isso troca chamadas adicionais de recuperação por mais robustez contra uma única formulação inadequada.
def multi_query(raw, n=4):
queries = expand(raw, n)
rankings = [dense_retrieve(q, 30) for q in queries]
fused = rrf(*rankings)
return dedup(fused)Decomposição da consulta
Perguntas complexas de múltiplas etapas precisam de decomposição em subperguntas, cada uma recuperada separadamente e depois combinada. Perguntar qual CEO da empresa que adquiriu X é mais velho que... não pode ser respondido por uma única recuperação.
Decomponha, recupere por subpergunta e permita que o gerador combine as evidências reunidas.
def decompose_and_retrieve(question):
subs = parse_lines(llm(
'Break this into independent sub-questions, one per line.\n' +
question, temperature=0))
evidence = {s: rerank(s, dense_retrieve(s, 30))[:3] for s in subs}
return evidence # generator synthesizes the final answerHyDE: a ideia central
HyDE (Representações vetoriais de documentos hipotéticos, Gao et al., 2022) inverte o problema. Em vez de representar vetorialmente a consulta curta, ele solicita ao LLM que gere um documento de resposta hipotético, depois representa vetorialmente esse documento e faz a recuperação usando-o.
O documento hipotético está no mesmo registro que os documentos reais, portanto sua representação vetorial fica mais próxima das respostas genuínas, corrigindo a incompatibilidade entre consulta e documento.
def hyde(query):
hypo = llm(
'Write a short passage that would answer this question, as if '
'from a reference document.\nQuestion: ' + query,
temperature=0.3)
return dense_retrieve_by_vector(embed(hypo), k=30) # embed the answerPor que HyDE melhora a cobertura
Uma pergunta e sua resposta são formuladas de maneiras diferentes; uma pergunta e uma resposta falsa, mas plausível, são formuladas de modo semelhante à resposta real. HyDE aproveita o conhecimento generativo prévio do LLM para superar essa diferença, mesmo que o documento hipotético contenha erros factuais.
A correção do documento hipotético não é muito importante: ele só precisa ter o vocabulário e a estrutura certos para ficar próximo dos documentos verdadeiros no espaço das representações vetoriais.
# Robustness: average several hypothetical docs to reduce variance
def hyde_avg(query, n=3):
vecs = [embed(llm(HYDE_PROMPT + query, temperature=0.5))
for _ in range(n)]
centroid = sum(vecs) / n
return dense_retrieve_by_vector(centroid, 30)Equilíbrios e modos de falha do HyDE
O HyDE adiciona uma geração por LLM antes da recuperação, aumentando a latência e o custo, e pode alucinar um documento hipotético que se desvie do tópico, prejudicando a cobertura de consultas de nicho ou fora da distribuição que o modelo desconhece por completo.
Atenue esse problema combinando a recuperação pelo vetor HyDE com a recuperação pela consulta bruta por meio de fusão, para que uma hipótese ruim não consiga comprometer totalmente a cobertura.
def hyde_hybrid(query):
a = dense_retrieve_by_vector(embed(hyde_doc(query)), 30)
b = dense_retrieve(query, 30) # raw-query fallback
return dedup(rrf(a, b)) # robust to bad hypotheticalsEscolha e combinação de técnicas
Essas transformações são complementares. Use condensação para conversas, expansão/múltiplas consultas para lacunas de vocabulário, decomposição para perguntas de múltiplas etapas e HyDE para incompatibilidades de registro entre pergunta e documento. Muitos sistemas de produção encadeiam a condensação, depois o HyDE, em seguida combinam os resultados com a consulta bruta e, por fim, reclassificam.
Cada transformação adicionada custa uma chamada ao LLM; portanto, selecione-as de acordo com o tipo de consulta em vez de executar todas sempre.
def route_transform(query, history, qtype):
q = condense(history, query) if history else query
if qtype == 'multi_hop': return decompose_and_retrieve(q)
if qtype == 'mismatch': return hyde_hybrid(q)
if qtype == 'vocab_gap': return multi_query(q)
return dense_retrieve(q, 30)Avaliando Transformações
Meça cada transformação pelo ganho em revocação@k na recuperação e na acurácia da resposta final em comparação com a consulta bruta, usando um conjunto sem vazamento. Acompanhe a latência adicionada e o custo de LLM para manter apenas as transformações que compensam seu custo.
Cuidado: uma transformação que melhora a revocação, mas adiciona distratores, pode reduzir a acurácia da resposta, a menos que seja combinada com reordenação e compressão.
def eval_transform(name, fn, eval_set):
return {
'recall@10': recall_at_k(eval_set, retriever=fn, k=10),
'answer_acc': answer_accuracy(eval_set, retriever=fn),
'extra_latency_ms': transform_latency(fn),
}Verificação Rápida
Reflita sobre por que HyDE funciona apesar das hipóteses imperfeitas.
Recapitulação
Principais conclusões:
- A recuperação é limitada pela consulta; transformá-la é uma melhoria barata e de alto impacto para RAG.
- A reescrita e a condensação tornam as consultas de conversa autônomas; a expansão e as múltiplas consultas corrigem lacunas de vocabulário.
- A decomposição lida com perguntas que exigem várias etapas, realizando a recuperação por subpergunta.
- HyDE incorpora uma resposta hipotética para superar a incompatibilidade de registro entre pergunta e documento; não é necessário que a hipótese esteja correta.
- Combine transformações conforme o tipo de consulta, faça a fusão com a consulta bruta para obter robustez e avalie a revocação, a acurácia da resposta, a latência e o custo.
Perguntas Frequentes
A aula “Reformulação de consultas e HyDE” é grátis?
Sim — o texto completo de “Reformulação de consultas e HyDE” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de AI Prompt Engineering, atualize para CoddyKit PRO. O curso de AI Prompt Engineering inclui 4 aulas no total.
O que vou aprender em “Reformulação de consultas e HyDE”?
Melhore a abrangência da recuperação. Você pratica AI Prompt Engineering com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar AI Prompt Engineering?
Nenhuma experiência prévia é necessária. AI Prompt Engineering no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “Reformulação de consultas e HyDE”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de AI Prompt Engineering?
Sim. Cada aula de AI Prompt Engineering inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Além do RAG ingênuo
- Reordenando trechos recuperados
- Compressão de contexto
- Reformulação de consultas e HyDE