AST just means "abstract syntax tree".
Both PSI and UAST provide AST representations of a source file.
And both of them provide a whole view of the file (e.g. if it contains a class, both will have a class -- PsiClass or UClass respectively).
However, the PSI hierarchy is language specific; the AST for Java looks one way, and the AST for Kotlin looks completely different (different classes involved etc). That means if you want to write a lint check for both Java and Kotlin, you'd basically need to implement the logic twice.
UAST basically can let you target both without worrying about the individual ASTs. It is backed by PSI; the parsers will construct PSI (java psi and kotlin psi), and UAST is constructed from that.
The reason PSI is still relevant is that when you analyze UAST and "resolve" a reference, you get back a PsiElement, not a UElement. That's because (for example) you might be referring to compiled code in a jar file -- which doesn't have a UAST representation.
-- Tor