An agent decides at runtime where your data goes.
Ordinary code has a fixed set of destinations you could in principle enumerate. An agent constructs its calls while running, which is what makes every other property of it awkward.
Four failures that are specific to this shape of code.
Whatever you interpolate into a prompt leaves your process. A user record concatenated into context is an egress, even though it looks like string formatting.
Prompt and completion logging is on by default in most frameworks, and it captures exactly the content you were careful about elsewhere.
A tool-calling agent inherits every permission you hand it. The interesting question is what the least useful version of that credential looks like.
Model output routed into a query, a shell, or another tool call is untrusted input that arrived by an unusual door.
The provider is a recipient.
A hosted model is a third party receiving personal data, whatever the integration looks like in your code. So is the vector database holding embeddings of your customer records. Both belong on the map and in the Record of Processing, and neither tends to be there, because the person maintaining that document thought of them as infrastructure.
A constructed call is hard, and we say when we lost it.
Following data into a prompt is tractable. Following it through a destination the program computes at runtime is not, in general. The scan reports how many outbound calls it could not resolve rather than presenting a partial map as a complete one, and you can place the systems it could not name yourself.