select x,y,z, (extract_keywords(l.*)).*
[...]
Does this mean the function gets called three time?
Yes.
(function_call(...)).*
syntax is problematic. You should avoid it via one of two options.
LATERAL (new way, preferred)
or
CTE (old way)
In the CTE version you make the call in the CTE but do "(col).*" in the main query. This way the function is only called once to generate a composite output, then the composite output is exploded.
With LATERAL the system is smart enough to do it the right way.
David J.