It seems you never got an answer. Sad story bro. But for future reference purposes... What I see often done for params like yours (and others, like the usual tracking utm params) is:
Before doing the return (hash) in the vcl_recv subroutine, strip the param(s) from the url like so (example with utm params and the _ you mentioned):
if (req.url ~ "(\?|&)(utm_[a-z]+|_)=") {
set req.url = regsuball(req.url, "(utm_[a-z]+|_)=[-_A-z0-9+()%.]+&?", "");
set req.url = regsub(req.url, "[?|&]+$", "");
}
(Not tested, so do not just copy-pasta...)
In this way, the stripped params are ignored for caching purposes (so, not added to the caching hash). Keep in mind that a side effect of this is that these params won't reach your app backend either, so if you need to process them for whatever reason, you might actually want to avoid the caching altogether when those params are present (which would involve to do a param presence check and a conditional return (pass), but that is another story...).
By the way, I hope the _ is not a content versioning param, because... if it is, I suspect you might not want to strip it from the caching hash 🤔