Building a financial health chatbot with GenAI: The ING Challenge
By Julian von der Goltz
Introduction
Financial health plays an important role in how individuals and households experience stability in their daily lives and confidence about the future. It affects not only people’s ability to manage their finances or cope with setbacks, but also their emotional wellbeing, stress levels, participation in society, and capacity to make long-term choices. When financial pressure is high, attention often narrows to immediate financial matters; when it is lower, there is more room to engage with broader issues, from education and community life to sustainability.
Against this backdrop, we joined forces with ING – one of our founding partners – to address financial health as a shared societal challenge. In the Netherlands specifically, research shows that 47% of Dutch households are financially vulnerable or financially unhealthy. This highlights the scale of the issue and the need for accessible support that can reach people early and at scale. For many, seeking help is further complicated by feelings of shame or reluctance to discuss personal financial situations, which can delay or prevent timely support.
Creating a solution that strengthens financial health helps meet this need, contributing to reduced stress, improved wellbeing, and greater social participation, while also solidifying the relationship between ING and its customers. In this project, we explored how an AI-powered chatbot could play a role in providing such support.
Lowering the threshold to financial health support with AI
While many people experience financial challenges at some point in their lives, the threshold for seeking in-person help, such as booking an appointment with a financial coach or the Financial Health Desk, is high. Limited time, feelings of shame, discomfort with in-person conversations, or the overwhelming nature of financial concerns can all make it harder for people to take that step – even if they are in regular contact with their bank for different financial services.
This creates an opportunity to rethink how financial health support is offered. Support that is accessible, low-threshold, and available when people need it most can make it easier for individuals to seek guidance. A generative AI chatbot offers the potential to function as an anonymous channel and to provide this form of assistance in a scalable and consistent way, reaching more people than traditional one-on-one interactions.
At the same time, offering financial health support through an AI chatbot is far from straightforward. The sensitive nature of personal finance, combined with technical difficulties, introduces several challenges that make this problem particularly interesting to solve:
Emotional intelligence and personalization
Conversations about financial health are often nuanced and highly personal.Traditional, rule-based chatbots are ill-suited for this type of interaction, as they struggle with unpredictable dialogue. This project required a chatbot capable of:
Understanding context: Establishing a deep understanding of the user's financial situation through conversation alone, as it would not have access to private data like bank transactions.
Interpreting user sentiment: The generative AI approach was necessary to engage in fluid, human-like dialogue.
Personalizing the experience: Adapting the bot’s responses to the customer’s tone and style(e.g., formal vs. informal, empathetic vs. factual) while strictly preserving anonymity.
Financial language and literacy
Lower financial health often coincides with lower financial literacy. As a result, complex financial concepts and terminology need to be explained in clear, accessible language, ensuring a consistent and positive user experience, regardless of the user’s financial and digital literacy
Scattered educational resources
Educational information around financial health is currently scattered across various sources, including the ING website, and external sites like NIBUD.nl, Geldfit.nl, and WijzerInGeldzaken.nl. Rather than adding yet another information source, the opportunity was to bring these resources together in a single conversational interface.. A Retrieval-Augmented Generation (RAG) approach was used to ensure that the chatbot retrieves the relevant, up-to-date information needed to provide accurate and reliable answers.
The challenge
The complexity of offering meaningful financial health support with generative AI called for a different way of working. Rather than treating this as a narrowly defined machine-learning task, the goal was to explore how an AI-powered chatbot could function in a realistic, end-to-end setting – taking into account usability, trust, evaluation, and safety in a sensitive domain.
To explore this, we set up a “challenge” together with ING. A KickstartAI challenge is a structured two-week hackathon where participants from our team and our partner organizations work together on a concrete problem.
This particular challenge was intentionally set up differently from previous editions. Traditionally, KickstartAI challenges focus on improving model performance using a provided dataset and evaluation script. Participants train models and compare results against fixed evaluation criteria. But in this particular case, this approach wouldn’t be sufficient. Instead, the objective was to build on an early-stage chatbot prototype and develop it into a more mature application using generative AI, with real-user deployment in mind.
This shift fundamentally changed the core of the challenge. Rather than spending time on data preparation and baseline implementations, participants could concentrate on the aspects that matter most in a real financial health setting: personalization, conversational quality, evaluation strategies, safety mechanisms, and integration with trusted information sources.
In total, 14 data scientists, customer journey experts, machine learning and software engineers from ING, KickstartAI, KLM, NS, and Ahold Delhaize worked together during the challenge.
The provided prototype application came with:
A backend: the heart of the application that runs on an isolated server and connects to Google’s Gemini LLM.
A frontend: the page that users see in their browser with a chat box similar to known chatbots like ChatGPT or Gemini.
The application was configured to run in a dedicated Google Cloud environment. Anyone from the challenge and ING could easily test it without software engineering skills required. Consequently, we opened this challenge up for non-technical participants from ING, like customer journey experts, to bring in business and user knowledge.
We divided the group into four teams that worked on different components of the chatbot. These “work packages” that the teams focused on were:
Evaluations: For any machine learning or AI system, we need to know how well the system is doing. Is the chatbot giving correct answers? Is it adding links to the sources to the answer? Is the tone appropriate?
To answer these questions, an evaluation system has to be put in place where we have so-called “ground truth” conversations with example questions and expected responses. The example questions are run through the chatbot and with evaluation criteria, we compare the chatbot answer with the expected answer and give it a grade.Understanding & Informing: A key characteristic of the financial health chatbot is the way it understands and informs the users about financial health. How should it answer a question given the user’s situation? How should it adapt its tone to suit the user? How to formulate the answer to make it understandable?
Tool Use and Retrieval: The financial health chatbot does not simply give answers out of its own “memory,” as they could be outdated, missing specific context, or simply wrong (what would be called a “hallucination”).
The answers have to be factual and come from the approved websites. Therefore, the chatbot has to “retrieve” the relevant information from these websites. In addition, to make sure the chatbot returns correct numbers, it needs to access calculators that perform exact calculations for the chatbot. The retrievers and calculators are called “tools” that the chatbot can use.Guardrails: A chatbot could theoretically answer any question, because it is trained on a vast amount of knowledge. If you give it a closer look though, it won’t answer certain questions, and refuse or deflect instead. The obvious ones are questions that could be used to harm people, like asking how to build a bomb. In our case, we also don’t want the chatbot to talk about topics outside of financial health. The policies of what questions and topics to allow and refuse are called the guardrails.They make sure that the chatbot stays within a certain range of allowed topics.
Results
The results of the challenge closely follow the work packages described above. Each subsection below reflects the outcomes of one of these work packages, highlighting both what was built and what was learned during the two-week challenge.
Work package 1: Evaluations
In machine learning and deep learning, an evaluation setup typically consists of two elements:
An evaluation dataset with example inputs (user questions and conversation history) and expected outputs (the ideal answer that the chatbot should give, with the correct information, tone, verbosity, etc). Each combination of question, history, answer is treated as a test case.
A set of metrics or criteria that determine how well the actual output matches the expected output. These metrics are derived from the system requirements and should reflect the usefulness of the chatbot for its different stakeholders, including users and ING.
Whenever changes are made to the chatbot – for example to its instructions or to how information is provided – the full evaluation pipeline is run to assess if the chatbot improves. But improvements in one area can often lead to regressions in another, so it is important to track results across individual test cases and criteria. To support this, we used MLflow to manage evaluations and compare results over time.
Evaluation Dataset
Ideally, the evaluation dataset would consist of real conversations from real users. Unfortunately, this wasn’t possible for two reasons: protecting user privacy, and the fact that there isn't yet a deployed financial health chatbot from which we could get these conversations.
To solve this, we generated synthetic conversations. Writing these manually proved time-consuming and did not scale well, as it is difficult to realistically simulate a broad range of users and situations. Instead, we used an LLM that “simulates” a user.
We compiled a list of possible user personas (different ages, different financial and digital literacy, different occupations) and scenarios in which a user would contact a financial health chatbot (for example, a life event like job loss). These personas and scenarios were fed to the user-simulator LLM, which then generates questions for our chatbot.
From simulated data to realistic conversations
Although this approach enables scalable data generation, simulated users are not perfectly realistic. For example, the LLM simulator tends to write with perfect grammar, spelling and punctuation, whereas a real user would be more inconsistent. Sometimes, the simulator also repeats itself or asks meaningless questions.
Therefore, the simulated questions have to be checked and – if necessary – corrected. To do this in an efficient way that doesn’t require coding skills, we built a small helper app called the Conversation Editor. This tool allows reviewers to adjust both the simulated user questions and the chatbot responses, correcting errors and improving realism.
With this tooling in place – the personas, scenarios, simulator, and editor – we were able to create many diverse conversations to evaluate the chatbot on. During the challenge, the participants could generate additional conversations to test new features. These new conversations were also used to make sure that certain bugs or unexpected behavior in the chatbot answers would be caught. They were then added to the evaluation dataset.
At the same time, customer journey experts and a dedicated conversation specialist were continuously testing the chatbot and adding new conversations to the dataset. The focus of those conversations was to evaluate the tone and style of the answers, rather than factuality and correctness.
Evaluation Criteria
In traditional machine learning and deep learning, evaluations are relatively straightforward: the model output is compared to an expected output, and the result is marked as a pass or fail. However, with generative AI this process is harder.
A chatbot can produce a correct and useful answer even when its wording differs from the expected response, and many evaluation questions require subjective judgement. For example, did the chatbot provide financial advice, or did it merely inform the user about available options?
In an ideal setting, such evaluations would employ human expert graders that judge the chatbot responses. In practice, however, it’s impractical to ask a human to assess dozens or hundreds of questions and answers every time you make a small change.
LLMs-as-judges
Therefore, we opted for an automated solution. One approach was using LLMs that are instructed to automatically judge the output of the chatbot – essentially acting as a proxy for human judges.
Initially, the set of judges were set up based on the project requirements. Over the course of the challenge, additional judges were introduced based on issues observed during development. For example, at some point the chatbot forgot previous messages in a conversation and greeted the user again midway through the conversation. To make sure that this did not happen again, the team added the “coherence judge.”
Here are some examples of the LLM-based judges we used:
Follow-up questions: Does the chatbot ask exactly one follow-up question, either to gather more information or to keep the conversation flowing? Is the follow-up question relevant? This ensures that the chatbot doesn’t give premature solutions or delay providing a clear answer.
Coherence: Is the chatbot’s answer coherent with the rest of the conversation? Does it stay consistent in its role and tone?
Non-Advice: The LLM judges if the answer stays clear from giving specific financial advice but instead informs and educates the user about their options. This is critical for risk mitigation and legal compliance.
Tone: Checking that the chatbot response matches the tone, style, and voice of the user. This evaluates how well the chatbot handles aspects like formality, empathy, and directness to give a consistent and positive User Experience.
Deterministic evaluation metrics
There are limitations with LLM judges, however. They suffer from the same shortcoming as the chatbot itself: the variability in their responses and bias. They can occasionally produce outright wrong evaluations or misunderstand the user intent, or the intent of the expected response. Additionally, they can be relatively slow (and expensive) to run: having 10 judges, requires 10 requests to an LLM judge to evaluate a single chatbot answer. This directly impacts the speed of iteration and development feedback, which can be crucial in a two-week hackathon.
Therefore, the team came up with non-LLM based metrics that are fast to run, reproducible, and deterministic. For example:
URL checker: Checks that the links in a reply do actually exist in the retrieval database.
Readability: Uses the Flesch Reading Ease score to determine how readable a chatbot reply is. We aim for a score of 70, which corresponds to 7th grade reading level.
Word count: Simply counting the words in the chatbot reply to see if the bot keeps it concise.
In practice, LLM and non-LLM based metrics were used together to get a holistic picture of the evaluation.
At this point, it is nevertheless worth mentioning that evaluations alone are not sufficient to create a reliable chatbot system. LLMs can generate plausible answers even when their input is corrupted due to a bug in the code, as in one instance when the chatbot started greeting users again mid-conversation. Such issues can remain silent unless they are explicitly tested for, making classical software best practices, such as unit testing and monitoring, more important than ever.
Throughout the challenge, the evaluation team monitored the work of the other teams to ensure that the whole group made progress. New features often introduced new issues, which in turn led to the addition of new test cases and judges to monitor those problems and implement fixes.
As a result, the actual evaluation scores kept fluctuating significantly during the challenge. This was because the evaluation framework itself was not fixed but constantly changed together with the capabilities of the chatbot, becoming progressively stricter as more test cases and judges were added.
Consequently, although we made a lot of qualitative improvements to the chatbot, the evaluation scores over the two weeks do not directly reflect that. Nevertheless, the work of the evaluation team was invaluable as it provided guidance and feedback to the other teams.
Work package 2: Understanding and Informing
The “Understanding and Informing” team was key in customizing the chatbot. The first step to tailoring a generic chatbot to a specific context is to write a system prompt that instructs the chatbot about its role, its tasks, boundaries, and capabilities.
The core objective of this work package was to:
Understand: Establish a deep understanding of the user's financial context, especially when they are in severe financial distress. Obtain this information purely through empathetic conversation.
Inform: Educate them with relevant and accurate financial knowledge.
Personalize: Adapt the chatbot's tone and communication style (formal vs. informal, empathetic vs. factual) to the user’s style of communication while preserving their anonymity.
In collaboration with ING’s conversation specialist and the evaluation team, this team formulated explicit prompts to instruct the bot to adapt its answer tone based on the detected user persona. The team adopted an investigation strategy to ask only one focused question at a time to avoid overwhelming the user and to gather the minimum necessary information for a hand-off or a tailored response (the "One Question" rule).
Prompting – even begging – the chatbot LLM to only ask one question at a time didn’t convince the chatbot to do so. Very often it would ask multiple questions. To address this, the team found a simple trick: instead of letting the chatbot generate free text, they enforced a structured output that allowed only the following three components:
Reasoning: The LLM generates a step-by-step approach to analyze the situation and give an answer. This is not shown to the user.
Response: The main answer containing the requested information.
Follow-up question: The follow-up question to ask.
By enforcing this structure, the chatbot consistently asked only one follow-up question. Additionally, the response quality also improved because the LLM had room to create a plan and reflect on its instructions in the reasoning stage, before creating a response. This technique is known as “chain-of-thought”. Current LLMs perform this reasoning (also called “thinking”) automatically and don’t have to be prompted to do so. However, that process can not be controlled, which is why we made it explicit in the chatbot output structure.
Multi-agent Architecture
Writing a single prompt for all the different scenarios and edge cases can lead to an overly large system prompt, which may contain conflicting instructions that can confuse the chabot. Therefore, the team set up a multi-agent architecture in collaboration with the “Tool Use” team. In this architecture, each user question is forwarded to a chatbot “within” the chatbot (a so-called “subagent”). Each subagent is responsible for a specific topic, such as mortgages, investments, or credit cards. These subagents have their own prompts and also their own specific tools (see Tool Use).
In addition to the topic-specific subagents, the team added a “customer intake” subagent, responsible for gathering information about the user’s situation. This agent is the default agent being activated if the topic or the intent of the question is not yet clear.
But how do we decide which subagent to invoke for a certain user question? We can use another agent! For every user question, the conversation is passed to a faster language model that has only one task: return the name of the subagent that should process this question. We call this the “routing agent.”
One special type of agent in our architecture is always active: the RAG (Retrieval Augmented Generation) agent. This agent generates search queries for the retrieval engine to fetch websites that are relevant to the user question. Every chatbot answer should be grounded in a website, which is why the RAG agent is constantly active – while for simple inputs like “Hello!,” it can also decide not to perform a search.
Introducing multiple subagents created a new challenge. Each subagent required instructions for answer style, which led to duplicated prompt content and, over time, inconsistent responses across subagents. To resolve this, the team added a “final answer agent.” This agent synthesizes the information collected by the subagents as well as website snippets from the RAG agent. It then formulates a concise, understandable response that is sent back to the user. The prompt for the final answer agent includes instructions for the tone, style, and structure of the response.
Work package 3: Tool use & Retrieval
Tools are pieces of software that the chatbot can use to perform a certain task, such as calculations, information retrieval, or even scheduling appointments. For each user input, the chatbot can decide whether it can answer directly or whether a tool is required. If a tool is needed, the chatbot generates the input for that tool. The tool is then executed and the results are fed back to the chatbot. Based on these results, the chatbot can either generate a response for the user or decide to invoke another tool, repeating this process as necessary.
Each of the six agents has access to a specific tool set which it needs to perform its duties. In total, the team implemented 22 tools during the challenge.
For a financial application for example, calculators are an important tool as language models are not reliable with math. Current LLM models can do simple calculations like additions and multiplications but struggle with exponentials like compound interest calculations for investment returns.
Retrieval
Retrieval refers to the process of collecting approved websites that are relevant to the user question and can provide this information to the chatbot, so it can generate a response with verifiable sources
Subsequently, the websites are fed to the chatbot so that it can generate a response with sources that the user can check.
Initially, retrieval was implemented as a tool that individual agents could invoke when needed. However, because every informational response needed to be grounded in trusted sources, we didn’t want to rely on the chatbot or the subagents to decide whether they would use the tool. This is why we added a dedicated retrieval subagent (the “RAG agent” mentioned above) which is invoked for every user interaction and generates a retrieval query for the retrieval engine.
For the retrieval engine we had several options at the start of the challenge:
A self-hosted vector database that is integrated with the chatbot application
A vector database hosted by Google Cloud (Vertex RAG)
A hybrid text search and vector search database, also hosted on Google Cloud (Vertex AI Search)
The retrieval corpus consisted of a collection of websites from ING.nl, Geldfit.nl, Wijzeringeldzaken.nl, NIBUD.nl that we downloaded, cleaned from cookie banners and irrelevant layout elements, and saved as text files.
To determine which retrieval engine performs, the team created an evaluation pipeline that used synthetic question-answer pairs, generated from the retrieval corpus with the following methodology:
Source Document Sampling: We selected a diverse and representative set of websites from the knowledge base. For each selection, we identified a few paragraphs or "chunks of text" that are thematically or contextually related. This ensures that the generated questions require a multi-website or multi-chunk synthesis to answer.
Question and Answer Generation: We employed an LLM to analyze the selected, related chunks of text. The LLM's task was to:
Generate a Question: Create a complex, natural language question that requires synthesizing information from the selected chunks to form a complete answer. These questions should simulate genuine user queries.
Mark the Source: The original chunks of text that contain the necessary information to answer the generated question must be explicitly marked and associated with that question-answer pair. These marked chunks serve as the "ground truth" source for validation during the retrieval phase.
Scaling the Process: This process must be repeated a substantial number of times to create a diverse evaluation dataset. The goal is to cover various document topics, question types (e.g., factual, comparative, descriptive), and levels of difficulty.
Retrieval Metrics:
Recall: This metric measures the retrieval system's ability to retrieve all relevant pieces of information necessary to form a correct and complete answer.
Precision: This metric measures the efficiency and accuracy of the retrieval system, focusing on minimizing noise and irrelevant context.
Together with the evaluation system, the agent team concluded that Vertex AI search provided the best results. This is not surprising, as it is based on the very same technology that Google Search is based on as well.
Work package 4: Guardrails
Developing a chatbot for a financial institution presents unique challenges because the topic is both personal and sensitive. It should provide helpful information to vulnerable customers without crossing ethical, regulatory, or operational boundaries.
Guardrails, defined as rigid safety mechanisms, are necessary to contain the chatbot's unpredictable generative capacity and ensure it remains helpful without becoming illegal, unethical, or starting to hallucinate.
The primary objective was to secure the chatbot against six specific risks:
Regulatory Risk (Financial Advice)
Guarantee the chatbot informs and educates but never advises. The objective is to detect and block responses that contain specific financial recommendations.
Privacy Risk (PII)
Safeguard customer data in line with GDPR and ING guidelines. The objective is to identify and redact Personally Identifiable Information (PII) from user inputs (e.g., names, addresses, IBANs) to prevent sensitive data from being processed or stored.
Ethical Risk (Bias)
Prevent harmful stereotypes and bias in chatbot responses. The objective is to monitor and filter output to ensure the chatbot uses neutral, inclusive language.
Brand Risk (Competitors & Ads)
Protect ING's reputation and commercial interests. The objective is to prevent the chatbot from mentioning competitor banks or advertising specific commercial third parties.
Reliability Risk (Link Hallucinations)
Eliminate "link hallucinations" to maintain user trust. The objective is to verify that every URL provided by the chatbot actually exists and is accessible.
Scope Risk (On-Topic)
Restrict the chatbot on financial health use cases. The objective is to detect off-topic queries and steer the conversation back to the core topic.
Simple keyword filtering was deemed insufficient for creating robust guardrails, as it lacks the understanding required to detect nuance, or context. Instead, the team implemented an LLM-as-a-Judge framework, very similar to the LLM judges in the evaluation team.
There are two types of guardrails:
The input guardrails that guard our application against malicious or unwanted user inputs. Examples are questions about unrelated topics or even attempts to “jail-break” the chatbot, where a malicious user tries to coerce the chatbot into undesired behavior.
The output guardrails that check the output of the chatbot, in this case specifically the final answer agent. This is where we check for unwanted financial advice or biases in the responses.
For each guardrail, smaller, specialized language models with a singular clear purpose act as a guarding layer. These "Judge" agents evaluate the user’s input and the chatbot’s draft output against the pre-defined safety concerns. The process is broken down into three steps:
The Draft (Hidden): The message (user question or chatbot answer) is intercepted and temporarily held.
The Trial (The Judge): A separate, specifically instructed AI evaluates the text against the guardrails.
The Verdict (Shown): The guardrail judge issues a verdict.
Safe: The message is released.
Unsafe: The message is redacted, refused, rephrased, or adjusted before being sent.
Let’s look a this process for the PII handling: The system detects specific entities (Names, IBANs, Addresses) and replaces them with placeholders ([REDACTED_NAME]) or generalizes them (Age 50 → [range_age: 50-60]) before the conversation is processed by the main chatbot model.
You may ask yourself now: How can I get useful, customized answers if the chatbot is not allowed to give financial advice or can see any personal information?
This was indeed an ongoing dilemma during the challenge, and we concluded that for the sake of the final demonstration, we could push the envelope further and relax some of the strict requirements like the PII filtering.
Conclusion
Over the course of two weeks, 14 participants from across KickstartAI's partner companies turned a basic chatbot prototype into a financial health assistant. The resulting system could address the challenge of making financial support more accessible by lowering the barrier to entry through an anonymous, empathetic AI interface.
The technical innovations developed during the challenge – the multi-agent architecture, the evaluation framework combining LLM and non-LLM judges, the retrieval system, and the guardrail approach – represent more than just engineering achievements. They demonstrate how generative AI can be responsibly deployed in sensitive domains like personal finance. By separating concerns across specialized agents, enforcing structured outputs, and implementing multiple layers of safety checks, the team created a system that balances empathy and personalization with regulatory compliance and user privacy.
Perhaps most importantly, the challenge revealed that building reliable AI systems requires more than prompt engineering alone. The evaluation-driven development approach, the synthetic data generation pipeline, and the classical software testing practices proved essential for iterating quickly and catching issues that LLMs might otherwise silently mask. While tensions remain – between personalization and privacy, between usefulness and compliance – the foundation is in place for a chatbot that could meaningfully support the 47% of Dutch households facing financial vulnerability, while also helping everyone stay informed about their financial health, both now and in the future.
Lessons Learned
One agent, one job: Multi-agent architectures with specialized subagents outperform monolithic prompts, reducing conflicting instructions and improving response quality.
Structure beats begging: Enforce structured outputs (JSON) rather than prompting the LLM to follow rules – it's the difference between "please ask one question" and making it impossible to ask more.
LLMs hide bugs: Generative AI can produce plausible responses even when code is broken, making classical testing (unit tests, monitoring) more critical than ever.
Synthetic data needs human touch: Generated evaluation datasets are scalable but require human review and correction to be realistic and useful
Fast feedback loops win: Combine quick non-LLM metrics (word count, readability scores, URL validation) with slower LLM judges to maintain development velocity.
Let them think: Explicit chain-of-thought reasoning in agent outputs improves instruction-following and response quality – make the hidden reasoning visible and structured.
Evaluation drives everything: Building the evaluation framework alongside the chatbot, not after, enables rapid iteration and prevents regression.
The personalization paradox: There's an inherent tension between creating helpful, empathetic, personalized experiences and maintaining privacy, professionalism, and regulatory compliance – acknowledge and navigate it explicitly.