Predictability lets users anticipate an ML system’s behavior from the inputs and conditions they provide. For an API, it stands alongside simplicity as a core quality: callers should understand what controls an outcome and avoid surprising hidden behavior. section 13.1
Predictability does not mean hiding every option. A simple interface should conceal unnecessary implementation detail while exposing meaningful controls for customization and debugging. The practical balance is a small public surface with explicit parameters where runtime conditions matter. section 13.1
Design for predictable ML API behavior by:
- Making common calls short and understandable instead of requiring many interdependent parameters. section 13.1
- Passing relevant runtime conditions explicitly, such as time and random seed, rather than burying them inside the implementation. section 13.1
- Keeping controlled customization available for debugging and operational diagnosis. section 13.1
- Using layered APIs, separating ML logic from I/O where possible, and providing fallback behavior when the primary path fails. section 13.6
Figure 13.1 Overconfiguration vs. underconfiguration
Use the overconfiguration-versus-underconfiguration comparison to judge whether an API exposes too much complexity or hides controls needed for predictable operation. section 13.1
Listing 13.1 A mediocre design for a predict function
def predict(features):
time = datetime.now()
return model.predict(features, time, seed=42)
The mediocre predict function illustrates surprising behavior when time is created internally and the caller cannot control it. section 13.1
Listing 13.2 A better design for a predict function
def predict(features, time=None, seed=42):
if time is None:
time = datetime.now()
return model.predict(features, time, seed)
The improved predict function makes time optional and the seed explicit, preserving a convenient default while enabling repeatable calls and debugging. section 13.1

