Why don't do the context switch in the internal of the API ended with FromISR?

As I said, different ports handle the scheduling differently. In some ports, the call to portYIELD_FROM_ISR will IMMEDIATELY go to the scheduler and it will then go to that task, stopping in the middle of the ISR. The ISR is really running in the context of the task that was interrupt, just as if it had a subroutine call at that point. This means the rest of the ISR code won’t run until that task gets its next chance to run, and since the whole point of putting code into an ISR is to get it to run right away, that tends to not be what you want.

On machines where portYIELD_FROM_ISR just sets a pending interrupt bit at the lowest priority, then yes, that could have been done in the FreeRTOS functions, but then FreeRTOS could not be run on machines which don’t work that way, and one goal of FreeRTOS was to support a wide variety of platforms.