Improvements to AI behaviour - vision, searching and animations

in other words, do interfaces not work in terms of something sends a message to the interface and all BPs that have that interface can then just use it?

No, you send something directly, but you do not need to know what it is that you’re sending to =)

So for example you don’t care whether it is an AIController, an AICharacter, or … So if BP A wants to send/execute something via interface to BP B, C, D and E, then you need to execute the interface function with B as target, then with C as target, same for D and E.

Another method of communication inside UE are event dispatchers. Basically an event dispatcher broadcasts an event, and everyone that listens will receive it. So BP A broadcasts, and if BP B, C, D, and E would listen (to exactly this event dispatcher) then they would all receive the event. In your case the event dispatcher would have one input, the AI State.
In order to listen to an event dispatcher, you need to bind an event to it. So BP B, C, D and E would need to get a reference to the event dispatcher from BP A (of this exact instance of BP A) and then bind to it. So in your case, the AnimBP would need to get a reference to the AI controller and access the event dispatcher from it. For event dispatcher you could take a look at this here Event Dispatchers explained - Finally!

Generally speaking for structuring code, you got a couple of different tools there (like inheritance, components, interfaces, event dispatcher, cast). What you use depends on what you’re trying to do, but generally I find it good to think about what you would need to adjust when you want to delete/change/expand something. For example if you would use casting in your case, then e. g. if you would want to switch out the animation blueprint, you would not only make changes inside the new animation blueprint (like implementing an interface or binding to an event dispatcher), but you would also need to go into the code where you call the event on the animation blueprint.

Or if you send the AI State from the controller to the AnimBP, then now your AnimBP also gets information from the controller (and not only from the pawn). Now that means that you have two classes/places you need to keep in mind there instead of only one (if you do everything from the pawn). Same if you would do Behavior tree task → AnimBP. And ofc AI controller and Behavior Tree do not exist on clients, so it will all break if you ever want to use it in multiplayer…

And you could also do right click on an asset → Reference Viewer / Size Map to see what that references, what will be loaded into memory as soon as this asset is loaded into memory. So if you never took into consideration how to structure your assets and what references what, then you may/will end up bloating memory usage and loading times.

And you could also look at this here Blueprint Kickstart | Course and Breaking Down the Components of Gameplay | Course (and ofc generally the online learning courses if you haven’t already).