Both RevitPythonShell scripts and Revit Python Macros are relying on Iron Python. In both cases, at least in Revit 15, neither require the installation of IronPython. I believe RevitPythonShell installs with the capacity to process the ironPython script (rpsruntime.dll). Revit must install with the same capacity.
Therefore, I assume the two programming environments are being executed from separate sources. Is this accurate?
How would I be able to install an external module as I would typically use pip for? Another words, if I wanted to use the docx, pypdf2, tika, or other library - is this possible?
I agree with your assumption that these two environments are probably completely separate and independent of each other.
Since the Python code that you write within them is pure .NET, it is easy to reference other .NET modules, assemblies, libraries, whatever you want to call them. They would reside in .NET assembly DLLs.
pip to add external Python libraries is a completely different matter, however, and rather removed from the end user environment offered by these two.
To research that, you will have to dive into the IronPython documentation and see how that can be extended 'from within' so to speak.
For pure-python modules, it could be as easy as having a CPython installation (e.g. Anaconda) and pip installing to that, then adding the site-packages of that installation to the search path in RPS.
For modules that include native code (numpy and many others), this gets more tricky and you should google how to install those for IronPython. In the end, adding the installed module to your search path will give you access in RPS.