Okay, well it's not AI so much, as that would be very difficult to code. Rather, it's more of a set of "Circumstance:Action" for sieging armies, so make the next siege harder. For example, if an enemy siege throws itself on your trapped corridor and dies, the next siege will bring wooden planks to lay over the traps and stop them from triggering. If you hole up inside your fortress and shoot arrows from fortifications, the sieging army will bring siege towers (which act something like a people-wagon, protecting them) to both climb the walls and block the arrows. If your entire defense consists of ballistae or catapults, they will send sappers to dig under the line of fire(this will require tunneling enemies first). If you send squads of melee troops out into combat with little or no backup, then the enemy will respond by sending lots of archers, etc.
Basically, the goal is to make sieges less predictable and more variable. There is no one "ultimate" defense, because each method can be countered by the enemy siegers. Rather, you need to compose your defenses so you have several different methods of fighting off the invaders if you want to keep your fort.