When caching affects externally visible payloads (prompts, auth/JWT inputs, token summaries), ensure the serialized representation used for cache identity is deterministic and the cache has an explicit validity boundary.
Practical rules:
Example: deterministic merge without map-key-order instability
func mergeDeterministic(base map[string]any, fallback map[string]any) map[string]any {
if len(base) == 0 && len(fallback) == 0 {
return nil
}
merged := make(map[string]any, len(base)+len(fallback))
keys := make([]string, 0, len(base)+len(fallback))
seen := make(map[string]struct{}, len(base)+len(fallback))
for k := range base {
if _, ok := seen[k]; !ok {
seen[k] = struct{}{}
keys = append(keys, k)
}
}
for k := range fallback {
if _, ok := seen[k]; !ok {
seen[k] = struct{}{}
keys = append(keys, k)
}
}
sort.Strings(keys)
for _, k := range keys {
if v, ok := fallback[k]; ok {
merged[k] = v
} else {
merged[k] = base[k]
}
}
return merged
}
If the cached payload must preserve ordering semantics (e.g., output_config), prefer an ordered representation (OrderedMap) instead of converting to map[string]any during merges.