It allows you to run black (or whichever command comes after run) installed in your virtual environment without needing to activate your virtual environment first.
The relevant note is in the poetry run docs (emphasis mine):
The run command executes the given command inside the project’s virtualenv.
Let's say you have this poetry-demo project with a main.py, and you installed black:
poetry-demo$ ls
README.rst main.py poetry.lock poetry_demo pyproject.toml tests
poetry-demo$ poetry add black
The following packages are already present in the pyproject.toml and will be skipped:
• black
...
If you don't activate your virtual environment first (i.e. poetry shell) and if you have no black installed anywhere else on your system, simply doing black file.py would fail:
poetry-demo$ which black
poetry-demo$ black main.py
-bash: black: command not found
But, with poetry run, even without activating your virtual environment, you can run black:
poetry-demo$ poetry run black main.py
All done! ✨ ✨
1 file left unchanged.
The source of your confusion is probably because you already have your virtual environment activated, so then there really is no difference:
poetry-demo$ poetry shell
Spawning shell within /path/to/virtualenvs/poetry-demo-hCA44HQ0-py3.8
poetry-demo$ . /path/to/virtualenvs/poetry-demo-hCA44HQ0-py3.8/bin/activate
(poetry-demo-hCA44HQ0-py3.8) poetry-demo$ black main.py
All done! ✨ ✨
1 file left unchanged.
(poetry-demo-hCA44HQ0-py3.8) poetry-demo$ poetry run black main.py
All done! ✨ ✨
1 file left unchanged.