So yea.... one thing I figured out after about 5 min of actually thinking about how the AI system would work, is that it would be much more efficient to just add an extra invisible rect to just the player. Then whatever npc sprite that collides with it will sense the play and start tracking it.
sprite.spritecollide(invis_rect, NPCs, False), check how close the sprites on the returned list are from the player, maybe check LoS, then do whatever.
One drawback I see is that the invisible rect would restrict the max tracking range of the NPCs. Making the invisible rect the size of the screen would allow all NPCs on screen to know where the player is, but then there would be far too many useless collisions. Making the invisible rect too small would allow the player to easily avoid NPCs.
meh... I'll probably just pick an arbitrary value and see how it works