Semantic LLM caching: how do you evaluate a verifier that rewrites instead of rejects, when there's no ground truth for the rewrite?
ok so quick context if you haven't seen the other posts: I've been messing around with CacheVerifier, basically testing whether bolting a verifier onto semantic caching actually helps. right now it's dumb and binary, candidate answer either gets a thumbs up or thumbs down, no in-between.
there's this other paper, TweakLLM (arXiv:2507.23674), that does something I think is genuinely smarter: instead of rejecting a bad candidate and eating the full regen cost, it has a cheap LLM just... rewrite the candidate so it fits the new query. patch it instead of throwing it out. I want to add that as a comparison to my own setup and I've been stuck on it for a while, so figured I'd just ask here, since this sub has already bailed me out twice on this project (the axis-problem theory and the bucketing design both came from comment threads here, not from me).
here's where I'm stuck. everything I currently measure is trace-based against public benchmarks , "was this correct" comes entirely from the dataset's own labels, no actual LLM judge anywhere in the loop. works great when the answer is binary. falls apart completely once you're rewriting text, because now you've got a brand new string that isn't in any label anywhere. nothing to check it against.
things I've considered and don't love:
just throw an LLM judge at grading the rewrites. but now I'm introducing a whole new cost/noise source that literally nothing else in this project needed, and "let an LLM grade another LLM's output" is its own whole mess
when there happen to be multiple reference answers for the same query cluster, score the rewrite against one of them by similarity. except that's literally the "similarity ≠ correctness" problem this entire project exists to complain about. using it as my metric here feels like cheating on my own thesis
just skip fine scoring, measure something crude like "did rewriting recover some recall vs just rejecting," and not even try to put it on the same hit-rate/error-rate curve as everything else. doable but honestly a weaker result than I want
if anyone's had to evaluate a generate-a-rewrite step where there's no clean ground truth for the output, not classification, not ranking, an actual freeform string you have to judge somehow , genuinely curious how you dealt with it. or if you think I'm overcomplicating this and should just pick one of the above and move on.
repo's here if you want the full context on what's been tested so far: https://github.com/imxinchengyou/CacheVerifier