I don’t have enough experience to say this with full confidence, but I think using a nested helper function is a pretty common and reasonable approach when dealing with recursion and memoization. It helps keep the main function clean by hiding the implementation details.
That said, without any comments and with a generic name like helper, the code can be harder to follow, especially for someone new to it. Giving the function a more descriptive name and maybe adding a short docstring could make it clearer, especially if you're working in a team.