A RAG chatbot answers questions from your own documents by searching them first and then letting a language model write an answer from the passages it found, with a citation for each claim. The language model is the easy part. Answer quality is decided earlier, in how documents are parsed, split, indexed, searched and filtered by permission, and in whether anyone measures retrieval before going live. A realistic project runs through four phases: discovery, a proof of concept on a document subset, a pilot with real users, then production. Expect roughly four to seven months from kickoff to a production system for one department, with the proof of concept answering the hard questions within the first two months.
This article goes through the architecture component by component, with the design choices and trade-offs at each step, the failure modes documented most often in research and practitioner write-ups, how to evaluate the system, where to host it under GDPR, and what to settle before you start. It is written for the people who will sign off on such a project: CTOs, heads of data, IT leads and product owners.
What a RAG chatbot is, and why not just use a bigger context window
The term retrieval-augmented generation comes from Lewis et al. (2020), a Facebook AI Research paper presented at NeurIPS. The authors combined a pretrained sequence-to-sequence model with a dense vector index of Wikipedia that a neural retriever searched at question time. Their argument still holds for company chatbots: knowledge stored in model weights is hard to update, hard to inspect and impossible to cite, while knowledge kept in an external index can be replaced overnight and every answer can point to its source.
Context windows have grown since then, and the obvious question is why you would not simply load the whole document set into the prompt. There are four reasons.
First, size. A mid-sized company’s policies, contracts, manuals and project files easily run into millions of pages’ worth of tokens. No context window holds that, and even a large one is expensive to fill on every question.
Second, models do not read long contexts evenly. Liu et al. (2023), in “Lost in the Middle: How Language Models Use Long Contexts” (Stanford, published in Transactions of the ACL in 2024), tested multi-document question answering and found accuracy was highest when the relevant passage sat at the start or end of the input and dropped noticeably when it sat in the middle. Accuracy also fell as the input grew longer, including for models built for long contexts. Newer models have improved on this, but the lesson for system design is unchanged: fewer, better passages beat more passages.
Third, permissions. If everything goes into the prompt, every user sees everything. Retrieval is the natural place to filter by who is asking.
Fourth, traceability. A retrieval step produces a list of specific passages, which is what makes citations and audits possible.
There is one honest exception. Anthropic’s 2024 post “Introducing Contextual Retrieval” notes that a knowledge base under about 200,000 tokens (roughly 500 pages) can simply go into the prompt, ideally with prompt caching. If your use case is a single handbook that a whole team may read, start there and skip RAG. If the document set is larger, changes often or has mixed access rights, you need retrieval. If you are still deciding whether to adapt the model itself instead, our comparison of fine-tuning vs RAG covers that choice.
The architecture end to end
A production RAG chatbot has two pipelines. The ingestion pipeline runs in the background and turns documents into a searchable index. The query pipeline runs on every question.
INGESTION (scheduled or event-driven)
source systems -> connectors -> parsing (text, layout, OCR, tables)
-> cleaning -> chunking -> metadata + ACLs -> [optional: context per chunk]
-> embeddings -> vector index + keyword index
QUERY (per question)
user + identity -> query rewriting -> hybrid search (BM25 + dense)
-> permission filter -> rank fusion -> reranker (top 50 -> top 5-8)
-> prompt with passages -> LLM answer with citations or refusal
-> logging + feedback
Each box is a decision with trade-offs. The sections below follow that order.
Which documents go in, and who owns them
Before any engineering, make an inventory. For each candidate source, write down the system (SharePoint, Confluence, a file share, a DMS, a ticket system), the rough volume, the formats, how often content changes, who owns it, who may read it, and whether it contains personal data. This sounds administrative. It decides half the project.
Two findings come up in almost every inventory. The first is duplication and decay: the same policy exists as three Word versions, a PDF export and an outdated wiki page. A chatbot that indexes all of them will sometimes quote the wrong one with full confidence. Someone has to decide which source is authoritative, and that someone is a content owner, not an engineer. The second is that access rights in the source systems are messier than anyone assumed. Folders shared with “everyone” years ago are common, and a chatbot makes such oversharing visible, because it answers from whatever it is allowed to read.
Start with a bounded set: one department, one question type, a few thousand documents that have a named owner. Scope can grow once the pipeline works. Connector specifics for the two most common sources are covered in our article on RAG over SharePoint and Confluence.
Parsing PDFs, scans, tables and slides
Most retrieval errors that look like “the model got it wrong” turn out to be parsing errors. If the text extraction scrambles a two-column layout, merges a table into a single line of numbers or drops the header that says which product a section is about, no embedding model can repair it.
What to expect by format:
- Born-digital PDFs carry text, but not structure. Reading order, headings, columns, footnotes and running headers have to be reconstructed from layout. Simple text extraction works for plain reports and fails on forms, multi-column documents and anything with tables.
- Scanned PDFs and images need OCR. Quality depends on scan resolution, skew and fonts; old faxed contracts and stamped documents are the hard cases. German umlauts and ß are a classic source of OCR noise that then breaks keyword search.
- Tables need table-structure recognition, then a representation the model can read. Markdown or HTML tables with their header row repeated per chunk usually work better than flattened text.
- Slides are short fragments of text whose meaning depends on the layout and the images. Speaker notes often hold more information than the slide.
- Word, Excel and HTML are easier because structure is explicit, but Excel needs a decision: index sheets as tables, as rows with column names, or not at all.
Layout-aware open-source tools have improved a lot. IBM Research’s Docling (described in the “Docling Technical Report”, 2024) uses layout analysis and table-structure models to convert PDFs into Markdown or JSON with reading order and table structure preserved. Cloud document-intelligence services from the large providers do similar work as a managed API. Multimodal LLMs can also read page images directly, which helps with charts and complex forms but is slower and harder to make deterministic.
The practical advice is to sample before choosing. Take fifty of your worst documents, run them through two or three parsers, and look at the output by eye. A day spent on this saves weeks of tuning retrieval later.
How should documents be chunked?
Chunking means splitting parsed documents into passages that are embedded and retrieved one by one. Chunks that are too small lose context (“the deadline is 30 days” without saying for what). Chunks that are too large dilute the embedding and waste prompt space. There is no universally right size; it depends on how your documents are written and what people ask.
| Strategy | How it works | Works well for | Weak spots |
|---|---|---|---|
| Fixed size with overlap | Split every N tokens, overlap of 10-20% | Uniform prose, quick baseline | Cuts mid-sentence and mid-table, ignores structure |
| Recursive / sentence-aware | Split on paragraphs, then sentences, up to a size limit | Most mixed corpora | Still blind to document hierarchy |
| Structure-based | Split on headings, sections, articles, clauses | Policies, manuals, contracts, regulations | Needs good parsing; sections vary wildly in length |
| Semantic | Start a new chunk where embedding similarity between sentences drops | Long unstructured text | More compute, results hard to predict |
| Parent-child (small-to-big) | Retrieve small chunks, pass their larger parent section to the LLM | Precise search with enough context to answer | More storage and logic, larger prompts |
| Table / row-level | One chunk per table or per group of rows, header repeated | Price lists, spec sheets, matrices | Loses the text around the table unless linked |
For internal documents, structure-based chunking with a size cap, plus the section path prepended to each chunk (“HR Handbook > Travel > Reimbursement > Foreign trips”), is a sound default. Parent-child retrieval is worth adding once the baseline works, because questions about policies often need the paragraph before and after the hit. Whatever you choose, make chunking configurable and re-runnable, since you will change it after the first evaluation round.
Metadata that pays for itself
Every chunk should carry metadata: source system, document ID, title, section path, version or last-modified date, language, document type, owner, and the access control list. Some of it is for filtering (“only current versions”, “only documents of type contract”), some for ranking (newer beats older when two passages conflict), and some for the citation the user sees.
Metadata can also be extracted: product names, customer names, contract types, validity dates. That work is worth doing only when you know which filters users actually need, which is a result of the discovery phase, not a guess made at the start.
Choosing an embedding model for German and multilingual content
The embedding model turns each chunk and each query into a vector; retrieval finds the chunks whose vectors are closest to the query’s. For a European company the first requirement is language. If your documents mix German and English and users ask in either, the model has to place a German question near an English answer.
The common public reference is MTEB, the Massive Text Embedding Benchmark (Muennighoff et al., EACL 2023), extended in 2025 as MMTEB to several hundred languages and over 500 tasks (Enevoldsen et al., ICLR 2025). Use the leaderboard to build a shortlist, filtered to retrieval tasks and to the languages you need, not to pick a winner. Leaderboard scores come from public datasets that may not look like your documents, and some models have been trained on data close to the benchmark sets.
Candidates fall into two groups. Hosted embedding APIs from the large model providers are easy to start with and generally strong in German. Open-weight multilingual models can run on your own infrastructure; two well-documented examples are Microsoft’s multilingual E5 family (Wang et al., “Multilingual E5 Text Embeddings: A Technical Report”, 2024) and BAAI’s BGE-M3 (Chen et al., 2024), which supports over 100 languages, inputs up to 8,192 tokens and produces dense, sparse and multi-vector representations from one model. Self-hosting matters when documents may not leave your environment.
Then test two or three candidates on your own golden question set (see the evaluation section). Things to check besides retrieval quality: maximum input length against your chunk size, vector dimension (storage and speed), whether the model expects query and passage prefixes, and the licence. Changing the embedding model later means re-embedding the whole corpus, so pin the model version and plan for that cost.
Where to store the vectors
| Option | Typical fit | What to consider |
|---|---|---|
| PostgreSQL with pgvector | Teams already running Postgres, up to a few million chunks | One database for vectors, metadata and ACLs; tuning needed at larger scale |
| OpenSearch / Elasticsearch | Companies with an existing search stack | Native BM25 and vector search in one engine, which makes hybrid search simple |
| Dedicated vector databases (Qdrant, Weaviate, Milvus and others) | Large corpora, high query load, advanced filtering | Another system to operate; check self-hosting and EU hosting options |
| Managed cloud search services | Teams that want a managed service in their cloud tenant | Data residency per region, vendor lock-in, feature set for filtering |
For most internal chatbots the vector store is not the bottleneck. Choose what your operations team can run, back up and secure. Two requirements are non-negotiable: filtering on metadata at query time (for permissions), and support for keyword search either natively or next to it.
Hybrid search, reranking and query rewriting
Dense retrieval finds passages with similar meaning even when the wording differs. It is weak on exact strings: article numbers, error codes, names, abbreviations, paragraph references like ”§ 14 Abs. 2”. Keyword search with BM25 (described by Robertson and Zaragoza in “The Probabilistic Relevance Framework: BM25 and Beyond”, 2009) is the opposite. Internal documents are full of exact identifiers, so running both and merging the results is standard practice. For German, configure the keyword index with a proper analyser, including stemming and ideally compound splitting, or “Reisekostenabrechnung” will not match “Reisekosten”.
The simplest reliable way to merge two ranked lists is reciprocal rank fusion, from Cormack, Clarke and Büttcher’s SIGIR 2009 paper “Reciprocal Rank Fusion outperforms Condorcet and individual rank learning methods”. Each document scores the sum of 1/(k + rank) over the lists it appears in, with k = 60 in the original paper. It needs no score normalisation, which matters because BM25 and cosine scores live on different scales.
def reciprocal_rank_fusion(result_lists, k=60):
scores = {}
for results in result_lists: # e.g. [bm25_hits, dense_hits]
for rank, doc_id in enumerate(results, start=1):
scores[doc_id] = scores.get(doc_id, 0.0) + 1.0 / (k + rank)
return sorted(scores, key=scores.get, reverse=True)
Fusion produces a good candidate list, say the top 50. A reranker then reorders it. Rerankers are cross-encoders: they read the query and one passage together and output a relevance score, which is far more accurate than comparing two independently computed vectors, and far slower, so they only run on the shortlist. Nogueira and Cho (2019), “Passage Re-ranking with BERT”, showed the approach on the MS MARCO benchmark, and it has been the standard second stage since. Multilingual rerankers exist both as open-weight models and as hosted APIs. After hybrid search, adding a reranker is often the cheapest quality improvement available, with latency as the price.
Query rewriting addresses the gap between how people ask and how documents are written. In a conversation, the follow-up “and for part-timers?” has to be rewritten into a standalone question using the chat history before it can be searched. Beyond that, an LLM can expand abbreviations, add synonyms or split a compound question into parts. HyDE, from Gao et al. (2022), “Precise Zero-Shot Dense Retrieval without Relevance Labels” (ACL 2023), goes further: an LLM writes a hypothetical answer, and the embedding of that answer is used for search, because a fake answer often looks more like the real passage than the question does. It helps when questions are short and documents are long and formal. It costs an extra LLM call per query and can drift when the model knows nothing about your company’s terms, so test it rather than switch it on by default.
Contextual retrieval: giving chunks their missing context
A chunk often loses the information that makes it findable. “The notice period is three months” does not say which contract, which party or which year. Anthropic’s 2024 post “Introducing Contextual Retrieval” describes a fix: before indexing, an LLM reads the full document and writes a short context for each chunk (typically 50 to 100 tokens), which is prepended to the chunk before both embedding and BM25 indexing. In Anthropic’s experiments, contextual embeddings combined with contextual BM25 reduced the top-20 retrieval failure rate by 49%, and by 67% with reranking added. Those figures are from Anthropic’s own test sets.
The cost is one LLM call per chunk at ingestion time, which prompt caching reduces considerably because the same document is sent repeatedly. For corpora where chunks are ambiguous without their document (contracts, minutes, technical specifications) it is worth testing. Prepending the section path, as suggested in the chunking section, gets part of the benefit at no ingestion cost.
Generation with citations, and refusing when there is no evidence
Once the top five to eight passages are selected, the prompt to the LLM has three jobs: answer only from the passages, cite which passage supports each statement, and say clearly when the passages do not contain the answer. A condensed version:
You answer questions for employees of <company> using only the sources below.
Each source has an ID like [S3].
- Base every statement on the sources. Cite the source ID after each statement.
- If the sources do not answer the question, say so and name the document
or team that is likely to know. Do not answer from general knowledge.
- If sources contradict each other, show both and their dates.
- Answer in the language of the question.
Sources:
[S1] (HR Handbook > Travel > Foreign trips, version 2026-03) ...
[S2] ...
Question: ...
Citations should link to the exact document and, where the parser preserved it, the page or section. Users check citations in the first weeks, and a chatbot that points to the right page earns trust quickly. One that points to the wrong one loses it.
Refusal is the behaviour most often underbuilt. A RAG chatbot will always retrieve something, because a nearest neighbour always exists. Without an explicit rule and a test set of unanswerable questions, the model will write a plausible answer from loosely related passages. Two safeguards help: a minimum reranker score below which the system answers “I could not find this in the documents I can access”, and evaluation questions whose correct answer is a refusal.
The choice of LLM matters less than most buyers expect, as long as it follows instructions well in your languages and supports the context length you need. It does decide hosting, which is covered below.
Permission-aware retrieval
A chatbot must never show a user a passage they could not open in the source system. That is a security requirement and, for personal data, a GDPR one. The OWASP Top 10 for LLM Applications (2025 edition) lists “Vector and Embedding Weaknesses” as LLM08, with unauthorised access through misaligned access controls on embeddings as the first example.
There are three common patterns:
- Separate indexes per audience (HR-only, management-only, everyone). Simple and safe, but it does not scale beyond a handful of groups.
- ACLs as metadata on every chunk, filtered at query time. At ingestion, the connector reads the document’s permissions (users and groups) and stores them with each chunk. At query time, the system resolves the user’s group memberships from the identity provider and adds a filter so only chunks with a matching principal are searched. This is the standard design.
- Post-retrieval check against the source system. After retrieval, the system asks the source system whether the user may read each document. Most accurate, but slow, and it puts load on the source system’s API.
In practice, pattern 2 with periodic permission sync, plus pattern 3 for highly sensitive sources, covers most needs. Filter before or during the search, not after: if you retrieve the top 50 and then drop the 45 the user may not see, the remaining five are poor matches.
Microsoft’s documentation for Microsoft 365 Copilot makes the same point from the vendor side: Copilot only surfaces organisational data to which the individual user has at least view permission, and Microsoft’s SharePoint guidance for Copilot asks customers to clean up oversharing first. A custom chatbot inherits the same problem. Permission hygiene in the sources is a prerequisite, not an add-on.
Prompt injection is the other security topic. Greshake et al. (2023), “Not what you’ve signed up for: Compromising Real-World LLM-Integrated Applications with Indirect Prompt Injection”, showed that instructions hidden in retrieved content can steer an LLM-integrated application. For a read-only chatbot over curated internal documents the risk is moderate. It grows when the index contains emails, uploaded files or external web content, and it becomes serious once the chatbot can call tools.
Keeping the index fresh
An index that is a month out of date answers with last month’s policy. Plan freshness per source:
- Change detection. Most enterprise systems offer change feeds or delta APIs (Microsoft Graph delta queries for SharePoint and OneDrive, for example). Where none exist, compare modification timestamps or content hashes on a schedule.
- Updates and deletions. Deleted or superseded documents have to disappear from the index, including all their chunks. Deletion is the part most often forgotten in prototypes.
- Permission changes. A document whose sharing was narrowed must be re-filtered quickly, which may need a faster sync cycle than content.
- Full re-indexing. Changing the parser, chunking or embedding model means rebuilding the index. Keep the pipeline idempotent and build the new index next to the old one, then switch.
Agree a freshness target with the business (“changes visible within one hour” or “by next morning”) and monitor it. A small dashboard with document counts per source, last successful sync and failed parses saves a lot of support tickets.
How do you know it works? Evaluation
Without measurement, RAG tuning turns into guesswork. Build evaluation in from the proof of concept onward.
Start with a golden question set: 100 to 300 real questions collected from the people who will use the system, each with the correct answer and the document (ideally the passage) that contains it. Include easy lookups, questions that need two documents, questions with exact identifiers, questions in each language, and questions that have no answer in the corpus. The domain experts’ time to build this set is one of the real effort drivers of a project.
Then measure the two halves separately:
| Layer | What to measure | Typical metrics |
|---|---|---|
| Retrieval | Is the right passage in the top k? How high? | Recall@k / hit rate, MRR, nDCG |
| Generation | Is the answer supported by the passages and does it answer the question? | Faithfulness (groundedness), answer relevance, correctness against the reference, citation accuracy, correct refusals |
| End to end | Do users get what they need? | Thumbs up/down, follow-up rate, escalations, expert review of samples |
Separating them tells you where to work. If the right passage is not in the top 20, no prompt change will help; fix parsing, chunking or search. If it is in the top 5 and the answer is still wrong, look at the prompt, the passage order or the model.
RAGAS (Es, James, Espinosa-Anke and Schockaert, 2023, published as an EACL 2024 demo paper) defined metrics for these layers that need no human-written reference answers, including faithfulness, answer relevance and context relevance, and comes with an open-source implementation. Tools like it use an LLM as the judge. That is practical for large test sets but has known biases. Zheng et al. (2023), “Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena” (NeurIPS 2023), documented position bias (preferring the first of two answers), verbosity bias (preferring longer answers) and some self-preference. Calibrate the judge against a sample graded by your own experts, keep the judge model fixed between runs, and never treat a judge score as ground truth for decisions with legal or financial consequences.
Run the full evaluation on every change to parsing, chunking, models or prompts, and keep the results. After launch, add questions from production logs where users gave negative feedback.
Failure modes and their usual causes
| Symptom | Usual cause | Typical fix |
|---|---|---|
| Confident answer from an outdated document | Several versions indexed, no recency or authority signal | Deduplicate, mark authoritative sources, add version metadata and boost recency |
| “Not found” although the document exists | Parsing failure, OCR noise, or the document never ingested | Check ingestion logs, inspect parsed text, re-parse with a layout-aware tool |
| Misses on article numbers, codes, names | Dense-only search | Add BM25 with a proper German analyser, use hybrid search |
| Right document, wrong section | Chunks too large or without section context | Structure-based chunking, section path in chunk, reranker |
| Answer cut off or missing conditions | Chunks too small, exceptions in the next paragraph | Parent-child retrieval, larger windows around hits |
| Wrong numbers from tables | Tables flattened during parsing | Table-structure recognition, tables as Markdown with headers |
| Invented answer when nothing fits | No refusal rule, no score threshold | Refusal instruction, reranker threshold, unanswerable questions in tests |
| Follow-up questions go off track | No query rewriting with chat history | Condense history into a standalone query before search |
| User sees content outside their rights | ACLs not synced or filtered after retrieval | ACL metadata, pre-filtering, permission sync monitoring |
| Quality drops weeks after launch | Index stale, new document types, sync failures | Freshness monitoring, parse-failure alerts, ongoing evaluation |
Hosting: API, private cloud or on-premises
The hosting decision is mostly about where document content and questions travel. In a RAG chatbot, every question sends retrieved passages of your internal documents to the LLM, so the LLM provider processes your content even if the index stays in-house.
| Option | What it means | Main considerations |
|---|---|---|
| Public model API | Call a provider’s model over the internet | Fastest start, strongest models; check EU data processing regions, retention, and whether data is used for training |
| Model in your cloud tenant | Provider models deployed in your Azure, AWS or Google Cloud tenant in an EU region | Data stays in your cloud contract, good model choice, DPA via the cloud provider |
| Private cloud / dedicated hosting | Open-weight models on dedicated GPU servers with a European host | Full control, no third-party model provider; you operate the models |
| On-premises | Open-weight models on your own hardware | Maximum control, fits air-gapped or highly regulated settings; GPU procurement and operations on you |
Under the GDPR, any provider processing personal data on your behalf is a processor, and Article 28 requires a contract (a data processing agreement) that sets out the subject matter, duration, type of data and the processor’s obligations, including sub-processors. If data is transferred outside the EU, Chapter V applies; for US providers that usually means certification under the EU-US Data Privacy Framework, the adequacy decision adopted in July 2023, or standard contractual clauses. Internal documents almost always contain personal data (names in minutes, HR files, customer contacts), so assume GDPR applies.
Two more points for German companies. If employees use the chatbot and their usage is logged, the works council has a co-determination right under § 87(1) no. 6 of the Works Constitution Act (BetrVG), since the system is technically suited to monitoring behaviour or performance. Involve the works council early and agree what is logged and who sees it. And the EU AI Act (Regulation (EU) 2024/1689) requires that people are informed when they interact with an AI system unless it is obvious; an internal knowledge chatbot is usually not a high-risk system, but check this for HR or credit-related uses.
Open-weight models are now good enough for most internal question answering in German and English, which makes private hosting a realistic option rather than a compromise. Our LLM hosting services page describes the setups, and the articles on LLM hosting cost and the cost of running a local LLM cover the infrastructure side.
Project phases and timeline
These are typical ranges for a chatbot over one department’s or one domain’s documents, with one or two source systems. They assume the client side provides a product owner, domain experts for the golden set and timely access to systems.
| Phase | Typical duration | What happens | Exit criterion |
|---|---|---|---|
| Discovery | 2-4 weeks | Use cases and users, document inventory, owners, access model, hosting constraints, first 50-100 golden questions, success criteria | Agreed scope, data access, measurable targets |
| Proof of concept | 4-6 weeks | Pipeline on a representative subset (a few hundred to a few thousand documents), parser comparison, chunking and embedding tests, hybrid search, first evaluation | Retrieval and answer quality on the golden set, known gaps |
| Pilot | 6-10 weeks | Full corpus for the scope, connectors with incremental sync, permission filtering, SSO, UI or Teams integration, 20-50 pilot users, feedback loop, security review | Targets met with real users, DPA and works council agreement in place |
| Production | 4-8 weeks | Hardening, monitoring, freshness SLAs, runbooks, load tests, rollout and training, handover | Stable operation, owners for content and system |
That adds up to roughly four to seven months, with real decisions after the proof of concept. If the proof of concept shows that parsing the core document type is unreliable, or that the golden set exposes questions the documents simply do not answer, it is better to learn that in week eight than in month six. For how to frame a proof of concept so it produces a clear decision, see our overview of AI proof-of-concept companies.
What drives the effort
The same headline (“chatbot on our documents”) can mean a project twice as long as another. The drivers, roughly in order of impact:
- Document quality and formats. Clean Word and Confluence pages are quick. Scans, complex tables, CAD exports and decades of legacy PDFs are not.
- Number of source systems and their APIs. Each connector with incremental sync and permission mapping is a work package of its own.
- Access model. One audience is simple. Fine-grained, frequently changing permissions with nested groups take time to get right and to test.
- Languages. Mixed German and English corpora with cross-language questions need more evaluation work.
- Answer quality bar. An assistant for internal IT FAQs tolerates more errors than one answering contract or regulatory questions, which needs larger test sets and expert review.
- Hosting constraints. On-premises with open-weight models adds infrastructure work; a model API in an EU region adds less.
- Integration. A standalone web UI is the smallest option. Embedding into Teams, an intranet or a ticket system adds work, and so does logging into existing monitoring.
- Availability of domain experts. Golden questions and answer review need people who know the content. When they have no time, the project waits.
Build or buy
Off-the-shelf assistants such as Microsoft 365 Copilot, Google’s Gemini in Workspace and the enterprise search products with built-in chat answer questions over documents in their own ecosystems. For a company that lives in Microsoft 365, has cleaned up its permissions and mainly wants help with everyday documents, buying is usually the right first step. Setup is fast, and permissions are handled by the platform.
A custom RAG chatbot makes sense when one or more of these apply:
- Content lives outside one vendor’s ecosystem: a DMS, a PLM system, a ticket system, file shares, a database.
- Answer quality on a specific domain matters more than breadth, and you need control over parsing, chunking, search and prompts to get there.
- Documents may not be processed by a particular vendor, or must stay on-premises.
- You need a defined behaviour: strict citations, refusals, answers in a fixed format, a hand-over to a human or a ticket.
- The chatbot is part of a product or process, for example a support assistant for customers or field technicians.
Many companies end up with both: the platform assistant for general office work and a custom system for one or two domains where precision matters. A middle way is a packaged private chatbot that is configured to your sources, which is the idea behind our own AiSuperiorGPT.
Checklist before you start
- One or two use cases with named users and example questions, not “all company knowledge”.
- A document inventory for that scope: systems, volumes, formats, owners, change frequency.
- A decision on which sources are authoritative and what happens with outdated versions.
- An access model: who may see what, where the permissions live, how they are synced.
- Hosting constraints agreed with IT security and the data protection officer, including where the LLM runs.
- The works council informed, for employee-facing tools in Germany.
- Domain experts committed to build 100+ golden questions with reference answers.
- Success criteria in numbers: retrieval hit rate, answer correctness on the golden set, refusal behaviour, response time.
- A product owner on the client side who can decide on scope and content questions.
- An owner for operations after go-live: index freshness, failed ingestion, feedback triage.
FAQ
How long does it take to build a RAG chatbot on internal documents?
For one domain with one or two source systems, typically four to seven months from discovery to production. A proof of concept on a document subset is usually ready within six to ten weeks of kickoff, including discovery.
How accurate will the answers be?
That depends on your documents and questions, which is why accuracy has to be measured on your own golden question set instead of taken from a benchmark. Systems with layout-aware parsing, hybrid search, a reranker and a refusal rule answer most well-documented questions correctly; the remaining errors usually trace back to missing, outdated or badly parsed documents.
Do we need to fine-tune a model for this?
Usually not. Retrieval supplies the company knowledge, and current models follow citation and refusal instructions well. Fine-tuning can help with a very specific output style or vocabulary, or to make a small self-hosted model behave better, but it does not replace retrieval for facts that change.
Can the chatbot respect our existing SharePoint or file permissions?
Yes, if it is designed for it: permissions are read with each document, stored with every chunk, and used as a filter at query time based on the user’s identity. Permission errors in the source systems carry over, so oversharing should be cleaned up first.
Can we run a RAG chatbot fully on-premises?
Yes. Open-weight LLMs, embedding models, rerankers and vector stores can all run on your own hardware or a dedicated European host. The trade-offs are GPU capacity, operational effort and a somewhat smaller choice of models.
How do we keep the chatbot from making things up?
Instruct it to answer only from retrieved sources with citations, set a relevance threshold below which it says the information was not found, include unanswerable questions in your test set, and measure faithfulness on every change. Hallucination cannot be removed completely, but it can be made rare and visible.
Building a RAG chatbot with AI Superior
AI Superior is an AI engineering company in Darmstadt, founded in 2019 by AI scientists. We design and build RAG systems, chatbots and LLM applications for B2B clients, with retrieval evaluation, permission-aware search and EU or on-premises hosting as part of the architecture. For a consulting firm we built a private chatbot on a custom in-house LLM that answers with references to the source documents and lets users upload their own files as context. AiSuperiorGPT packages the same approach as a private chatbot for on-premises or private cloud use. If you are planning a chatbot on your internal documents, see our AI chatbot development services.
Sources and further reading
- Lewis, P. et al. (2020). Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks. NeurIPS 2020.
- Liu, N. F. et al. (2023). Lost in the Middle: How Language Models Use Long Contexts. Transactions of the ACL, 2024.
- Robertson, S. and Zaragoza, H. (2009). The Probabilistic Relevance Framework: BM25 and Beyond. Foundations and Trends in Information Retrieval.
- Cormack, G. V., Clarke, C. L. A. and Büttcher, S. (2009). Reciprocal Rank Fusion outperforms Condorcet and individual rank learning methods. SIGIR 2009.
- Nogueira, R. and Cho, K. (2019). Passage Re-ranking with BERT.
- Gao, L., Ma, X., Lin, J. and Callan, J. (2022). Precise Zero-Shot Dense Retrieval without Relevance Labels. ACL 2023.
- Anthropic (2024). Introducing Contextual Retrieval.
- Muennighoff, N. et al. (2023). MTEB: Massive Text Embedding Benchmark. EACL 2023; Enevoldsen, K. et al. (2025). MMTEB: Massive Multilingual Text Embedding Benchmark. ICLR 2025.
- Wang, L. et al. (2024). Multilingual E5 Text Embeddings: A Technical Report.
- Chen, J. et al. (2024). BGE M3-Embedding: Multi-Lingual, Multi-Functionality, Multi-Granularity Text Embeddings Through Self-Knowledge Distillation.
- Auer, C. et al. (2024). Docling Technical Report. IBM Research.
- Es, S., James, J., Espinosa-Anke, L. and Schockaert, S. (2023). RAGAS: Automated Evaluation of Retrieval Augmented Generation. EACL 2024 (demo track).
- Zheng, L. et al. (2023). Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena. NeurIPS 2023.
- Greshake, K. et al. (2023). Not what you’ve signed up for: Compromising Real-World LLM-Integrated Applications with Indirect Prompt Injection.
- OWASP (2025). OWASP Top 10 for LLM Applications 2025, LLM08: Vector and Embedding Weaknesses.
- Microsoft. Data, Privacy, and Security for Microsoft 365 Copilot (Microsoft Learn).
- Regulation (EU) 2016/679 (GDPR), Article 28 and Chapter V; Regulation (EU) 2024/1689 (AI Act); German Works Constitution Act (BetrVG), § 87.