@available is, indeed, when something was actually introduced. As you put it, "available to use starting with this version."
@backDeployed is for when something could've worked on an earlier version, if you just copied and pasted the function body. So something that has relatively straightforward logic, doesn't change the layout of or introduce new structs, etc.
Then when you build the project, the compiler can figure out if it can just use the library's version of the function (target >= @available) or if it needs to copy over the definition itself (@backDeployed <= target < @available). But from your perspective as a consumer of the function, you can act like it's been present since the version indicated in @backDeployed.