you are correct in that the past participle does not match the COD in the case of avoir
BUT (and there always is a but!)
except for the case when the COD precedes the particple, in which case it IS matched. Let's look at your example:
Nous les avons préparés. --"les" is the COD and precedes the participle ("préparés"). Since "les" is plural (and apparently not all female), the participle needs to take this into account --> "preparés".
-- Chris (not a anative speaker).