Standard RAG often fails to retrieve the right documents due to asymmetry in embedding space: the query is encoded into a vector from the question cloud, far from the document cloud. The solution is HyDE (Hypothetical Document Embeddings). An LLM generates a hypothetical answer to the query; its embedding naturally lies close to real documents. Our team implements HyDE turnkey—from model selection to production integration. With over 5 years of experience, we have completed 30+ projects improving RAG, guaranteeing an MRR improvement of 10–15%.
Why standard retrieval falls short
In vanilla RAG, the query embedding lands in a region distinct from that of documents. A hypothetical answer embedding, on the other hand, lands near documents. The difference is significant: on a legal dataset (8,500 docs), standard retrieval yields MRR@5=0.68, while HyDE gives 0.77 (+13% accuracy).
Standard RAG:
Query → Embedding(query) → search → documents
HyDE:
Query → LLM → Hypothetical_Response → Embedding(response) → search → documents
How HyDE works in practice
Consider a legal example. The query "What is the statute of limitations for labor disputes over unpaid wages?" typically searches for documents mentioning deadlines. The LLM generates a hypothetical document like "According to the Labor Code, the statute of limitations for wage-related disputes is 3 months…" The embedding of this document closely matches real code articles. Result: retrieval finds not just documents with the word "deadline", but precisely those describing the deadline—accuracy improves.
Why HyDE gives a 10-15% accuracy boost
The reason lies in embedding space collision. Queries are posed as questions—their vectors concentrate around interrogative constructions. Documents are written declaratively, so their embeddings occupy a different area. HyDE generates text in the style of a document, and its embedding automatically falls into the cluster of real documents. On the 8,500-document legal dataset we measured an MRR@5 increase from 0.68 to 0.77—a 13% improvement.
How HyDE generates hypothetical documents: an example with LangChain
Implementation via LangChain is minimal. The following code shows generation of a hypothetical document and search in Qdrant.
from langchain.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
from langchain_community.vectorstores import Qdrant
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.3)
embeddings = OpenAIEmbeddings(model="text-embedding-3-large")
vectorstore = Qdrant.from_existing_collection(
embeddings=embeddings,
collection_name="legal_docs",
url="http://localhost:6333",
)
HYDE_PROMPT = ChatPromptTemplate.from_template("""Write a short excerpt of a document (150-250 words)
that fully answers the following question.
Write as a fragment of an official document, without introductory phrases like "According to the document".
Question: {question}
Hypothetical document:""")
def hyde_retriever(question: str, top_k: int = 5) -> list:
hypothetical_doc = llm.invoke(
HYDE_PROMPT.format_messages(question=question)
).content
docs = vectorstore.similarity_search(hypothetical_doc, k=top_k)
return docs
question = "What is the statute of limitations for labor disputes over unpaid wages?"
docs = hyde_retriever(question)
When to use HyDE
HyDE is especially effective for large corpora (10,000+ documents) in specific domains: law, medicine, technical documentation. You pay 300–500 ms of latency for the extra LLM call. For short queries (numbers, dates), it's better to combine with standard retrieval and pass through a reranker.
Comparison of methods in practice
On the 8,500-document legal dataset with 300 test queries we obtained:
| Method |
MRR@5 |
NDCG@5 |
Latency (ms) |
| Standard RAG |
0.68 |
0.65 |
180 |
| HyDE |
0.77 |
0.74 |
580 |
| Multi-Query |
0.81 |
0.78 |
650 |
| HyDE + Reranker |
0.84 |
0.81 |
820 |
HyDE boosts accuracy, but latency increases. For production we recommend caching and parallel LLM calls.
What's included in our HyDE implementation
- Corpus and query analysis: evaluate applicability of HyDE, collect baseline metrics.
- HyDE integration: set up the hypothetical document generation pipeline with your LLM (GPT-4o, Claude, LLaMA).
- Prompt tuning: 2–3 days of experiments with temperature, style, and response length.
- Testing on your data: measure MRR, NDCG, latency p99.
- Optimization: implement caching, parallel LLM calls, combine with multi-query.
- Documentation and training: handover of code, instructions, and a demo session for your team.
- Support: 2 weeks of post-production monitoring and adjustments.
Step-by-step guide to implementing HyDE (for technical specialists)
- Collect baseline metrics (MRR, NDCG) on your corpus.
- Choose an LLM (GPT-4o-mini, Claude 3 Haiku—good speed/quality balance).
- Write a prompt for hypothetical document generation (sample above).
- Connect a vector store (Qdrant, Pinecone).
- Replace the retriever in your RAG pipeline with
hyde_retriever.
- Test on 100 random queries, compare against baseline.
- If latency is high, add caching for frequent queries.
Implementation timeline
| Phase |
Duration |
| HyDE integration |
1–2 days |
| Prompt tuning |
2–3 days |
| Testing vs baseline |
2–3 days |
| Total |
from 5 days |
The cost is calculated individually—it depends on corpus size, number of LLM calls, and custom modifications. Contact us: describe your task—we'll propose the optimal solution. If you want to further improve accuracy, order a corpus audit—it will show how effective HyDE is for your specific data.
For more details on HyDE implementation, see LangChain documentation.
Get a consultation: tell us about your challenges—we'll select the right HyDE implementation option.
LLM Development: Fine-Tuning, RAG, Agents, and Production Deployment
Using GPT‑4 or Claude 3.5 Sonnet through a public API is not a solution — it's just a tool. When the requirement is to "make it like ChatGPT, but on our data," there is a real engineering challenge behind it: from prompt engineering to training a 70B model on your own infrastructure. End-to-end LLM solution development is a complex stack, and we have been doing it for over 5 years. During this time, we have completed over 20 projects in generative AI: from RAG systems for legal departments to custom support agents. Where exactly your task falls depends on data, latency requirements, budget, and how critical confidentiality is.
A typical situation: the client has already tried ChatGPT, but results are unstable — sometimes accurate, sometimes hallucinating. Or they need integration into a corporate portal while complying with security policies. Let's break down each layer of the stack in detail — from RAG to production deployment.
Why Do RAG Systems Break and How to Fix It?
RAG (Retrieval-Augmented Generation) looks simple: find relevant documents, put them in context, get an answer. In practice, it fails in several places.
Chunking without overlap. Classic mistake: chunk_size=512, overlap=0. If the answer lies across two chunks, retrieval won't find either with sufficient confidence. Solution: overlap 15–25% of chunk_size, or better yet, sentence-aware splitting with spaCy or NLTK instead of naive character splitting.
Poor embedder. text-embedding-ada-002 is good for general use, but on legal or medical texts, specialized models like E5-large-v2, BGE-M3, or fine-tuned sentence-transformers on domain data outperform it. Recall@5 differences can be 15–25%.
No re-ranking. Vector search optimizes for speed, not relevance. A cross-encoder re-ranker (ms-marco-MiniLM-L-6-v2, bge-reranker-large) after initial retrieval improves top-3 accuracy with acceptable latency (+50–150ms). This is often more impactful than improving the embedding model.
Hybrid search. Dense vectors alone work poorly on exact queries: names, SKUs, codes. BM25 (sparse) finds exact matches but misses semantics. Hybrid via RRF (Reciprocal Rank Fusion) is the optimal compromise. Qdrant, Weaviate, and pgvector 0.7+ support hybrid search natively.
Typical production architecture for a corporate knowledge base
- Documents → preprocessing (PyMuPDF, Unstructured)
- Chunking → embedding (BGE-M3)
- Qdrant (hybrid dense+sparse)
- Cross-encoder re-ranking
- Context → LLM (vLLM or OpenAI API)
- Answer with sources (RAGAS for quality evaluation)
When to Fine-Tune Instead of Prompt Engineering?
Prompt engineering solves ~70% of LLM adaptation tasks for a domain. The remaining 30% require fine-tuning. Three indicators: the model ignores a specific output format even with detailed prompting; the task requires deep knowledge of specialized vocabulary (medicine, law); you need to significantly reduce token costs by replacing a large model with a smaller specialized one.
LoRA and QLoRA are the standard for SFT. LoRA adds trainable low-rank matrices to attention layers. A typical configuration for Llama-3 8B: r=64, lora_alpha=128, target_modules=["q_proj","v_proj","k_proj","o_proj"] yields ~0.8% trainable parameters, training on one A100 40GB. QLoRA adds 4-bit quantization (NF4) and allows fine-tuning 70B models on two A100 40GB, though speed drops by half compared to bf16.
DPO instead of RLHF. Direct Preference Optimization requires only (chosen, rejected) pairs, not scalar reward signals. DPOTrainer from the trl library (Hugging Face) implements it in a few dozen lines.
Common mistake. A dataset of 500 examples, 5 epochs, validation loss 0.8 — seems fine. But on test, the model degrades on general instructions. Cause: catastrophic forgetting. Solution: add 10–20% general instruction-following examples (Alpaca, FLAN) to the training set to preserve original capabilities.
How to Choose a Base Model: 8B or 70B?
| Model |
Parameters |
Strengths |
Context |
| Llama-3.1 8B |
8B |
Quality/speed balance |
128k |
| Llama-3.1 70B |
70B |
Complex reasoning |
128k |
| Mistral 7B / Mixtral 8x7B |
7B / 47B |
Efficiency for size |
32k |
| Qwen2.5 72B |
72B |
Code, multilingual |
128k |
| Gemma 2 27B |
27B |
Open license |
8k |
For most tasks, fine-tuning an 8B model is sufficient. 70B is needed when deep reasoning is required or the 8B baseline does not reach the required quality even after fine-tuning. Inference cost for Llama-3 8B via vLLM on A100 is efficient; the exact cost depends on volume.
What Does PagedAttention Bring to Production?
vLLM is the first choice for serving open-source models. PagedAttention is the key technical innovation: KV-cache is managed like virtual memory in an OS, without fragmentation. This yields 2–4x higher throughput compared to naive HuggingFace Transformers inference. The vLLM documentation confirms that continuous batching and PagedAttention are the standard for high-load LLM services.
Typical numbers on A100 80GB for Llama-3 8B (bf16): 400–600 req/s, P50 latency 200–400ms, P99 latency 600–900ms at concurrency 64. For 70B on two A100 with tensor parallelism: 80–120 req/s, P99 latency 1.5–2.5s. AWQ or GPTQ quantization reduces memory consumption by 2x with quality loss within 1–3%.
Multi-Agent Systems
Agents are LLMs with access to tools: search, code execution, API calls, database interaction. Common patterns:
- ReAct (Reason + Act): the model reasons → chooses a tool → observes the result → reasons again. LangChain and LlamaIndex implement it out of the box.
- Multi-agent orchestration: multiple specialized agents with a coordinator on top. Example: coordinator → researcher (search + summarization) → coder (code generation and execution) → critic (verification). Tools: AutoGen (Microsoft), CrewAI, custom implementation on LangGraph.
In production, agent systems are non-deterministic. Essential: guardrails, step limits, logging of each step, human-in-the-loop for critical actions.
How We Work: Stages, Timeline, Deliverables
| Stage |
Duration |
What You Get |
| Audit and data collection |
1–2 weeks |
Eval dataset of 100+ examples, task formalization |
| Baseline (prompt + RAG) |
1–2 weeks |
Working prototype, quality metrics |
| Fine-tuning (if needed) |
2–4 weeks |
Trained model, LoRA weights, model card |
| Deployment and monitoring |
1–2 weeks |
vLLM server, Grafana + Prometheus |
| Documentation and training |
1 week |
API documentation, team training |
What Is Included
We deliver:
- Technical documentation (model card, configs, deployment instructions)
- Access to infrastructure (code repository, trained weights)
- 1 month of post-deployment support (consultations, bug fixes)
- Customer team training (2–3 sessions on system operation)
Timeline: basic RAG prototype — 1–2 weeks. Fine-tuning with customer data — 3–6 weeks (including data preparation). Production system with monitoring and retraining — 2–4 months. Cost is calculated individually based on data volume, model complexity, and infrastructure requirements.
We guarantee the quality of the final model with performance benchmarks and ongoing monitoring. Our engineers have hands‑on experience with dozens of production LLM systems.
Want to evaluate your project? Leave a request — we will prepare a preliminary summary within 1–2 business days. Or get a consultation on choosing the approach: RAG, fine-tuning, or hybrid — we will tell you what works best for you. Contact us to discuss your LLM development needs. Schedule a free consultation today.