I agree that the ai seems to really do tactical battles poorly.
Even when it has ranged units, it targets a catapult first, even though the damage to it is only a couple of damage points. Why not target my spell caster or mages that have little armor? Why not target units that have high attack and little armor? When fighting city battles especially, I (and most everyone probably) target the highest melee units with least armor for physical damage and slow, terror, magical damage the high armor units.
Also, I like to knock units down unit they are less effective and go to the next one so there won't be a 70hp+ attack from one of them. This allows me to heal/withdraw units so they don't die. The AI never seems to think about keeping units alive to keep their levels up.
This means by mid-game my armies have a huge advantage in experience and the ai has no armies with lots of armor and I just wipe them out.
One thing I feel would help is if the "healed" units wouldn't resurrect or at least lose some experience. By this I mean a 6 man unit down to 1 man left and heals naturally over time shouldn't resurrect the old dead, but be replaced by newer recruits. Probably with a penalty for metal, crystal, etc. That way the human player won't have such a large advantage over the ai. The ai armies tend to get wiped out, the human armies tend not to. That is what causes the resource/experience avalanche that dooms the ai most of all.
As to tactical battles
The ai needs to spread out the range units! That will keep the catapult, AOE spells from doing much! Also, I would like to see the catapult/area spells be less exact. By this I mean a catapult shot, fireball, etc targeted just behind the guys you are fighting won't ever hit yours currently. There is no way to be that exact! There should be an accuracy check that could move the actual landing location by one square in any direction. If you want to go further, make a malus to defense of a unit to getting hit from behind by ranged units. That will make a player think twice before firing so close to their own troops.
I would also like to see ranged units have a lesser, but similar chance to miss and potentially hit something else. I am pretty sure most melee troops would not like arrows flying past their shoulders when engaged with an enemy!
Obviously, as the original poster stated, it needs to do a calculation that if the other side has more range units with higher attack then it needs to go berserk and charge. Perhaps when it is "outgunned" by more than 1.5 to 1 in strength?