Design of information systems in the age of AI
Many enterprises are facing a very similar problem these days. This is the problem of how to use AI to open up a freer exchange of information across the enterprise, between enterprises and with customers. Here I will discuss some high level design elements that should aid in making this effective.
The goal is not only to make more information available but make the user experience of attaining that information consistent, safe and secure. In addition, we want a design that allows for effective application development that maintains a seamless character. The information should be the same regardless of application or channel though perhaps presented differently based on context or channel limitations. Finally, there is the need for effective governance that doesn’t interfere with application development productivity.
Uses of Gen-AI in information systems
Gen-AI in particular provides a number of advances in productivity for accessing information. These include:
A high level design
There is a natural inclination to simply let application developers handle all aspects of this as they experiment and see what users want. This might be appropriate in the very beginning but there will soon be a need to reign this in before the complexity grows out of control. Multiple application development teams that give us similar information will have little ability or incentive to cooperate to ensure this seamless character that will be desired. When problems arise from discrepancy in data, they will need to solve such problems bilaterally. At scale, this is a recipe for chaos, endless debugging and excess coupling which will drive complexity and eventually rigidity and low productivity. It would be advisable to think hard about creating an enterprise wide strategy about preventing this poor outcome.
Well known, fundamental principles of good engineering can be used to keep such problems in check. The key ones are well defined domain boundaries, single point of responsibility and component reuse.
In this diagram below, I show an example architecture. The gray components or domains are meant to be reusable by all. The individual applications in orange provide different purposes and different communication channels. Those channels could be webpages, mobile apps, chatbots, voice bots, phone calls etc. The purposes could be as wide as: learning about the company and its products/services,? checking private user information such as bank balances, updating an address, requesting a change in prescription, making a purchase etc.
The key thing here is that we have a single component with a single purpose that is reused across the industry. Authentication is an example which is already handled in this fashion by most companies. But we can extend this to the process of requesting information. Usually we let applications decide when to get information, how to get information and where to get information. Each application repository will often have a directory full or queries or query templates. Sometimes we take more of a data platform approach and provide APIs that will be used by multiple applications. This way we can abstract the details of where the data actually is, how it is internally structured and how it is accessed. This allows for internal refactoring and clean separation of concerns. An API is simpler than a SQL script but still involves knowledge of what URL to use, what to provide and how to interpret the result.
Changes required for Gen-AI: security and safety
Gen-AI however adds some new possibilities. Normally, whether with direct database access or data platforms, we assume static queries. We might allow for some dynamism through parametrization. But these will be well defined APIs where the dynamic possibility is limited to the parameters expected by the API.
Gen-AI allows for far more dynamism in seeking information. With this comes great power, but also risk.
There are well known risks such as SQL injection, where a hacker fills out a form element in a clever way. Imagine the SQL template is:
?SELECT * FROM users WHERE username = 'admin' AND password = {input_password}
And then the input_password is filled in with whatever comes back from the UI form and this is run in the database. If the hacker types in the password field as: “'password' OR '1'='1';” this will allow for admin access without actually providing the password. There are well known solutions to this problem. You should not simply interpolate user provided text into SQL templates and blindly run them. There are safe ways to do it but this is not one of them. Rookie mistakes like this are, unfortunately, still made by development teams every day.
Gen-AI will have this same problem though it will present in different ways. Regular LLMs exposed directly to an untrusted user can be coerced into doing almost anything and coerced into giving out whatever information it knows. So one must assume that any information held by an LLM is exposed to anyone who can chat with it directly. Clever prompt templates are no guarantee of preferred behavior. This might imply for example that separate LLMs need to be created to hold some subject of information that together as a unit is either all available to a user or all unavailable (at least through this data source).
领英推荐
The idea of users asking questions and then an LLM creating SQL code on the fly is both amazing from an application perspective and frightening from a security standpoint. There is so much value that can be created here that there is a strong incentive to figure out how to do it right and make it safe. Whatever that solution is, it must be the full time job of specialists and done in one place within the information landscape.? It can’t be done willy-nilly all over the place within multiple applications. If a common attack is discovered, you want to fix it in a single place rather than having to scour every repository looking for the weakness.
Making app development easier
Beyond removing security responsibilities from applications, the idea of creating centralized information access components also makes their job easier and removes rework. Natural Language Understanding (NLU) for example can be its own component with its own team that supports applications. So for example, a voicebot application through a phone call channel might have a user that asks the question. “Can I have my bank balance?” Another user on a web-channel chatbot might ask the same question as “What’s my bank balance?” or more complex questions like “Show me my minimum bank balance, daily, over the past 6 months”. If this works, and is valuable, consider how much money will be saved by not having to have a developer create this particular static dashboard.
Imagine that both these applications only need to recognize this as a request for balance information. They should know that they need to authenticate the user and know how to initiate that process if it hasn’t occurred already. They now send off the user text message to the information seeking domain along with the authentication token. If the token is absent or incorrect, the information domain sends back an error message along with information on how to authenticate. The application can decide how to handle the error or perhaps pass along the correct authentication procedure to the user and wait for the continuation of the conversation.
The information seeking domain, not the application, now tries to determine what it is exactly that the user wants. They decide whether their authentication is valid in that context. They also decide whether the channel is secure enough to pass the information. Phone perhaps is not considered safe for some information even if you trust that it is indeed the user on the other end. They also act as another gatekeeper to the information. We don’t always want to give out information even when it is about the user. We also might not want to give out information unless we are confident that the application will not present it confusingly. That might involve communication between an application team and the information request team.
This process could be a combination of NLU/NLP tools as well as rules based code. If it decides the information can be returned, it will initiate the request to the information provisioning domain. It might act like an orchestrator for sending multiple individual requests. It will take the returned information, transform it and restructure it into a common data format to return to the applications.
The information provisioning domain has the responsibility of actually taking these requests and finding the information. This will include a number of normal static parameterized queries but also possibly some dynamically generated queries using LLMs, with particular concern for safety. This is also a refactorable component which can provide a static contractible API to the information request service while its own team makes whatever changes required that make it more effective and safe.
The purpose
The purpose of this kind of design is that it keeps the AI components out of the applications or at least the part dealing with data access and security. The application developer can focus more on the user experience. This may still involve use of an LLM but the LLM is just taking data structures of information and transforming them into content that makes sense for its purpose and characteristics. That is essentially a RAG model approach but the “Retrieval” part is outsourced to a specialized component.
For example, a voicebot cannot show you a table or chart, though this would be possible with a web/mobile chatbot. It needs to explain things in words and eventually its own voice. The voicebot might allow user input with key entry but cannot ask you to click on something or upload a file. These are presentation level / UX concerns of the application but they can all work with the same underlying data and data structures. The data request service only needs to output the data in that one common format. It might return some complex data that is used by some and ignored by others.
This separation of concerns makes the application developers job easier and the same for the information services.
Seamlessness?
A goal of the company as a whole should be that different applications and channels may be used by users (customers or internal employees) and while the presentation form may differ, the underlying data is the same. It’s the same because they all use the same information request service.
If this approach is not followed and each application can decide on where and how it will get data, you will have the situation where users might get conflicting information from different services. One might be the chatbot on the web page which says that tax forms are sent in January and another is an email saying they are sent in March. They will instead be forced to agree whenever the question “When are tax forms sent?” (perhaps stated in different ways) are sent to the same service. This same issue occurs with normal non-AI requests and this centralization has generally been used as the solution. We should do the same with AI powered applications.
Safety
This high level design is geared towards safety. It concentrates common safety concerns on one particular place. For example making dynamically created queries that are safe and effective is the job only of the information provisioning query service. Perhaps SQL can be used for this or perhaps it is deemed inherently unsafe in the dynamic creation environment, being too powerful of a language. Perhaps specialty databases such as knowledge graphs will be a better approach. However that is solved, it is solved within the provisioning service and need not trouble either the information request service or individual applications.
Conclusion
One goal of all of this is that when you “ask the company” something, you get the same answer no matter how you ask or what component you use to ask it. The other goal of this is to minimize complexity by keeping common functionality in one place. This is the best way to enable both sustainable, high productivity in application development as well as security and safety. There is an eternal trade off between centralization and “letting all flowers bloom” as they say. There is value in both. But when it comes to providing information, it is worth leaning on the side of centralization. You can’t easily put the genie back in the bottle once applications are up and running with custom data provisioning pipelines especially when applications become coupled with others. Letting this happen might be the fastest way to market but also creates technical debt that will have to be paid once problems arise; and they will. Gen-AI is a new technology. You don’t need to rush it. Take your time and do it right.