Using AI to unlock business information

Using AI to unlock business information

Chris Goodwin . 10/12/2026

I'm sure we've all had times when we've spent an age searching a website for some basic information, or when we've called a business only to get bounced around various departments before finally getting an answer. It's a common problem, and really should be an area where AI can help. I know there are super powerful models out there such as ChatGPT and Claude that can suck in the entire content of the web and produce some increasingly impressive results, but if we want to provide a useful chat experience that focuses solely on our own organization's data how should we go about it?

To help answer that question I thought I would build out a simple proof of concept. I wanted to use the opportunity to explore what European models are available and to assess their capabilities in the real world. I also wanted to make the solution realistic, accessing a reasonably sized dataset that could return some interesting results. The data set I settled on was the government's Foreign Travel Advice website. This fulfils all the criteria I was looking for: there's a lot of data there but if you wanted to answer broad questions like “What countries have landmines?” or even very specific questions like “What's the emergency phone number in Mongolia?”, you might have to spend some time looking. You can try out the solution I created on this website here. Hopefully you'll find all your travel questions are answered! In the rest of this article, I'll run through the technical solution I've built.

The approach

At a high level, what I wanted to build was a Retrieval-Augmented Generation (RAG) system. Rather than sending a user's question directly to an LLM and hoping that it knows the answer, the system first searches the government website for the most relevant pieces of information. Those pieces of information are then supplied to the LLM as context, allowing it to construct an answer based on the source material. This isn't the only possible solution; it would also be theoretically possible to train a model on the data, but that would be vastly more complex and expensive.

The basic flow looks something like this:

User → Web application → API → Semantic search → Relevant government content → LLM → Answer

There are actually two quite separate parts to the solution. The first is an ingestion pipeline, which takes the content from GOV.UK and prepares it for searching. The second is the runtime application, which takes a question, finds the relevant content and generates the answer. This separation is important. The LLM doesn't need to know anything about the underlying website structure, and I don't need to train or fine-tune the model every time the government publishes new information.

Getting the data

The first challenge was getting the Foreign Travel Advice data into a form that could be searched effectively. The GOV.UK site contains information for a large number of countries, with each country having information covering areas such as safety and security, entry requirements, health, local laws and customs, and emergency contacts.

Simply putting the entire website into an LLM isn't particularly practical. Apart from the cost and context-window limitations, it also wouldn't give a particularly good mechanism for ensuring that the answer was based on the most relevant information. Instead, I extracted the relevant pages and converted them into a collection of text documents.

This is where one of the less glamorous but more important parts of an AI application becomes apparent: data preparation. The quality of the eventual answers is heavily dependent on the quality of the data that is supplied to the model. Removing navigation elements, boilerplate and irrelevant content while retaining headings and the structure of the original document makes a significant difference.

Breaking the documents into chunks

Once I had the source material, I needed to break it into smaller chunks. This is a fundamental part of a RAG system. A question such as:

"What's the emergency phone number in Mongolia?"

doesn't require the entire Mongolia travel advice document. Ideally, the search system should be able to identify the small section containing the emergency contact information. I therefore split the documents into chunks of manageable size, while trying to preserve the logical structure of the original content. There is a trade-off here. If chunks are too large, the search results contain lots of irrelevant information. If they are too small, useful context can be lost.

This turned out to be one of the areas where there is more experimentation involved than I initially expected. Chunk size and the way the source documents are structured can all affect retrieval performance.

Semantic search with embeddings

The next question was how to search those chunks. A conventional keyword search would work for some questions. If I searched for "emergency phone number Mongolia", for example, I might get a sensible result. But what happens if someone asks:

"What number should I call if I need an ambulance while travelling in Mongolia?"

The relevant section might never contain the words "ambulance" and "phone number" together. This is where embeddings come in. I used an embedding model to convert each chunk of text into a numerical vector representing its semantic meaning. I can then convert a user's question into a vector using the same model and compare it with the vectors representing the stored chunks. The result is a form of semantic search. Instead of asking "Which documents contain these exact words?", I'm effectively asking "Which pieces of content mean something similar to this question?"

For this project I chose jinaai/jina-embeddings-v5-text-nano. One of the reasons for choosing it was that I wanted to explore European AI models rather than simply defaulting to one of the better-known US providers. I also wanted a small model that I could run on my laptop in a reasonable timeframe, and Jina's nano model excelled in this respect.

The embedding process is performed when the data is ingested, so I don't need to regenerate the embeddings every time someone asks a question. Those embeddings were saved in a PostgreSQL database using the pgVector extension. At runtime, only the user's question needs to be encoded.

Finding the right model

Once I had retrieved the relevant pieces of information, I needed a model to turn them into a useful answer. This was another interesting part of the experiment. There are now a surprisingly large number of European AI companies and models, including models from organisations such as Mistral AI, Aleph Alpha and others. Rather than choosing a model purely on benchmark scores, I wanted to see how well a European model performed when given real-world government information.

The role of the LLM in this architecture is actually quite constrained. It isn't being asked to know everything about foreign travel. Instead, it is being given a question and a handful of relevant passages retrieved from the GOV.UK data. The prompt essentially tells the model:

  • here is the user's question;
  • here is the relevant source material;
  • answer the question using that material;
  • don't invent information that isn't present in the source.

This distinction is important. The model is being used primarily as a reasoning and language-generation layer, rather than as the source of truth.

Putting the RAG pipeline together

The complete request now looks like this:

  1. The user enters a question in the web application.
  2. The frontend sends the question to my API.
  3. The API generates an embedding for the question.
  4. The embedding is compared with the stored document embeddings.
  5. The most relevant chunks are retrieved.
  6. Those chunks are added to the LLM prompt as context.
  7. The LLM generates an answer.
  8. The API returns the answer to the frontend.

This is the core of the application.

One useful consequence of this architecture is that the individual components are relatively independent. I can change the embedding model without fundamentally changing the frontend, or swap the LLM without changing how the government data is stored. That makes the architecture considerably more flexible than building the whole application around a particular AI provider.

The API

I decided to build the backend API using NestJS. This provides a nicely structured framework on top of a NodeJS/Typescript application. The API sits between the frontend and the AI components and is responsible for orchestrating the process. I deliberately didn't put the AI logic directly into the React frontend application. Apart from keeping the frontend relatively simple, this gives me a single place to manage things such as prompts, retrieval parameters, model configuration and logging. It also means that the frontend doesn't need access to any model credentials or other infrastructure.

The API effectively exposes a simple interface along the lines of:

POST /question

with the question supplied in the request body. Everything else happens behind that interface.

The frontend

For the frontend I used Next.JS (rather confusingly! Next.JS frontend, NestJS Api), which is a framework over the top of React. The application itself is intentionally simple. The interesting part of the project is what happens behind the interface, rather than building a sophisticated chat application. The user enters a question, the application sends it to the API and then displays the resulting answer.

Keeping the frontend lightweight also makes it easier to imagine how the same API could eventually be used by other clients — for example, a mobile application, a customer-service application or even an existing government website.

Does it actually work?

This was probably the most interesting part of the project. It is relatively easy to build something that produces an impressive-looking answer. The more difficult question is whether the system consistently retrieves the right information before generating that answer. I created a collection of test questions covering different types of queries. Some were straightforward:

"What is the emergency number in Mongolia?"

Others were deliberately more semantic:

"Which countries warn about landmines?"

And some were designed to test whether the system could combine information from different parts of the source material. This highlighted an important distinction between retrieval quality and generation quality. If the correct piece of information is retrieved but the LLM produces a poor answer, I have a generation problem. If the correct information isn't retrieved in the first place, changing the LLM probably isn't going to solve the problem. In my testing, the retrieval stage was therefore the area that required the most attention.

What I learned

The biggest lesson from building this was that an LLM is only one part of an AI application. It is tempting to think of the architecture as:

Website → LLM → Answer

In reality, a useful application often looks more like:

Source data → ingestion → chunking → embeddings → retrieval → prompt construction → LLM → answer

Each stage introduces opportunities for errors. A fantastic LLM can't compensate for poor source data. A good embedding model can't compensate for badly constructed chunks. And excellent retrieval doesn't help if the prompt doesn't give the LLM enough information to formulate the answer. The quality of the overall system is therefore determined by the entire pipeline.

What I'd improve next

There are several things I'd like to add to the proof of concept.

The first is a reranking stage. At the moment I'm using vector similarity to identify the most relevant chunks. A reranker could take those initial results and perform a second, more sophisticated relevance assessment before the information is passed to the LLM.

I would also like to improve the evaluation framework. Rather than manually testing questions, I want to build a larger test set containing questions with known answers and measure retrieval accuracy systematically.

Finally, I'd like to experiment with different embedding models and European LLMs and compare them using the same dataset and test questions. That would turn this from a simple proof of concept into a more meaningful comparison of the different approaches.

So, is RAG the answer?

For this particular problem, I think it is a very good fit.

If an organisation has a relatively well-defined body of information — policies, procedures, product documentation, knowledge bases, regulations or customer information — RAG provides a way of putting a conversational interface over that information without having to train a model from scratch. More importantly, the underlying information can be updated independently of the LLM. That's a significant advantage for applications where accuracy and currency matter. The model doesn't need to "know" the latest travel advice. I simply need to update the underlying dataset and regenerate the relevant embeddings.

Of course, this doesn't make the system infallible. An LLM can still misunderstand the retrieved information or produce a confident answer that isn't supported by the source. For anything genuinely important, the generated response should therefore be treated as an interface to the underlying information rather than an unquestionable source of truth.

Final thoughts

What started as a relatively simple experiment turned out to be a useful demonstration of how many different technologies come together to create an AI application. The LLM gets most of the attention, but in this application the model is arguably the easiest part. The interesting engineering challenges are around getting good source data, retrieving the right information, evaluating whether retrieval is actually working, and designing the system so that the individual components can evolve independently.

It also gave me a chance to experiment with European AI models in a real application rather than simply comparing benchmark numbers. The proof of concept is deliberately small, but the architecture could be extended considerably. The same approach could be applied to an organisation's internal knowledge base, customer support documentation, product information or regulatory material.

And that, ultimately, is what I find most interesting about RAG: it provides a relatively straightforward way of turning an existing body of organisational information into something that people can interact with conversationally — without having to build or train an AI model from scratch.

Copyright © Intuity 2026