Reusability in MLOps: Leveraging Ports and Adapters to Build a Microservices Architecture for the Maritime Domain
Listen
Radio episode about this paper
Transcript
Introduction to the show: ident: AI Radio. Generated commentary on the latest Artificial Intelligence papers.
Tom: Next we'll be talking about the paper "Reusability in MLOps: Leveraging Ports and Adapters to Build a Microservices Architecture for the Maritime Domain".
Jane: The paper was written by Renato Cordeiro Ferreira, Aditya Dhinavahi, Rowanne Trapmann and Willem-Jan van den Heuvel from Jheronimus Academy of Data Science and Tilburg University and Technical University of Eindhoven.
Tom: Stay tuned as we take you through the paper and discuss its implications.
Title: Tom: Alright, welcome back to the show, everyone. Today we're digging into a paper that just hit arXiv, and it's called "Reusability in MLOps: Leveraging Ports and Adapters to Build a Microservices Architecture for the Maritime Domain." Jane, I gotta say, that title is a mouthful, but it's got me hooked already.
Jane: It really is, Tom, but the core idea is actually pretty simple once you unpack it. So, MLOps is all about managing machine learning systems in production, and the maritime domain means ships, ports, shipping lanes, that kind of thing. The paper is about how to build these systems so you don't have to reinvent the wheel every time you add a new feature or a new service.
Tom: Right, and the authors are from Tilburg University and TU Eindhoven, plus a bunch of collaborators. They built this tool called Ocean Guard, which is basically an anomaly detection system for maritime data. Think illegal fishing, smuggling, ships going off course, that sort of thing.
Jane: Exactly. And the clever part is how they structured the code. They use something called the Hexagonal Architecture, which is also known as Ports and Adapters. I can explain that in plain terms, Tom. Imagine your software is a house. The core business logic is the living room, where all the important decisions happen. The ports are like the doors and windows, the openings. And the adapters are the specific things you put in those openings, like a door that fits a specific frame or a window that fits a specific wall.
Tom: So the living room doesn't care if it's a sliding door or a hinged door, as long as it fits the opening?
Jane: Exactly. The core logic doesn't care if the data comes from a database, a sensor, or a third-party vendor. It just knows it needs to receive data through a port. The adapter handles the specifics of talking to that particular data source. That's the whole trick.
Tom: And that's what makes it reusable. They built this whole system in a single code repository, a monorepo, and they can spin up different microservices just by picking and choosing which ports and adapters they need.
Jane: Right. So you have one service for ingesting data, one for processing it, one for detecting anomalies, one for the API. They all share the same underlying building blocks, but each one has its own core logic and uses a different subset of the available adapters.
Tom: It's like having a box of Legos. You can build a car, a house, or a spaceship, all from the same pieces, just arranged differently.
Jane: That's a great way to put it. And this paper is essentially a report on how they did it, the challenges they faced, and the lessons they learned. It's an experience report, so it's not a theoretical paper. It's about what actually worked in practice.
Tom: And I love that. It's real-world engineering wisdom. Now, I want to bring in Lu from Tsinghua, because I know you have strong opinions about architecture patterns like this. Lu, what do you make of this approach?
Lu: Thanks, Tom. I think this is a really pragmatic application of a well-known pattern. The Hexagonal Architecture has been around for a long time, but applying it specifically to MLOps systems is smart. Machine learning systems are notoriously messy because you have data pipelines, model training, serving, monitoring, all these different concerns. Keeping them decoupled is a huge win.
Tom: And they're not just talking about it, they actually built it. The paper includes a reproduction package with example code. That's a big deal for reproducibility.
Lu: Absolutely. It means someone else can look at their implementation and learn from it, or even adapt it for their own projects. That's how the field moves forward.
Jane: And that's exactly what we're going to dig into next. We'll look at the actual system architecture and how these microservices fit together. Stay with us.
Summary: Tom: Welcome back. We're still on "Reusability in MLOps: Leveraging Ports and Adapters to Build a Microservices Architecture for the Maritime Domain." So Jane, we've talked about the general idea, but let's get into the actual system. What did they build?
Jane: So Ocean Guard is composed of a bunch of microservices, and they're grouped into seven subsystems. There's Data Acquisition, which collects data from various sources like sensors and third-party providers. There's Continuous Training, which keeps the models fresh. There's Serving, which runs the anomaly detection. And there's also Data Fusion, Application, Monitoring, and Development.
Tom: And they all interact in a pretty specific flow. You start with the Data Ingestor, which pulls in raw data and stores it in a data lake. Then the Data Processor cleans it up. Then the Data Loader organizes it into a data warehouse and also sends messages to a broker to trigger anomaly detection.
Jane: Right. And the Anomaly Detector is interesting because it has two flavors. There's a pipeline for scheduled predictions, like running a batch job every night, and there's a service for near real-time predictions. So they cover both use cases.
Tom: And then the API serves all that data to a web application for users to see. So the whole thing is a pipeline from raw data to actionable insights.
Jane: Exactly. And the key point is that all these microservices share code. They're in a single monorepo, and they reuse the same ports and adapters. For example, the Data Ingestor and the Data Processor both need to talk to the data lake. They use the same storage adapter. The Anomaly Detector and the Data Loader both need to talk to the broker. They use the same broker producer and consumer adapters.
Tom: So instead of writing new code for each service to talk to the same database, they just reuse the same adapter. That's the reusability in action.
Jane: Precisely. And they have a whole list of adapters they've built. There's one for cache, one for database, one for model serving, one for metrics, one for web, one for settings. Each microservice picks the ones it needs.
Lu: And I think that's a really elegant way to handle the complexity. Each service has its own core business logic, but the infrastructure concerns are shared. It's like having a common toolkit that every team can use.
Meng: But I have to ask, as someone who actually has to run these systems, how does this work in practice? Like, if you have all these services sharing code, how do you avoid breaking one service when you update a shared adapter?
Jane: That's a great question, Meng. And it's actually one of the challenges they talk about in the paper. They call it "generality." When you have a port that's used by multiple adapters, it's hard to keep it specific enough for each use case but general enough to be shared.
Tom: And there's also the "separation of concerns" challenge. When does a piece of code become part of the core business logic, and when should it be an adapter? If an adapter starts doing too much, it's no longer thin and focused.
Meng: So it's a balancing act. You get reusability, but you also get coupling. If you change a shared adapter, you have to test all the services that use it.
Jane: Exactly. And that's why they have a Continuous Delivery subsystem that handles building, testing, and deploying all these components. They need to make sure that changes to shared code don't break anything.
Tom: And that's a perfect segue into the next segment. We're going to talk about the improvements they suggest and the lessons they learned. Stick around.
Improvements: Tom: Alright, we're back on "Reusability in MLOps: Leveraging Ports and Adapters to Build a Microservices Architecture for the Maritime Domain." So we've covered the architecture, the challenges, and now we get to the good stuff. What did they actually learn from this experience?
Jane: They have three main lessons, and they're all about the benefits of this approach. The first one is compatibility. Because they reuse the same ports and adapters across microservices that talk to the same external dependencies, it's much easier to keep them compatible. If the data lake changes its interface, you only have to update one adapter, and all the services that use it are automatically updated.
Tom: That's a huge time saver. Imagine having to update five different services every time a database schema changes.
Jane: Right. And the second lesson is extensibility. Because each microservice has its own isolated core, you can create new microservices pretty easily. You just pick the adapters you need, write the new business logic, and you're done. They even mention that they can extend the tool with new models, new data types, and new external dependencies.
Meng: So it's like a plugin system. You can add new functionality without rewriting existing code.
Jane: Exactly. And the third lesson is incremental development. The Ocean Guard tool is a complex system, but by using this pattern, they can develop and update it incrementally. They can add a new microservice, update an existing one, or swap out an adapter without disrupting the whole system.
Lu: And I think that's the most important takeaway. In machine learning systems, things change constantly. Models need to be retrained, data sources change, new requirements come in. If your architecture is rigid, every change is a nightmare. This approach makes the system resilient to change.
Tom: And they also mention future work. They want to keep developing and extending all the components using this approach. So this isn't a one-off project. It's a foundation for ongoing development.
Jane: Right. And the reproduction package is a big part of that. They've made their example code available on GitHub, so other teams can learn from their implementation. That's how the community benefits.
Meng: But I'm curious, Lu. Do you think this pattern would work for other domains, or is it specific to maritime?
Lu: Oh, it's definitely transferable. The maritime domain is just the use case. The pattern is about building MLOps systems in general. Any domain that needs to process data, train models, and serve predictions could benefit from this. Finance, healthcare, manufacturing, you name it.
Tom: So this could be a blueprint for a lot of different industries.
Lu: Absolutely. And I think that's the real impact of this paper. It's not just about ships and anomalies. It's about showing a practical way to build machine learning systems that are maintainable and scalable.
Jane: And that's a great note to end this segment on. We'll wrap up with our final thoughts in just a moment.
Conclusion: Tom: And we're back for the final segment on "Reusability in MLOps: Leveraging Ports and Adapters to Build a Microservices Architecture for the Maritime Domain." Jane, let's bring it all together.
Jane: So, to recap, this paper is an experience report from the team that built Ocean Guard, an anomaly detection system for maritime data. They used the Ports and Adapters pattern, also known as Hexagonal Architecture, to build multiple microservices from a single codebase. The core business logic is decoupled from external dependencies through ports and adapters, which makes the whole system reusable and extensible.
Tom: And they faced two main challenges: keeping the ports generic enough to be shared but specific enough to be useful, and deciding when code belongs in the core versus when it should be an adapter.
Jane: Right. But the lessons they learned were positive. They gained compatibility across services, extensibility for new features, and the ability to develop incrementally. And they've shared their code in a reproduction package so others can learn from it.
Lu: And I think the broader impact is that this provides a practical template for building MLOps systems in any domain. It's a way to manage complexity and keep things maintainable as the system grows.
Meng: Yeah, and as an engineer, I appreciate that they're not just theorizing. They actually built it and hit real problems. That's the kind of paper I can use.
Tom: Absolutely. And with that, we're going to say goodbye to this paper. It's been a great discussion, and I think we've covered the key points. Thanks to Lu and Meng for joining us, and thanks to all our listeners for tuning in.
Jane: We'll be back with the next paper soon. Until then, keep building, keep learning, and keep sharing what you know. See you next time.
Tom: Take care, everyone.
Renato Cordeiro Ferreira, Aditya Dhinavahi, Rowanne Trapmann, Willem-Jan van den Heuvel
Jheronimus Academy of Data Science · Tilburg University · Technical University of Eindhoven
cs.SE, cs.AI, cs.LG
Submitted: 2025-12-09
Updated: 2026-08-18
Comments: 7 pages, 3 figures (3 diagrams), submitted to ICSA 2026
Code: https://github.com/ocean-guard/pirate-guard
License: http://creativecommons.org/licenses/by/4.0/
Importance score: 40/100
The gist: This paper is an experience report describing the software architecture reusability techniques used to develop the OCEAN GUARD tool, an extensible Machine Learning–Enabled System (MLES) for anomaly
Key concepts
- Ports and Adapters (Hexagonal Architecture)
- This architecture structures software by separating the core business logic from external dependencies. The 'ports' represent the openings where the core logic interacts with the outside world, while 'adapters' are specific implementations that handle details like connecting to a database or sensor.
- Microservices
- The paper describes building MLOps systems using multiple microservices, such as data ingestion, continuous training, and anomaly detection. These services are grouped into subsystems but share the same underlying building blocks for reusability.
- Reusability
- The core idea is to reuse the same ports and adapters across different microservices. This means that if an external dependency, like a data lake interface, changes, only one adapter needs updating instead of many services.
- Monorepo
- The system was built in a single code repository (monorepo). This structure allows different microservices to share the same core code and reuse the same set of ports and adapters.
Terminology
Summary
This paper is an experience report describing the software architecture reusability techniques used to develop the OCEAN GUARD tool, an extensible Machine Learning–Enabled System (MLES) for anomaly detection in the maritime domain. The system's goal is to analyze and detect anomalies across multiple types of data
to address the challenge of illicit trade at sea.
The paper details how the development team applied the PORTS AND ADAPTERS pattern (also known as HEXAGONAL ARCHITECTURE) to implement multiple microservices from a single monorepo codebase. The OCEAN GUARD tool follows a reference architecture proposed by Ferreira, and its microservices are grouped into seven subsystems: Data Acquisition, Continuous Training, Serving, Data Fusion, Application, Monitoring, and Continuous Delivery. The system includes services such as the Data Ingestor (for data collection), Data Processor (for data cleaning), Data Loader (for data organization), Anomaly Detector (for ML-based anomaly detection), and API (for exposing data to clients).
The core of the implementation is the reuse of PORTS AND ADAPTERS across microservices. The paper states: To promote reusability and avoid redundancy, the OCEAN GUARD tool is implemented in a single repository (monorepo), allowing the sharing of common code between microservices.
The external dependencies supported by these shared ports and adapters include: Broker Producer, Broker Consumer, Cache, Database, Data Loader, Data Processor, Data Retrieval, Model, Metrics, Settings, Storage, and Web. Each microservice has its own core business logic and uses a different subset of these available ports and adapters.
The authors describe two main challenges encountered during development:
-
Generality:
Designing generic PORTS AND ADAPTERS that fit well in the context of multiple microservices can be hard.
A port should be specific yet dependency-agnostic, which becomes harder when a port has multiple adapter implementations. -
Separation of Concerns:
Choosing when a snippet of code should be isolated into PORTS AND ADAPTERS or become part of the CORE business logic can be hard.
An adapter should be distinct and thin, which becomes harder when an adapter handles complex, multi-step logic.
The authors also report three lessons learned from these challenges:
-
Compatibility:
By reusing the same PORTS AND ADAPTERS between microservices that communicate with the same storage, it is easier to make them compatible with the external dependencies.
-
Extensibility:
By reusing the PORTS AND ADAPTERS and isolating each individual CORE, it is easier to create new microservices that provide different functionalities.
-
Incremental Development:
By adopting the PORTS AND ADAPTERS pattern to implement its microservices, it is easier to incrementally develop and update the OCEAN GUARD tool, both on the architecture and application level.
The paper concludes that the reusability through the monorepo approach offers the possibility of extending the OCEAN GUARD tool with new models, data types, external dependencies, and ultimately new microservices.
The authors hope the report inspires software engineers, machine learning engineers, and data scientists to apply the HEXAGONAL ARCHITECTURE pattern to build their MLES.
A reproduction package with example source code is available at github.com/ocean-guard/pirate-guard.
Improvements for AI systems
Based on the scientific paper, here are the specific improvements I can make to AI systems, followed by what the improved system can do:
-
Modular AI Service Architecture: Implement a Ports and Adapters (Hexagonal Architecture) pattern for AI systems, where the core ML logic is decoupled from external dependencies (databases, brokers, APIs, storage). This allows the same ML core to be reused across multiple microservices without code duplication.
-
Reusable Port Definitions: Define generic, dependency-agnostic ports (e.g.,
Model,Storage,BrokerProducer,DataRetrieval,Metrics) that can be implemented by multiple adapters. This enables swapping out external dependencies (e.g., from a local database to a cloud data warehouse) without changing the AI business logic. -
Monorepo-Based AI Development: Structure the AI system as a single repository with shared Ports and Adapters, allowing multiple AI microservices (data ingestion, processing, anomaly detection, API serving) to reuse the same codebase. This reduces redundancy and ensures compatibility between services that communicate with the same storage or broker.
-
Incremental AI Service Extension: Design the AI system so new microservices can be added by reusing existing Ports and Adapters, without rewriting the core business logic. This supports adding new data types, models, or external dependencies over time.
-
Thin Adapter Isolation: Ensure adapters are thin and encapsulate a single external dependency (e.g., one adapter for the database, one for the broker). This prevents business logic from leaking into infrastructure code, making the AI system easier to test and maintain.
-
Deploy the same ML anomaly detection model across multiple services (e.g., scheduled batch detection and near-real-time detection) using the same
Modelport, without duplicating model-loading or prediction code. -
Swap data storage backends (e.g., from a local data lake to a cloud object store) by replacing a single
Storageadapter, without touching the ML core or other services. -
Add a new microservice (e.g., a data augmentation service or a synthetic data generator) by reusing existing
DataRetrieval,Storage, andMetricsports, reducing development time from weeks to days. -
Ensure compatibility between services that read and write to the same data lake or broker, because they share the same adapter implementations, eliminating version mismatches and serialization errors.
-
Monitor all AI services uniformly by reusing the same
Metricsport and adapter, enabling consistent telemetry collection across the entire MLES without per-service custom instrumentation. -
Incrementally evolve the system — for example, adding support for a new data source (e.g., satellite AIS data) by implementing a new
DataRetrievaladapter, while keeping the anomaly detection core unchanged. -
Reduce operational risk by isolating each external dependency in a thin adapter, so a failure in one adapter (e.g., broker outage) does not propagate into the ML core, and the system can degrade gracefully.
Abstract
ML-Enabled Systems (MLES) are inherently complex since they require multiple components to achieve their business goal. This experience report showcases the software architecture reusability techniques applied while building Ocean Guard, an MLES for anomaly detection in the maritime domain. In particular, it highlights the challenges and lessons learned to reuse the Ports and Adapters pattern to support building multiple microservices from a single codebase. This experience report hopes to inspire software engineers, machine learning engineers, and data scientists to apply the Hexagonal Architecture pattern to build their MLES.
Related papers
- Falsification-Based Verification of LLM-Generated Optimization Models: Sound Test Batteries and Their Detection Limits
- GitSkills: A Dataset of Agent Skills on GitHub
- SABER: Benchmarking Operational Safety of LLM Coding Agents in Stateful Project Workspaces
- PackMonitor: Enabling Zero Package Hallucinations Through Decoding-Time Monitoring
- IntentCoding: Amplifying User Intent in Code Generation
- Incentives and Outcomes in Bug Bounties