I have identified the problem as lead screw backlash.  Bed calibration and Z axis offset compensation appears to be working as intended, but there is enough backlash in the Ender 3 stock lead screw that the corrections in Z axis movement commanded by Klipper result in almost no actual nozzle movement.  I'm measuring about 0.35mm of backlash in my lead screw.  With differences between the lowest and highest points of my bed being only 0.6mm the best case scenario (which would only happen if I was using my entire bed) is that the actual nozzle movement would only be about 58% of what Klipper commanded.  The fix for this is to change out the lead screw for a ball screw.  The problem could also be mitigated in Klipper if Klipper implemented backlash compensation, but from what I've read on Git Hub it doesn't seem like that is a feature the developer of Klipper wants to implement.  See https://github.com/KevinOConnor/klipper/issues/2040.